WHCSRL 技术网

初识C语言二_Britney

1. 选择语句

  • if 
    1. #include <stdio.h>
    2. int main()
    3. {
    4. int input = 0;
    5. scanf("%%d", &input);
    6. if (input == 1)
    7. {
    8. printf("好offer ");
    9. }
    10. else
    11. {
    12. printf("卖红薯 ");
    13. }
    14. return 0;
    15. }
    16. //无else
    17. int main()
    18. {
    19. int a = 0;
    20. if (a == 20)
    21. {
    22. printf("hehe ");
    23. }
    24. return 0;
    25. }

2. 循环语句

  • whlie
    1. int main()
    2. {
    3. int line = 0;
    4. printf("敲代码 ");
    5. while (line<20000)
    6. {
    7. printf("继续敲代码 ");
    8. line = line + 1;
    9. }
    10. if (line >= 20000)
    11. printf("好offer ");
    12. else
    13. printf("火候还不够 ");
    14. return 0;
    15. }

3. 函数

  1. #include <stdio.h>
  2. int main()
  3. {
  4. int num1 = 0;
  5. int num2 = 0;
  6. int sum = 0;
  7. printf("输入两个操作数:>");
  8. scanf("%%d %%d", &num1, &num2);
  9. sum = num1 + num2;
  10. printf("sum = %%d ", sum);
  11. return 0;
  12. }
  13. 上述代码,写成函数如下:
  14. #include <stdio.h>
  15. int Add(int x, int y)
  16. {
  17. int z = x+y;
  18. return z;
  19. }
  20. int main()
  21. {
  22. int num1 = 0;
  23. int num2 = 0;
  24. int sum = 0;
  25. printf("输入两个操作数:>");
  26. scanf("%%d %%d", &num1, &num2);
  27. sum = Add(num1, num2);
  28. printf("sum = %%d ", sum);
  29. return 0;
  30. }

特点就是简化代码,代码复用

4. 数组

  1. 数组的定义(一组相同类型元素的集合)
  2. int arr[10] = {1,2,3,4,5,6,7,8,9,10};//定义一个整形数组,最多放10个元素
  3. 数组的下标
    1. int arr[10] = {0};
    2. //如果数组10个元素,下标的范围是0-9
    3. //数组每个元素都有一个下标,并且下标从0开始,数组通过下标访问
    4. int arr[10] 0 0 0 0 0 0 0 0 0 0
    5. 下标 0 1 2 3 4 5 6 7 8 9
    6. int main()
    7. {
    8. //arr就是10个元素的整型数组
    9. int arr[10] = {1,2,3,4,5,6,7,8,9,10};
    10. //0~9
    11. int i = 0;//使用i产生下标
    12. while (i<=9)
    13. {
    14. printf("%%d ", arr[i]);
    15. i = i + 1;
    16. }
    17. //printf("%%d ", arr[2]);//3
    18. //存字符 - 字符数组
    19. //char ch[5] = { 'a', 'b', 'c', 'd', 'e' };
    20. //char ch[6] = "hello";
    21. //int arr[10] = {0};
    22. return 0;
    23. }
  4. 数组的使用
    1. #include <stdio.h>
    2. int main()
    3. {
    4. int i = 0;
    5. int arr[10] = {1,2,3,4,5,6,7,8,9,10};
    6. for(i=0; i<10; i++)
    7. {
    8. printf("%%d ", arr[i]);
    9. }
    10. printf(" ");
    11. return 0;
    12. }
    C99 的标准中,支持:变长数组,允许变量来指定数组大小

5. 操作符(运算符就是操作符)

  • 算术操作符
    1. + - * / %%
    2. //注:%% - 取模操作符只能作用于整型

        

  • 移位操作符
    1. >> <<
    2. 作用于二进制位
    3. << 表示二进制位向左移动一位
    4. int a = 3;
    5. int b = a << 1;
    6. printf("%%d ", b);
    7. return 0;
    8. 00000000000000000000000000000011 --> 00000000000000000000000000000110 (缺位用零补上)
    9. 同理
    10. >> 则是二进制位向右移动一位
    11. 00000000000000000000000000000011 --> 00000000000000000000000000000001 (缺位用零补上)

  • 位操作符
    1. & ^ |
    2. int c = a & b;//按位与,对应的二进制位有0,则为0,全1才为1
    3. int c = a | b;//按位或,对应的二进制位有1,则为1,全0才为0
    4. int c = a ^ b;//按位异或,对应的二进制位,相同为0,相异为1
    5. 00000000000000000000000000000011 - 3
    6. 00000000000000000000000000000101 - 5
    7. 3 & 5 则为
    8. 00000000000000000000000000000001 - 1
    9. 3 | 5 则为
    10. 00000000000000000000000000000111 - 7
    11. 3 ^ 5 则为
    12. 00000000000000000000000000000110 - 6

  • 赋值操作符
    1. = += -= *= /= &= ^= |= >>= <<=
    2. int a = 10;
    3. a = a + 4;//= 赋值
    4. a += 4; //+= 复合赋值符
    5. //其他同理

  • 单目操作符(一个操作数,几目操作符由操作数决定)
    1. ! 逻辑反操作
    2. - 负值
    3. + 正值
    4. & 取地址
    5. sizeof 操作数的类型长度 [计算的是变量或者类型所创建变量占据内存的大小-单位是字节]
    6. ~ 对一个数的二进制按位取反
    7. -- 前置、后置-- 前置--,先--,后使用。后置--,先使用,后--
    8. ++ 前置、后置++ 前置++,先++,后使用。后置++,先使用,后++
    9. * 间接访问操作符(解引用操作符,指针再提)
    10. (类型) 强制类型转换
    11. ~ - 按位取反 - (2进制位)
    12. 按位取反是对存在内存中的【补码】进行取反的
    13. int a = -1;
    14. -1 是负整数
    15. 负整数的二进制有原码、反码、补码、
    16. 内存中存储的是二进制的补码
    17. 10000000000000000000000000000001 -原码
    18. 11111111111111111111111111111110 -反码(在原码的基础上除符号位全部按位取反)
    19. 11111111111111111111111111111111 -补码(在反码的基础上+1)
    20. 00000000000000000000000000000000 (-1按位取反的结果) 0

  • 关系操作符
    1. >
    2. >=
    3. <
    4. <=
    5. != 用于测试“不相等”
    6. == 用于测试“相等”

  • 逻辑操作符
    1. && 逻辑与
    2. || 逻辑或
    3. (逻辑语句中使用)

  • 条件操作符
    exp1 ? exp2 : exp3 (也叫三目操作符)
    

  • 逗号表达式
    1. exp1, exp2, exp3, …expN
    2. //逗号表达式会从左向右依次计算
    3. //整个逗号表达式的结果是最后一个表达式的结果

  • 下标引用、函数调用和结构成员
    1. [] () . ->
    2. int arr[10] = { 1,2,3,4,5 };
    3. printf("%%d ", arr[4]);//此处的[]为下标引用操作符arr[4]指的其实是5,数组部分解释
    4. printf"");//此处的()为函数调用操作符
    5. 剩下两个在结构体中解释

6. 关键字

  1. auto 自动,定义自动变量,变量自带自带
  2. break 终止,循环语句中,while,for,do...while,switch
  3. case 用于switch语句中
  4. char 字符形
  5. const 常属性 -- 修饰变量,修饰指针
  6. continue 继续
  7. default 默认 -- switch
  8. do do...while语句
  9. double 双精度浮点形
  10. else if...else语句
  11. enum 枚举
  12. extern 声明外部符号
  13. float 单精度浮点形
  14. for for语句
  15. goto goto语句
  16. if if语句
  17. int 整形
  18. long 长整形
  19. register(建议作用) 寄存器(register int a = 10;)a是寄存器变量,寄存器变量是不能取地址
  20. return 返回,在函数中使用
  21. short 短整形
  22. signed 有符号的
  23. sizeof 运算符
  24. static 静态的
  25. struct 结构体
  26. switch switch语句
  27. typedef 类型重定义
  28. union 联合体
  29. unsigned 无符号的
  30. void 空、无 -- 函数返回类型/函数参数/修饰指针
  31. volatile 易变形变量
  32. while while语句

        1. typedef

        typedef 顾名思义是类型定义,这里应该理解为类型重命名

  1. //将unsigned int 重命名为uint_32, 所以uint_32也是一个类型名
  2. typedef unsigned int uint_32;
  3. int main()
  4. {
  5. //观察num1和num2,这两个变量的类型是一样的
  6. unsigned int num1 = 0;
  7. uint_32 num2 = 0;
  8. return 0;
  9. }

        2. static

        在C语言中:

        static是用来修饰变量和函数的

        1. 修饰局部变量-称为静态局部变量

        2. 修饰全局变量-称为静态全局变量

        3. 修饰函数-称为静态函数

                (1) 修饰局部变量

  1. //代码1
  2. #include <stdio.h>
  3. void test()
  4. {
  5. int i = 0;
  6. i++;
  7. printf("%%d ", i);
  8. }
  9. int main()
  10. {
  11. int i = 0;
  12. for(i=0; i<10; i++)
  13. {
  14. test();
  15. }
  16. return 0;
  17. }
  18. //代码2
  19. #include <stdio.h>
  20. void test()
  21. {
  22. //static修饰局部变量
  23. static int i = 0;
  24. i++;
  25. printf("%%d ", i);
  26. }
  27. int main()
  28. {
  29. int i = 0;
  30. for(i=0; i<10; i++)
  31. {
  32. test();
  33. }
  34. return 0;
  35. }

 对比代码1和代码2的效果理解static修饰局部变量的意义。

static修饰局部变量会将变量存储类型改变(栈区存储 -> 静态区)

编程语言包括:栈区、堆区、静态区

        其中栈区存储局部变量

        动态内存分配在堆区中(malloc,free,calloc,realloc函数的使用与其有关)

        静态区存储全局变量静态变量

 结论: static修饰局部变量改变了变量  的生命周期 让静态局部变量出了作用域依然存在,到程序   结束,生命周期才结束(具有全局变量的生命周期)。

(注:全局变量,静态变量的创建在编译期间已完成)

                (2) 修饰全局变量(具有外部链接属性)

  1. //代码1
  2. //add.c
  3. int g_val = 2018;
  4. //test.c
  5. int main()
  6. {
  7. printf("%%d ", g_val);
  8. return 0;
  9. }
  10. //代码2
  11. //add.c
  12. static int g_val = 2018;
  13. //test.c
  14. int main()
  15. {
  16. printf("%%d ", g_val);
  17. return 0;
  18. }

        代码1正常,代码2在编译的时候会出现连接性错误。

         结论: 一个全局变量被static修饰,使得这个全局变量只能在本源文件内使用,不能在其他源文件内使用。( 即链接属性改变,从外部链接属性变为内部链接属性,作用域变小)

                (3) 修饰函数(具有外部链接属性)

  1. //代码1
  2. //add.c
  3. int Add(int x, int y)
  4. {
  5. return c+y;
  6. }
  7. //test.c
  8. int main()
  9. {
  10. printf("%%d ", Add(2, 3));
  11. return 0;
  12. }
  13. //代码2
  14. //add.c
  15. static int Add(int x, int y)
  16. {
  17. return c+y;
  18. }
  19. //test.c
  20. int main()
  21. {
  22. printf("%%d ", Add(2, 3));
  23. return 0;
  24. }

                代码1正常,代码2在编译的时候会出现连接性错误.

                结论: 一个函数被static修饰,使得这个函数只能在本源文件内使用,不能在其他源文件内使用.(与修饰全局变量一致,将外部链接属性改为内部链接属性)

7. #define定义常量和宏

  1. //define定义标识符常量
  2. #define MAX 1000
  3. //define定义宏
  4. #define ADD(x, y) ((x)+(y))
  5. #include <stdio.h>
  6. int main()
  7. {
  8. int sum = ADD(2, 3);
  9. printf("sum = %%d ", sum);
  10. sum = 10*ADD(2, 3);
  11. printf("sum = %%d ", sum);
  12. return 0;
  13. }

注:   (1)#define定义的宏为预处理指令,即运算不先算,如下:
  1. #include <stdio.h>
  2. #define s(a) a*a
  3. int main()
  4. {
  5. int x = s (2 + 3);
  6. printf("%%d",x);
  7. return 0;
  8. }
  9. //结果为 11
  10. //2 + 3 * 2 + 3 = 11
  11. //预处理指令2+3不先运算

              (2)#define 定义的标识符常量一般习惯大写

8. 指针

        1. 内存

内存是电脑上特别重要的存储器,计算机中程序的运行都是在内存中进行的 。 所以为了有效的使用内存,就把内存划分成一个个小的内存单元,每个内存单元的大小是1个字节。 为了能够有效的访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为该内存单元的地址

变量是创建内存中的(在内存中分配空间的),每个内存单元都有地址,所以变量也是有地址的。 取出变量地址如下:

  1. #include <stdio.h>
  2. int main()
  3. {
  4. int num = 10;
  5. &num;//取出num的地址
  6. //注:这里num的4个字节,每个字节都有地址,取出的是第一个字节的地址(较小的地址)
  7. printf("%%p ", &num);//打印地址,%%p是以地址的形式打印
  8. return 0;
  9. }

注:%%p   为打印地址

        %%s   为打印字符串

        &     为取地址操作符  (&a; //取出的是所占4个字节空间的第一个字节的地址,也就是地址更小的那一个字节)

        *      为解引用操作符 / 间接访问操作符

那地址如何存储,需要定义指针变量

  1. int num = 10;
  2. int *p;//p为一个整形指针变量
  3. p = &num;

注:int * p 表p为一个指针变量,* 是指针的标志,int为原来变量的数据类型(与原变量的数据类型需一致),p表示为变量名

        指针的使用实例:

  1. 1
  2. #include <stdio.h>
  3. int main()
  4. {
  5. int num = 10;
  6. int *p = &num;
  7. *p = 20;
  8. return 0;
  9. }
  10. 2
  11. int main()
  12. {
  13. int a = 10;
  14. //%%p - 打印的格式来打印
  15. printf("%%p ", &a);
  16. int * p = &a;//p是用来存放地址的,所以我们把p称为指针变量
  17. *p = 20;//*的解引用操作符,*p的意思就是通过p中的值,找到p所指向的对象,也就是说*p就是a
  18. printf("%%d ", a);
  19. printf("%%d ", sizeof(p));
  20. printf("%%p ", p);
  21. printf("%%p ", &a);
  22. return 0;
  23. }

        除int * 类型外,还有char * ......

                2. 指针变量的大小

  1. #include <stdio.h>
  2. //指针变量的大小取决于地址的大小
  3. //32位平台下地址是32个bit位(即4个字节)
  4. //64位平台下地址是64个bit位(即8个字节)
  5. int main()
  6. {
  7. printf("%%d ", sizeof(char *));
  8. printf("%%d ", sizeof(short *));
  9. printf("%%d ", sizeof(int *));
  10. printf("%%d ", sizeof(double *));
  11. return 0;
  12. }

                ( 指针变量的大小由编译程序时的编译程序决定 )

                  指针大小在32位平台是4个字节,64位平台是8个字节

9. 结构体(针对复杂的对象,如人,书 等等)

结构体是C语言中特别重要的知识点,结构体使得C语言有能力描述复杂类型。

比如描述学生,学生包含: 名字+年龄+性别+学号 这几项信息。

这里只能使用结构体来描述了。

注:

.    结构体成员访问的操作符

结构体变量.结构体成员

->  结构体成员访问的操作符

结构体指针->结构体成员

    ( 汉字占两个字节 )

  1. struct Stu
  2. {
  3. char name[20];//名字
  4. int age; //年龄
  5. char sex[5]; //性别
  6. char id[15]; //学号
  7. };

结构体的初始化:

  1. //打印结构体信息
  2. struct Stu s = {"张三"20"男""20180101"};
  3. //.为结构成员访问操作符
  4. printf("name = %%s age = %%d sex = %%s id = %%s ", s.name, s.age, s.sex, s.id);
  5. //->操作符
  6. struct Stu *ps = &s;
  7. printf("name = %%s age = %%d sex = %%s id = %%s ", ps->name, ps->age, ps->sex, ps-
  8. >id);
  1. #include <string.h>
  2. //结构体类型的定义
  3. struct Stu
  4. {
  5. //结构体的成员
  6. char name[20];
  7. int age;
  8. char sex[10];
  9. };
  10. int main()
  11. {
  12. //创建结构体变量,并且初始化
  13. struct Stu zhangsan = {"张三", 30, "男"};
  14. struct Stu lisi = {"李四", 24, "保密"};
  15. //->这个操作符
  16. struct Stu * pl = &lisi;
  17. printf("%%s %%d %%s ", (*pl).name, (*pl).age, (*pl).sex);
  18. printf("%%s %%d %%s ", pl->name, pl->age, pl->sex);
  19. //打印结构体的数据
  20. //printf("%%s %%d %%s ", zhangsan.name, zhangsan.age, zhangsan.sex);
  21. //printf("%%s %%d %%s ", lisi.name, lisi.age, lisi.sex);
  22. return 0;
  23. }
推荐阅读