C语言学习

1.初学c语言

一、

#include <stdio.h>
int main()
{    printf("Hellow world\n");
    getchar();//从键盘获取一个字符,以回车键为结束
    return 0;
}

二、字符常量
字符常量:转义字符:\n表换行,\t表水平制表符(tab),'表示单引号,\表斜杠,?表问号 \a警告声音提示 , \b退格删除 \f换页符\r回车\v垂直制表符\o八进制\x十六进制

2.基本数据结构

变量:必须先定义后使用 命名规则只能有数字 字母 _(下划线)构成且数字不能为第一个

int a
char = 'a'
char b=64
ch = (int)ch//强制转化(将char类型的转化为int类型的)
float x=3.14159f//(f表示为float类型,不影响数字)   
//float 单精度浮点型4字节(精确到小数点后6道7位)       
// double 双精度浮点型8字节(精确到小数点后16到17位)编译器默认为double类
printf("%c\n",ch)//输出为a
 scanf("格式占位符",&变量)

int整形4字节 long长整形4字节 short短整型2字节(表示无符号就在前面加unsigned)
双长整形为long , char字符型1字节 字符可以与数字转化 参照ASCII表(隐示转化)
小数和整形之间的转换,如果把一个小数赋值给一个整形变量,那么整型变量只会保留整数部分

#include <stdio.h>
int main()
{  int a = 3.14 
   printf("%d\n",a);
   return 0;
}

输出结果
在这里插入图片描述
数据的输入与输出
格式占位符:将输出的数据转化为指定格式进行输出 printf(“格式占位符”,变量) 输出多个变量时printf(“变量一的格式占位符,变量二的格式占位符”,变量一,变量二)
类型 格式占位符
int %d
char %c
float %f (%.3f 同下)
double %lf(或者%.8lf .8表示输出位数)

3.运算符

3.1算数运算符:±*/% 自增自减运算符++ --(只变量的值加减一)
前缀:++a 先自增再运算 后缀:a++ 先运算后自增
%表示取余
3.2关系运算符:> >= < <= != == 表达只有两种:真(1) 假(0) int e=10 == 10 (结果为1)
3.3逻辑运算符:与(&&) 只有都为真时才为1 或(||) 只有都为假时才为0 非(!)假变真,真变假
3.4位运算符(二进制运算符):左移:<<(左移多少位相当于乘以2的n次方) 右移:>>(右移多少位相当于除以2的n次方) 按位非: ~ 按位或:| 按位与:& 按位异或:^

 //int占四字节   一字节等于8位   因为10的二进制等于1010,则10的 二进制表示方法为(……0000 )0000 1010(共32个)
 int a = 10  printf("%d\n", a << 1);    //那么位向左移一位变成0001 0100
 int c = 10  printf("%d\n", ~c);        // 0变1,1变0 
 int d = 5 e = 3 printf("%d\n", d | e); //有一为一,无一为零 结果为7
 int f = 5 g = 3 printf("%d\n", f & e); //两个都为1时才为1   结果为1
 int h = 5 i = 3 printf("%d\n", h ^ i); //相同为0不同为1     结果为6

3.5 赋值运算符 = += -= *= /= %=

int a = 10  int b = 0   b += a  //b=b+a

3.6逗号运算符: ,

 int a,b,c = (1,2,3)  

3.7条件运算符:表达式1?表达式2:表达式3 如果1为真,执行2 否执行3

int a= 10  int b = 2  N= (a>b)? a=11:b=11   printf("%d\n,N")  //(输出结果为a=11)

3.8操作数:一个运算符要用到几个变量计算,比如需要俩个数进行计算,那么叫做双位运算符
当float类型与double类型混合计算时,全部转化为double,再进行运算
int与float或者double类型的混合预算时,先把int转化为float或double在进行运算
char与int运算时,一般把字符型转化为整形再计算

4.分支结构与循环结构

4.1 if选择分支结构

int Hp=100
   if (Hp<60)
       {   printf("英雄血量不足")  }
   else if () 
   {
   }
   else ()//也可以不加括号
     { 
     }

4.2 switch多分支结构

switch(表达式)      
{  
 case 常量一:
      语句一; 
 break;//跳出当前Switch语句:只当前语句执行后,后面语句不在调试
 case 常量二:
      语句二; 
 break;
            ……
 case 常量 n:
      语句 n; 
 break
 default:语句n+1                                                                                                        
 }

4.3 for循环语句

for (表达式1;表达式2;表达式3)
{ 语句 }
表达式1:条件的初始值 表达式2:判断条件 表达式3:改变的条件的值

   for (int a = 10; a < 100;a++)
       {
         printf ("条件成立\n")  //执行a<100 ,输出语句,再进行a++,再进行<100,输出语句,以此循环,直到a=100
       }
           //for语句的嵌套
   for (int a = 10; a < 15; a++)
        {
        for (j = 10;j < 15;j++)
        {   
         printf("*\n")
        }
        printf("#\n")
        }     //输出结果为*****#(循环五次)
        

4.4 while循环语句

while (表达式)
{ 语句 }

      int a=10 
      while (a > 0)
            {
              printf("*\n")
                a--//输出10次
             }

4.5 do while循环语句

do
{语句 }
while
(表达式)

  do
      {
       printf("*\n")
       }
       while (a>0)//只输出一次
       a++         //一直循环输出

4.6 跳转语句

break:结束当前的执行
continue:结束本次循环并进行下一次循环
goto:跳转到指定标记的位置

  int main()
   {
    for (int i = 0; i < 100; i++)
        {
         if (i % 2 == 0)//i是偶数
            {
            continue;
            }
         printf("%d\t",i)
         }
   }   //输出结果为奇数
 for (int k = 0; k < 10; k++)
     {
      goto a
     }

  a:
    printf("#\n")
    //循环中的变量使用:局部变量只能在当前for循环中进行使用

5.数组

5.1定义格式

类型说明符(基本数据类型),必须是合法的标识符,满足规则和规范
数组名[数组的大小](是一个常量或者是一个字符)

int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }    //(若没有初始化则自动为0)
char arrl[10]={'a','b','c','d','e','f','g','h','i','j'}

5.2数组中的数据的访问

通过下标来访问,下标从0开始,表示方法是数组名[数组下标]

  printf("%d\n",arr[4])//输出结果为5
  scanf_s("%d",&arr[4])//改变第五个数

5.3 内存地址

//系统随机分配内存地址编号,地址一般是十六进制书写,查看方法:
    printf("%p\n",&arr[4])
    //求内存大小:
    printf("%d\n",sizeof(arr))
    //数组总数
     printf("%d\n",sizeof(arr)/sizeof(arr[0]))
    int maxsize =10//数据能够存储的最大个数
    int len//当前数组已经存储了多少个数据

输出所有数

int arr[10]
for(int i=0;i<10;i++)
{
printf("%d\n",arr[i])
}

5.4 二维数组

定义:类型说明符 数组名[ 数组大小 ][数组大小] 行 列
初始化:

int arr[2][9] = {
{1,2,3,4,5,6,7,8,9},
{9,8,7,6,5,4,3,2,1}
}//或者
int arr[2][9]={{1,2,3,4,5,6,7,8,9,9,8,7,6,5,4,3,2,1}}//赋值是一行一行的赋值
printf("%d\n",arr[1][1])//输出为8

输出所有的数

#include <stdio.h>
int main()
{
 int arr[4][3]={
 1,2,3,
 4,5,6,
 7,8,9,
 10
 };
 for(int i=0;i<4;i++)
    {
    for(int j=0;j<3;j++)
       {
        printf("%d\t",arr[i][j]);
       };
    printf("\n")
 }
 	return 0;
}
 

输出结果
在这里插入图片描述

5.5 三级数组

定义:类型说明符 数组名[ ][ ][ ] 个 行 列
初始化:

int arr[2][4][3]=
{
  {
    {1,2,3},
    {4,5,6},
    {7,8,9},
    {10}
  },
  {
    {1,2,3},
    {4,5,6},
    {7,8,9},
    {10}
  }
}
------------------------------------------
//某个数的表示方法
//例如第二个二维数组中的8表示为
arr[1][2][1]

6.字符数组

6.1 定义

char 数组名[ ]

#include<strinng.h>//字符串的头文件
char str[10]//={0}//未赋值输出是空着,但是会存在\0(就是空格),每一个字符串的末尾都有\0表示字符串的末尾
或者
str[0]='a'
str[1]="汉字"//一个字占两个字节 
或者
char str1[10]="abcdefg"//{}可有可无

输出
格式占位符为%s,只输出到\0d的位置

printf("%s",str1)

输入

scanf("%S",str1)//输入字符串不用加&
scanf("%s",&str1[0])
gets(str)//输入字符
puts(str)//输出字符

比较两个数组
和数字比较相同,从最高位数开始比较,按照字母表顺序一个一个大
返回结果值为0,则相等,>0,str>str1;<0,str<str1

strcmp(str,str1)

求字符串的有效长度和大小
strlen:求字符串的有效长度 \0不算有效长度
sizeof:求类型大小

char str[10]="abc"
printf("%d\n",strlen(str))
printf("%d\n",sizeof(str))

6.2 二维数组

char str[3][10]

6.3 字符串拼接函数

char str[10]="aaaa"
char str1[10]"bbbb"
strcat(str,str1);//把str1接到str上

6.4 字符串拷贝函数

strcpy(str,str1)//把str1拷贝到str中
strcpy(str,"qqqq")

7.函数

7.1 定义函数

返回值类型 函数名(形参列表){}
如果需要返回一个值出去,那么返回值类型这里,通过return把之值返回出去;如果不需要返回一个值,么返回值类型这里就用void
void表示空类型

int one(){
 
  return 0  
}
void two(){

}
int three(int a,int b)
{
return a+b;
}
int main()
{
three(1,2)//实参列表  
return 0
}

7.2 局部变量

作用域在一定的域内才能使用的变量

void add()
{
int a
}//一个{}是一个作用域
int main()
{
int a
}//两个变量互不影响

7.3 全局变量

int a;
int main()
{
 a=1
 int a//全局变量和局部变量可以同名,使用时遵循就近原则(从上到下)
}

7.4 静态变量

只会被定义一次

for(int i=0;i<10;i++)
{
static int a=10 //第二次循环的时候,因为上一个a没有被释放,所以会申请失败,a=11
a++
printf("%d\n",a)//输出结果为11-20
//如果没有static则会输出10个11
}

7.5 内存四区

静态全局区(存静态变量和全局变量)栈区(存局部变量) (会自动申请内存和释放内存)
堆区(自己申请的内存)代码区(函数)

7.6 函数的声明

会报错

int main()
{
 fun()
 return 0
}
void fun(){}

不会报错

int main ()
{
void fun()
fun()
return 0
}
void fun(){}

7.7 址传递

7.1
&:得到a的地址编号
*:指针变量,存储地址的变量

int *d

7.2

void (int *d){
printf("%d",*d)
}
int main(){
int a=10
one (&a)
}//输出结果是10

也可以传数组

void fun(int arr[],int len)
{
for(int i=0;i<len;i++)
   {
   printf("%d\n",arr[i])
   }
}
int main()
  {
  int a[10]={1,2,3,4,5,6} 
  fun(a,10)
  }

7.8函数的递归

自身调用自身

 void fun()
 {
 static int i=10
 if(i!=0)
   {
   i--;
   fun();
   }
   printf("%d\n",i);
 }
 int main()
 {
  fun()
 }//输出结果是11个0

 void fun(int n)
 {
 if(n!=0)
   {
   fun(n-1);  
   printf("%d\n",n);
   }
 }
 int main()
 {
  fun(4)
 }//输出结果是1,2,3,4

逆向输出一个数

void fun(int n)
{
if(n!=o)
  {
  printf("%d",n%10)
  fun(n/=10)
  }
}

8.自定义数据类型

8.1 结构体

struct student
{
  int id
  char name[10]
  float score
}
int main()
{
student aa={ 1,"张三"60}
aa.id =10
aa.name=张三//这种写法是错的
strcpy (aa.name,"张三")
student arr[4]={
               {1,"",10},
               {2,"",20},
                        }
printf("%d\t%s\t%d\t",arr[0].id,arr[0].name,arr[0].score)
}

8.1.2 类型取别名

typedef int 整形
typedef struct hero {}YX
struct{}s1,s2,s3[10]//定义的时候没有结构名,也没有取别名,那么}后面的标识符酒店hi定义该结构体的变量

8.1.3 内存计算

struct one{
          int a;
          int b;
          char c;
}
int main()
{
printf("%d\n",sizeof(one))
}//输出结果为12,因为以结构体中最大的基本数据类型所占的内存进行对齐
struct two{
int a;
char b[10]
float c;//20bit,
}//最高为4,b有10个字节,所以b被分到12字节
struct three{
	double a;
	char c[10];
	 int b;
}//24bit,int类型会多出4个字节给char

struct three{
	char c[10];
	double a;
	 int b;
}//但这时是32字节
struct four{
}

8.2 共用体

主要是内存计算方法不同
共用体所有的成员共用里面最大的成员的空间,在同一时刻只能存一个成员的值,但以共用体中最大基本数据类型所占内存进行对齐

union arr
{
int c
char a[10]
float b
}//12字节,基本数据类型最大为4字节,共用a[10]的空间,所以分个三个4字节

8.3 枚举类型

枚举的元素有默认的值,是整数,第n个元素的值是上一个值+1,第一个值默认为0

enum arr{
//可以写标识符
left,
right,
up,
down
}
#include<conio.h>
enum {up='w',down='s',right='d',left='a'};
int main()
{
  while(1)
  {
     switch(_getch())
     {
     case up:
     printf("按键为上")
     break
      case down:
     printf("按键为下")
     break
      case left:
     printf("案件为左")
     break
      case right:
     printf("案件为右")
     break
     }
  }
}

9.指针

9.1 认识指针

无论是什么类型,指针变量都是4bit

int *a
float *b
double *c//12bit
int arr[10]
int *p=&arr[0]
int *p=arr//数组名本身就表示是这个数组的首地址,*p=数组中的第一个数
p+=5//指针的偏移
p[i]=*(p+i   )
printf("%d",*p)//输出第6个数

通过指针变量修改原来的数据

#include <stdio.h>
void one(int* x, int* y) {
	*x = 3;
	*y = 4;
}
int main() {
	int a = 10;
	int b = 20;
	one(&a, &b);
	printf("%d%d\n", a, b);
	return 0;
}//a=3,b=4

9.2 常量字符串

char* p="hello world"
printf("%d\n",strlen(p))//11
printf("%d\n",sizeof(p))//4
p+=4
printf("%c",*p)//o
int arr[10]={1,2,3,4,5,6,7,8,9,10}
double *h=(double *)&arr[0]
h++
printf("%d",*((int *)h))//3
//int转化为double,double是8字节,h++是地址加八位,相当于int类型时偏移了两位

9.3 指针函数和函数指针

指针函数:是一个函数,这个函数的返回值类型是一个指针

int* fun(){
int a=10
return &a
}
int main(){
int *p=fun()
printf("%d",*p)
}

函数指针:是一个指针,这个指针是一个函数,并且函数名本身就是别名,可以当类型使用

void fun(int a,int b){
printf("%d",a+b)
}
void (*fun1)(int a,intb){}
int main(){
   fun1=fun;
   fun1(1,2)  
}

用法

int add(int a,int b)
{
  return a+b
}
//这一部分是我写的,但是需要别人提供计算功能,(int,int)表示占位参
void one(int (*p)(int,int),int x,int y){
       printf("%d\n",p(x,y))
}//ne(p pf,int x,int y){printf("%d",pf(x,y))}
int main()
{
one (add,10,10)
}

9.4 常量指针和指针常量

常量指针:不用初始化,能改变指向,但内容不能被修改

const int *p
void fun(const int *a){}//保护实参不被韩式形参调用修改

指针常量:必须初始化,不能改变指向,可以改变指向的内容

int* const p1

9.5 大端存储和小端存储

直接看【数据存储】大端存储 小端存储

9.6 指针数组和数组指针

指针数组
是一个数组,存储的是指针

int a=3,b=2,c=1
int *p=&a,*p2=b,*p3=c
int *p[3]={p1,p2,p3}

数组指针
是一个指针,指向的是一个数组(二维数组起)

int arr[3][2]=
{
1,2,3,
4,5,6,
}
int (*p)[2]=arr
void fun(int (*arr)[2])
{
for(int i=0;i<2;i++)
    {
    for (int j=0;j<2;j++)
         {
         printf("%d\t",arr[i][j])
         }
    printf("\n")
    ]
}
int main(){
  int arr[2][2]=
  {
  1,2
  3,4
  }
  fun(arr)
} 
int n[3][4]
{
{1,2,3,4},
{8,7,6,5},
{9,10,11,12}
}
int (*pn)[4]=n
int *p[3]{n[1],n[0],n[2]}
int **pp=p
printf("%d\n",*(*(pp+1)+2))//3

在这里插入图片描述

9.7 结构体指针

#include <stdio.h>
typedef struct note
{
int a;
char name[20];
}note
void main()
{
  note n;
  n.a=10;
  note *p=&n;
  p->a=20
}

数组

note n1[5]={
{1,"aaa"}
{2,"bbb"}
{3,"ccc"}
{4,"ddd"}
{5,"eee"}
}
note *p[5]={&n[3],&n[2]}
printf("%d\t%s\n",p[0]->a)//4

偏移

note *p=n1
printf("%d%s",(p+2)->name)//ccc 

9.8 动态内存分配

从堆区申请内存,自己使用
通过函数malloc calloc realloc申请内存,要记得释放,释放时指针必须指向首地址
9.8.1 malloc

#include<stdib.h>
void main()
{ 
  //赋值条件:类型相同
  int *p=(int *)malloc(100)//单位是字节
  *p=10;//前4个字节存10这个数
  *(p+1)=20 //接着4个字节存20这个数
  free(p)//释放
}
int *p1=(int *)malloc(sizeof(int)*25)//申请了25个int类型的字节
for (int i=0;i<25;i++)
{
   *(p1+1)=i+1
   printf("%d",p1[i])
}
#include<string.h>
memset(p1,0,sizeof(int)*25)//逐字节赋值

9.8.2 realloc

int *p1=(int *)malloc(sizeof(int)*25)
p1=(int*)realloc(p,sizeof(int)*50)//重新分配,不会初始化
for (int i=0;i<50;i++)
{
   *(p1+1)=i+1
   printf("%d",p1[i])
}
free(p1)
p1=NULL

9.8.3 calloc

int*p=(int*)calloc(25,sizeof(int))//会默认初始化为0

10.预处理

10.1 常用符号

__FILE__//当前编译的文件名
__FUNCTION__//当前所在函数的函数名
__DATE__//当前编译日期
__TIME__//当前编译时间
//以上格式占位符用%s
__LINE__//当前行数,格式占位符用%d
_CRT_SECURE_NO_WARNINGS//关闭安全检查

10.2 宏定义

10.2.1 无参宏定义

#define π 3.1415926
int main()
{}

10.2.2 带参宏定义

#define FUN(a,b) {printf ("%d",a+b)}
#define F(a,b) a*b
int main()
{
printf("%d\n",F(1+2,2+1))
}//6,先代替,再计算 

10.3 常量的定义

const int a=10//不允许被修改 

10.4 头文件

#include<>//只会从系统头文件中找
#include""//在自定义头文件中找不到就会在系统头文件中找
#pragma once //防止头文件重复包含,不让文件的内容被包含两次,在头文件最前面添加
#ifndef __TOOL_H__//如果没定义这个宏
#define __TOOL_H__
//在头文件中声明函数
void fun()
#endif

条件编译

#if 1 
printf("1111")
#else
printf("2222")
#endif
#ifdef A//如果定义A这个宏
#else//否则
#endif

11.文件操作

11.1 文件的打开与操作

打开文件:通过定义文件指针指向文件
文件操作:通过函数对文件中的数据进行操作
在这里插入图片描述

//操作的是数据文件
int main(){
FILE * file;
FILE * file1
file=fopen("1.txt","w")//使用w写入会清空原来的内容
file1=fopen("1.txt","r")
fputc('c',file)//输入字符
fputs("ewgaga",file)//输入字符串
char str[]="frgsgag"
fputs(str,file)//也可以用数组输入
char c;
c=fgetc(file1)
printf("%c\n",c)//读取内容
//读取字符串
char str[1024]={0}
fgets(str,3,file)//\0也占一个字符
//读取整个文件
char str1[10240]={0}
int x=0
while (!feof(file))//判断文件指针是否读到了末尾,到了返回一个真
{
  str1[x]=fgetc(file)
  x++
}
fclose(file)
fclose(file1)
}

11.2 顺序读写文件

int main(){
FILE*file=fopen("2.txt","w")
FILE*file1=fopen("1.txt","r")
int a=10
char str[]="asfas"
fprintf(file,"%d%s\n",a,str)
int b=0
char str1[10]={0}
fscanf(file1,"%d%s",&a,str1)//从文件夹中读取到数组中
fclose(file)
fclose(file1)
}
FILE*file=fopen("3.txt","wb")//以二进制方式写入
FILE*file1=fopen("3.txt","rb")
char str[]="fergre"
int a=10
fwrite(&a,//写入的东西
        4,//写入的数据字节大小
        1,//写入的个数
        file)
fread(&a,4,1,file1)
fclose(file)
fclose(file1)
FILE*file=fopen("3.jpg","rb")//图片是以二进制方式储存
fseek(file,
       1,//移动的字节数,正数往后移动,负数往前移动
       2//从那个位置移动。0是文件开头,1是文件指针当前位置,2是文件指针末尾位置)
int size=ftell(file)//获取文件指针的偏移量
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值