01 第一个C语言

  1. #include<stdio.h>
  2. int main()
  3. {
  4. printf("hello world");
  5. return 0;
  6. }
  • c语言入口函数
  • include包含的头文件(import)
  • 单行注释//,多行注释/ /
  • 一条语句:结尾

    02 C语言标识符

  • 数字字母下划线

  • 数字不能开头
  • 区分大小写
  • 不能是关键字 | 关键字 | 说明 | | —- | —- | | auto | 声明自动变量 | | break | 跳出当前循环 | | case | 开关语句分支 | | const | 定义常量,如果一个变量被const修饰,那么它的值就不能再被改变 | | continue | 结束当前循环,开始下一轮循环 | | default | 开关语句中的”其它”分支 | | do | 循环语句的循环体 | | double | 声明双精度浮点型变量或函数返回值类型 | | else | 条件语句否定分支(与if连用) | | enum | 声明枚举类型 | | extern | 声明变量或函数是在其它文件或本文件的其他位置 | | float | 定义声明浮点型变量或函数返回值类型 | | for | 一种循环语句
    | | goto | 无条件跳转语句
    | | if | 条件语句 | | int | 声明长整型变量或函数返回值类型 | | long | 声明整型变量或函数 | | register | 声明寄存器变量 | | return | 子程序返回语句(可以带参数,也可不带参数) | | short | 声明短整型变量或函数 | | signed | 声明有符号类刑变量或函数 | | sizeof | 计算数据类型或交量长度(即所占字节数) | | static | 声明静态变量 | | struct | 声明结构体类型 | | switch | 用于开关语句 | | typedef | 用以给数据类型取别名 | | unsigned | 声明无符号类型变量或函数 | | union | 声明共用体类型 | | void | 声明函数无返回值或无参数,声明无类型指针 | | volatile | 说明变量在程序执行中可被隐含地改变 | | while | 循环语句的循环条件 |

03 数据类型

基本类型:它们是算术类型, 包括两种类型:整数类型和浮点类型。
枚举类型:它们也是算术类型
void类型:类型说明符vold表明没有可用的值。(None)
复合类型:指针类型、数组类型、结构类型、共用体类型和函数类型。

3.1 整数类型

  • 通常在不同编译器上有所区别
  • 使用sizeof(运算符可以获取大小 | char | 1字节 | -128到127或0到255 | | —- | —- | —- | | wchar_ t | 2字节 | -32,768到32,767 | | unsigned char | 1字节 | 0到255 | | signed char | 1字节 | -128到127 | | int | 2或4字节 | -32,768到32,767或-2,147,483.648到2,147,483,647 | | unsigned int | 2或4字节 | 0 到65,535或0到4,294,967,295 | | short | 2字节 | -32,768到32,767 | | unsigned short | 2字节 | 0到65,535 | | long | 4字节 | -2,147,483,648到2,147,483,647 | | unsigned long | 4字节 | 0 到4,294,967,295 |

3.2浮点型

float 4字节 1.2E-38到3.4E+38 6位小数
double 8字节 2.3E-308到1.7E+308 15位小数

04 C语言变量

  • C语言的变量在定义时就确定变量存储大小和布局
  • C语言的变量需要符合标识符的命名规范
  • 定义变量
    1. #include <stdio.h>
    2. int main()
    3. {
    4. //变量走义时必须指名类型,与python不同, 这个类型一 直到安量销毁
    5. int a,b,c; //只定义变量
    6. int n =99; //定义并赋值
    7. char c,ch;
    8. float f;
    9. return 0;
    10. }
    image.png

    05 运算符

    | 运算符 | 描述 | 实例(A=10,B=20) | | —- | —- | —- | | + | 把两个操作数相加 | A+B将得到30 | | - | 从第一个操作数中减去第二个操作数 | A-B将得到-10 | | | 把两个操作数相乘 | AB将得到200 | | / | 分子除以分母 | B/A将得到2 | | % | 取模运算符,整除后的余数 | B%A将得到0 | | ++ | 自增运算符,整数值增加1 | A++将得到11 | | — | 自减运算符,整数值减少1 | A—将得到9 |

5.1 算数运算符

  1. #include <stdio.h>
  2. int main()
  3. {
  4. int a=10,b=20;
  5. int C = a+b;
  6. int d = a-b;
  7. int e = a/b;
  8. int f = a%b;
  9. int x = a++;
  10. int y = a--;//y=a;a--;
  11. int z = ++a;//a++;z=a;
  12. int k = --a;
  13. }

5.2 关系运算符

运算符 描述 实例
== 检查两个操作数的值是否相等,如果相等则条件为真。 (A==B)为假。
!= 检查两个操作数的值是否相等,如果不相等则条件为真。 (A!=B)为真.
> 检查左操作数的值是否大于右操作数的值,如果是则条件为真。 (A>B)为假。
< 检查左操作数的值是否小于右操作数的值,如果是则条件为真。 (A<B)为真。
>= 检查左操作数的值是否大于或等于右操作数的值,如果是则条件为真。 (A>=B)为假。
<= 检卉左操作数的值是否小于或等于右操作数的值,如果是则条件为真。 (A<=B)为真。
  1. #include <stdio.h>
  2. int main()
  3. {
  4. //在c中,假用0表示,真用非0表示(-1也是真)
  5. // python
  6. //if x == y:
  7. // pirnt("hello")
  8. if(7==8){
  9. printf("真\n");
  10. printf("7==8");
  11. }
  12. else
  13. printf("假\n");
  14. if(7 >= 8)
  15. printf("真\n");
  16. else
  17. printf("假\n");
  18. if(7!= 8)
  19. printf("真\n");
  20. else
  21. printf("假\n");
  22. }

5.3 逻辑运算符

运算符 描述 实例
&& 称为逻辑与运算符。如果两个操作数都非零,则条件为真。 (A&&B)为假
II 称为逻辑或运算符。如果两个操作数中有任意一个非零,则条件为真。 (AIlB)为 真
! 称为逻辑非运算符。用来逆转操作数的逻辑状态。如果条件为真则逻辑非运算符将使其为假。 (A&&B)为
  1. #include <stdio.h>
  2. int main()
  3. {
  4. int a=10;
  5. int b=20;
  6. if(a>10 && a<30)// &&类似python and 左右必须为真结果为真
  7. printf("真\n");
  8. else
  9. printf("假\n");
  10. if(10<a <30 ) // 18< a结果是假,假(0) <30 条件-一定满足
  11. printf("真\n");
  12. else
  13. printf("假\n");
  14. if(a>10 || a<30 ) //类似python or左右有一个为真结果为真
  15. printf("真\n");
  16. else
  17. printf("真\n");
  18. if(!a) //类似python not真为假,假为真
  19. printf("真\n");
  20. else
  21. printf("假\n");
  22. }

5.4 位运算符

运算符 描述 实例
& 按位与 100b &111b=100b
| 按位或 100b | 011b = 111b
^ 按位异或 100b | 011b = 111b
>> 右移 4>> 1 ==2
<< 左移 4<<1 ==8
  1. #include <stdio.h>
  2. int main()
  3. {
  4. int a=3;
  5. int c=a | 7;
  6. int d=a & 0x0F;
  7. int e=a ^ 8;//两个异或得到新的值
  8. int f=e ^ a;//将新的值和其中-一个,可以得到原来的值,加密
  9. int g = 4<<1;//<<1次等于*2
  10. int h = 4>>1;// << 1次等于/2
  11. }

5.5 赋值运算符

运算符 描述 实例
= 简单的赋值运算符,把右边操作数的值赋给左边操作数 C=A+B将把A+B的值赋给C
+= 加且赋值运算符,把右边操作数加上左边操作数的结果赋值给左 边操作数 C+=A相当于C=C+A
-= 减且赋值运算符,把左边操作数减去右边操作数的结果赋值给左 边操作数 C-=A相当于C=C-A
*= 乘且赋值运算符,把右边操作数乘以左边操作数的结果赋值给左 边操作数 C=A相当于C=CA
/= 除且赋值运算符,把左边操作数除以右边操作数的结果赋值给左 边操作数 C/=A相当于C=C/A
%= 求模且赋值运算符,求两个操作数的模赋值给左边操作数 C%=A相当于C=C%A
<<= 左移且赋值运算符 C<<=2等同于C=C<<2
>>= 右移且赋值运算符 C>>=2等同于C=C>>2
&= 按位与且赋值运算符 C&=2等同于C=C&2
^= 按位异或且赋值运算符 C^=2等同于C=C^2
|= 按位或且赋值运算符 C|=2等同于C=C12
  1. #include <stdio.h>
  2. int main()
  3. {
  4. int a=3;
  5. int b=10;
  6. b+=1;
  7. b*=2;
  8. b-=10;
  9. b/=2;
  10. b<<=2;
  11. }

5.6其他运算符

运算符 描述 实例
sizeof() 返回变量的大小。 sizeof(a)将返回4,其中a是整数。
& 返回变量的地址。 &a;将给出变量的实际地址。
解引用 *a;将指向一个变量.
?: 条件表达式 如果条件为真?则值为X:否则值为Y
  1. #include <stdio.h>
  2. int main()
  3. {
  4. int x = sizeof(int);
  5. int j = sizeof(x);
  6. int y=(int)&x;//取得x的地址
  7. int z=1>10?10:7;
  8. }

5.7 优先级

  • 与python-样
  • 通常我们记住,()优先级最高

    06 选择结构

  • if

  • if-else
  • if-else if -else
  • if嵌套 ```c

    include

    int main() { int a =10; if (a==10){ //单if判断
    1. printf("yes a == 10\n");
    } if (a == 9){ // if-else判断
    1. printf(" yes a == 9\n");
    } else{ //中问不能有其他语句
    1. printf(" no a != 9\n");
    } if(a > 10){ // if-else if - else判断
    1. printf(" yes a > 10\n");
    }else if(a > 7){ // 条件1不满足,将检查条件2,如果条件1满足,不会执行后面语句
    1. printf(" yes a > 9\n");
    } else{
    1. printf(" yes a < 7\n");
    } if(a >10 ){ //嵌套if if(a>10 && a<40)
    1. if(a<40){
    2. printf("a >10 and a <40");
    3. }
    } }
  1. - switca-case
  2. - 只能做简单的整数判断,不能做复杂的计算
  3. ```c
  4. #include <stdio.h>
  5. int main()
  6. {
  7. int number = 7;
  8. scanf("%d", &number); // 接收-一个整形变量
  9. switch(number)
  10. {
  11. //1每个case x的值不能出现重复,
  12. //2 case语句需要break ,否则会继续执行下一个break
  13. //3 case中如果定义变量,需要{}包裹起来
  14. case 1: printf("one \n");break;
  15. case 2:printf("two \n");break;
  16. case 3:printf("three\n");break;
  17. default:printf("other \n");break; //当所有数据都不匹配时执行这条语句
  18. }
  19. return 0;
  20. }

07 循环

  1. #include <stdio.h>
  2. int main()
  3. {
  4. // 1.初始化值,2. 循环条件 3.循环体4.循环计数器
  5. for(int i=0; i<10; i++)
  6. {
  7. printf("%d \n",i);
  8. }
  9. }

7.1 for循环

#include <stdio.h>
int main()
{
    //1循环条件,2循环体
    int i =0;
    while(1)
    //无限循环
    {
        i++;
    //循环计算
        if(i >10)//循环条件
            break; // 跳出一 -层循环
    }
}

7.2 do while 循环

#include <stdio.h>
int main()
{
    int i=0;
    do{
        printf("%d\n",i);
        i++;
    }while(i<10);
}

7.4 break,connitue

  • 循环控制语句

    #include <stdio.h>
    int main()
    {
      for(int i=0; i<10; i++)
      {
          if(i==3)
              continue;
          //跳过当前循环
          if(i==8)
              break;
          //跳出整个循环
          printf("%d \n",i);
      }
    }
    

    08 函数

  • 每个程序都是从main函数开始的,有且只有一个

  • C语言的组成单位是函数
  • 自定义函数 ```c

    include

    int add(int a,int b);

int main() { printf(“10 + 20 = %d”,add(10,20)); return 0; } //函数定义 //必须与函数声明时一样,是函数具体实现 int add(int a,int b) { return a+b; }


- c标准函数
| 头文件 | 函数  | 说明 |
| --- | --- | --- |
| #include<string.h>  | strcpy(),strlen(),strcat() | 字符处理相关 |
| #include<stdio.h>  | printf,scanf,fopen,fread  | 输入输出相关 |
| #include<math.h> . | abs(),asin()    | 数学相关 |
| #include<time.h > | time(),   localtime  | 时间相关 |
| #include<malloc.h> | malloc,free,calloc    | 堆操作 |

<a name="EWRmg"></a>
# 09 作用域
| 变量类型    | 变量说明 | 作用域 | 生周期存 |
| --- | --- | --- | --- |
| 全局变量  | 定义在函数外的变量 | 从定义的地方开始 | 整个程序结束 |
| 局部变量  | 定义在函数内的变量  | 函数中,或者{}中 | 在函数,或者{}结束 |
| 函数形参  |  函数声明时的参数也属于局部变量 | 函数中 | 函数结束 |

```c
#include <stdio.h>
//函数外的变量,全局变量,作用域从这个地方开始,生存周期整个程序
int g_global= 100;
//函数定义
int add(int a,int b){ // int a,int b是形参,作用域在函数中,生存周期在函数结束
    return a+b +g_global;
}
int main()
{
    int number; //局部变量
    printf("10 + 20 = %d\n" ,add(10,20));
    if(10 >20)
    {
        int a =9; // a局部变量,作用域仅在if的{}中,生成周期在{} 结束,就被释放}
    }

    // a无法使用,出了{}结束
    return 0;
}

10 数组

image.png

  • C语言支持数组数据结构,它是一 组类型相同并且在内存中是连续的变量的集合。(list)
  • 数组每个元素都有一个编号,编号从0开始到最大数-1
  • 数组的声明

                      //数组类型数组名数组长度
      int arr[10];
                      //定义了一个arr数组,类型int,长度10
                      // 1数组定义时长度就是固定的,不能更改
                      // 2.数组下标从0 -9 a[0] a[1] a[2] a[3]....a[9], a[10 ]数组越界
                      // 3.数组下标必须是正整数的值
    
  • 数组初始化

    int arr[10]={1,2,3,4,5,7,8};// 定义数组时可以进行初始化,同时给每个元素赋值,
                              //只要有初始化,那么剩余部分都会赋值为0
    int arr1[]={1,2,3,4};
                              //有初始化时,编译器自动算出数组长度,4
    int arr2[];
                              //没有初始化,编译器无法识别,报错
                              //只有在初始化时可以整体赋值数组元素,过了初始化将不能整休赋值
    
  • 数组使用

    char buff[]= "hello world"; //自动推算字符串的长度,并赋值
    for (int i=0;i< strlen(buff);i++) 
                              //循环字符长度
    {
      printf("%c" ,buff[i]);  //输出数组中每个元素
    }
    

    11 指针

    ●C语言最重要部分,与其他语言最大的区别(C++除外)
    ●指针变量就是个变量,变量中存放着地址,通过指针可以做许多有意义的事情
    ●这里记住一个事情指针及地址

    int a =99;
                  //整形变量
    int *p = &a;
                  //定义一个指针变量,赋值为a的地址
    char* pch = &c;  // 定义一个指针变量,赋值为c的地址
    *p=100;
                  // *解引用,获取指针指向的变量内容,并赋值 指针的使用
    

    image.png

    12 内存管理

  • C语言提供-套动态内存函数

  • 有些时候你需要一个数组,这个数组大小可能由用户动态的输入,然后去定义。但是C语言中的数组本身在定义时就已经限定死了,定义之初就必须确定大小,这时模可以用动态内存来实现
  • 管理动态内存函数在malloc.h库中 | 序号 | 函数和描述 | | —- | —- | | 1 | void calloc(int num, int size);在内存中动态地分配num个长度为size的连续空间,并将 1 每一个字节都初始化为0。所以它的结果是分配了numsize个字节长度的内存空间,并且每 个字节的值都是0。 | | 2 | void free(void address);该函数释放address所指向的内存块,释放的是动态分配的内存空间。 | | 3 | void malloc(int num);在堆区分配一块指定大小的内存空间,用来存放数据。这块内存空间在函数执行完成后不会被初始化,它们的值是未知的。 | | 4 | void realloc(void address, int newsize);该函数重新分配内存,把内存扩展newsize。 |

  • 通常使用malloc和free就足够 ```c

    include

    include

void main() {

int array_length;
//数组长度
scanf("%d",&array_length);//接收用户输入的长度
//int array[array_length];c语言不允许这种语法,数组定义时必须知道长度
int *parry=(int*)malloc(sizeof(int)* array_length);//动态分配内存
for(int i=0;i<array_length; i++)
{
    scanf("%d",&parry[i]);
}

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

//释放内存
free(parry);
parry = NULL;//空指针,不指向空(悬空指)

}

<a name="LlbLB"></a>
# 13 struct 结构体

- C数组允许定义可存储相同类型数据项的变量,**结构**是C编程中另一种用户自定义的可用的数据类型, 它允许您存储不同类型的数据项
- 学生信息
```c
struct Student{
            //声明结构体
            int id;
            char name[20];
            float score;
            } stu1,stu2;
    //定义两个结构体变量
    struct Student obj1,obj2; // 定义两个结构体变量, C语言必须在结构体名前加structobj1.id。100;
    strcpy(obj1.name,"小明",strlen("小明")+1); 
    obj1.score = 99.2;
}
  • typedef类型重命名

    typedef int INT;
      //将int重新命名INT,之后所有的INT等价于int
      INT number =10;
      //使用重命名的INT,等价于int number;
      INT *p ;
      typedef struct Student{
          //声明结构体
          int id;
          char name[20];
          float score; 
      }STUDENT,*STUDENT;
      //创建两个类型名,结构体类型和指针类型
      STUDENT obj1;
      //相当于 struct student obj1,
    

    14 函数指针

  • 函数指针是指向函数的指针变量。

  • 函数指针可以像-般函数-样,用于调用函数、传递参数。
  • 函数指针声明 ```c

    include

    include

int fun(int a, int b){ return a+b; }

//定义一个指向上面函数的函数指针 //返回值int,函数指针类型名PFUN, 参数有两个(参数类型,参数类型) typedef int (*PFUN)(int,int); //函数指针使用 //定义一个类型为PFUN函数指针类型的变量,变量名是pfun,将上面函数赋值给这个变量 PFUN pfun = fun;

int main() { //通过这个函数指针变量调用这个函数 printf(“a+b = %d\n”,pfun(10,20)); return 0; }

<a name="zB8fH"></a>
# 15 预处理

- 程序在编译阶段中有一个预处理阶段, 预处理命令在这个阶段会被展开
- C语言的预处理命令是以#开头的
```c
#include <stdio.h> //将stdio.h 文件在这个地方展开,预处理时
  • 宏 ```c

    define PI 3.14 //定义一个PI宏,之后所有的PI都会被替换成3.14不能加;号

    int a=PI33; // 将会被替换成3.14 * 3”3

undefine PI //从这个地方后的PI将不在代表3.14


- 有参宏
```c
#define fun(x,y) x*y    //带参数的宏
int x = fun(5,7);         //会被替换成5+7
int y = fun(5+7,3)        //宏只是简单替换5+7*3 = 26
  • 条件编译(宏)
    #define VALUE日        //定义一个宏
    #if VALUE            //条件编译,判断VALUE的值是真是假
      printf("value = 0\n");
    #else                //条件不成立
      printf("value != 0\n");
    #endif                // #if结束时必须endif结束
    
    #define DEBUG            //定义DEBUG宏
    #ifdef DEBUG            //如果定了DEBUG宏,执行
      printf("hello");     //输出调试信息
    #endif
    #ifndef DEBUG            //如果没有定义DEBUG就执行
      printf("no define");
    #endif