初识C语言二_Britney
1. 选择语句
- if
- #include <stdio.h>
- int main()
- {
- int input = 0;
- scanf("%%d", &input);
- if (input == 1)
- {
- printf("好offer ");
- }
- else
- {
- printf("卖红薯 ");
- }
- return 0;
- }
- //无else
- int main()
- {
- int a = 0;
- if (a == 20)
- {
- printf("hehe ");
- }
- return 0;
- }
2. 循环语句
- whlie
-
- int main()
- {
- int line = 0;
- printf("敲代码 ");
- while (line<20000)
- {
- printf("继续敲代码 ");
- line = line + 1;
- }
- if (line >= 20000)
- printf("好offer ");
- else
- printf("火候还不够 ");
- return 0;
- }
3. 函数
- #include <stdio.h>
- int main()
- {
- int num1 = 0;
- int num2 = 0;
- int sum = 0;
- printf("输入两个操作数:>");
- scanf("%%d %%d", &num1, &num2);
- sum = num1 + num2;
- printf("sum = %%d
", sum);
- return 0;
- }
- 上述代码,写成函数如下:
- #include <stdio.h>
- int Add(int x, int y)
- {
- int z = x+y;
- return z;
- }
- int main()
- {
- int num1 = 0;
- int num2 = 0;
- int sum = 0;
- printf("输入两个操作数:>");
- scanf("%%d %%d", &num1, &num2);
- sum = Add(num1, num2);
- printf("sum = %%d
", sum);
- return 0;
- }
特点就是简化代码,代码复用
4. 数组
- 数组的定义(一组相同类型元素的集合)
-
int arr[10] = {1,2,3,4,5,6,7,8,9,10};//定义一个整形数组,最多放10个元素
- 数组的下标
- int arr[10] = {0};
- //如果数组10个元素,下标的范围是0-9
- //数组每个元素都有一个下标,并且下标从0开始,数组通过下标访问
- int arr[10] 0 0 0 0 0 0 0 0 0 0
- 下标 0 1 2 3 4 5 6 7 8 9
- int main()
- {
- //arr就是10个元素的整型数组
- int arr[10] = {1,2,3,4,5,6,7,8,9,10};
- //0~9
- int i = 0;//使用i产生下标
- while (i<=9)
- {
- printf("%%d ", arr[i]);
- i = i + 1;
- }
- //printf("%%d ", arr[2]);//3
- //存字符 - 字符数组
- //char ch[5] = { 'a', 'b', 'c', 'd', 'e' };
- //char ch[6] = "hello";
- //int arr[10] = {0};
- return 0;
- }
- 数组的使用
C99 的标准中,支持:变长数组,允许变量来指定数组大小- #include <stdio.h>
- int main()
- {
- int i = 0;
- int arr[10] = {1,2,3,4,5,6,7,8,9,10};
- for(i=0; i<10; i++)
- {
- printf("%%d ", arr[i]);
- }
- printf(" ");
- return 0;
- }
5. 操作符(运算符就是操作符)
- 算术操作符
- + - * / %%
- //注:%% - 取模操作符只能作用于整型
- 移位操作符
- >> <<
- 作用于二进制位
- << 表示二进制位向左移动一位
- int a = 3;
- int b = a << 1;
- printf("%%d ", b);
- return 0;
- 00000000000000000000000000000011 --> 00000000000000000000000000000110 (缺位用零补上)
- 同理
- >> 则是二进制位向右移动一位
- 00000000000000000000000000000011 --> 00000000000000000000000000000001 (缺位用零补上)
- 位操作符
- & ^ |
- int c = a & b;//按位与,对应的二进制位有0,则为0,全1才为1
- int c = a | b;//按位或,对应的二进制位有1,则为1,全0才为0
- int c = a ^ b;//按位异或,对应的二进制位,相同为0,相异为1
- 00000000000000000000000000000011 - 3
- 00000000000000000000000000000101 - 5
- 3 & 5 则为
- 00000000000000000000000000000001 - 1
- 3 | 5 则为
- 00000000000000000000000000000111 - 7
- 3 ^ 5 则为
- 00000000000000000000000000000110 - 6
- 赋值操作符
- = += -= *= /= &= ^= |= >>= <<=
- int a = 10;
- a = a + 4;//= 赋值
- a += 4; //+= 复合赋值符
- //其他同理
- 单目操作符(一个操作数,几目操作符由操作数决定)
- ! 逻辑反操作
- - 负值
- + 正值
- & 取地址
- sizeof 操作数的类型长度 [计算的是变量或者类型所创建变量占据内存的大小-单位是字节]
- ~ 对一个数的二进制按位取反
- -- 前置、后置-- 前置--,先--,后使用。后置--,先使用,后--
- ++ 前置、后置++ 前置++,先++,后使用。后置++,先使用,后++
- * 间接访问操作符(解引用操作符,指针再提)
- (类型) 强制类型转换
- ~ - 按位取反 - (2进制位)
- 按位取反是对存在内存中的【补码】进行取反的
- int a = -1;
- -1 是负整数
- 负整数的二进制有原码、反码、补码、
- 内存中存储的是二进制的补码
- 10000000000000000000000000000001 -原码
- 11111111111111111111111111111110 -反码(在原码的基础上除符号位全部按位取反)
- 11111111111111111111111111111111 -补码(在反码的基础上+1)
- 00000000000000000000000000000000 (-1按位取反的结果) 0
- 关系操作符
- >
- >=
- <
- <=
- != 用于测试“不相等”
- == 用于测试“相等”
- 逻辑操作符
- && 逻辑与
- || 逻辑或
- (逻辑语句中使用)
- 条件操作符
exp1 ? exp2 : exp3 (也叫三目操作符)
- 逗号表达式
- exp1, exp2, exp3, …expN
- //逗号表达式会从左向右依次计算
- //整个逗号表达式的结果是最后一个表达式的结果
- 下标引用、函数调用和结构成员
- [] () . ->
- int arr[10] = { 1,2,3,4,5 };
- printf("%%d ", arr[4]);//此处的[]为下标引用操作符arr[4]指的其实是5,数组部分解释
- printf("");//此处的()为函数调用操作符
- 剩下两个在结构体中解释
6. 关键字
- auto 自动,定义自动变量,变量自带自带
- break 终止,循环语句中,while,for,do...while,switch
- case 用于switch语句中
- char 字符形
- const 常属性 -- 修饰变量,修饰指针
- continue 继续
- default 默认 -- switch
- do do...while语句
- double 双精度浮点形
- else if...else语句
- enum 枚举
- extern 声明外部符号
- float 单精度浮点形
- for for语句
- goto goto语句
- if if语句
- int 整形
- long 长整形
- register(建议作用) 寄存器(register int a = 10;)a是寄存器变量,寄存器变量是不能取地址
- return 返回,在函数中使用
- short 短整形
- signed 有符号的
- sizeof 运算符
- static 静态的
- struct 结构体
- switch switch语句
- typedef 类型重定义
- union 联合体
- unsigned 无符号的
- void 空、无 -- 函数返回类型/函数参数/修饰指针
- volatile 易变形变量
- while while语句
-
-
1. typedef
typedef 顾名思义是类型定义,这里应该理解为类型重命名
- //将unsigned int 重命名为uint_32, 所以uint_32也是一个类型名
- typedef unsigned int uint_32;
- int main()
- {
- //观察num1和num2,这两个变量的类型是一样的
- unsigned int num1 = 0;
- uint_32 num2 = 0;
- return 0;
- }
2. static
在C语言中:
static是用来修饰变量和函数的
1. 修饰局部变量-称为静态局部变量
2. 修饰全局变量-称为静态全局变量
3. 修饰函数-称为静态函数
(1) 修饰局部变量
- //代码1
- #include <stdio.h>
- void test()
- {
- int i = 0;
- i++;
- printf("%%d ", i);
- }
- int main()
- {
- int i = 0;
- for(i=0; i<10; i++)
- {
- test();
- }
- return 0;
- }
- //代码2
- #include <stdio.h>
- void test()
- {
- //static修饰局部变量
- static int i = 0;
- i++;
- printf("%%d ", i);
- }
- int main()
- {
- int i = 0;
- for(i=0; i<10; i++)
- {
- test();
- }
- return 0;
- }
对比代码1和代码2的效果理解static修饰局部变量的意义。
static修饰局部变量会将变量存储类型改变(栈区存储 -> 静态区)
编程语言包括:栈区、堆区、静态区
其中栈区存储局部变量
动态内存分配在堆区中(malloc,free,calloc,realloc函数的使用与其有关)
静态区存储全局变量和静态变量
结论: static修饰局部变量改变了变量 的生命周期 让静态局部变量出了作用域依然存在,到程序 结束,生命周期才结束(具有全局变量的生命周期)。
(注:全局变量,静态变量的创建在编译期间已完成)
(2) 修饰全局变量(具有外部链接属性)
- //代码1
- //add.c
- int g_val = 2018;
- //test.c
- int main()
- {
- printf("%%d
", g_val);
- return 0;
- }
- //代码2
- //add.c
- static int g_val = 2018;
- //test.c
- int main()
- {
- printf("%%d
", g_val);
- return 0;
- }
代码1正常,代码2在编译的时候会出现连接性错误。
结论: 一个全局变量被static修饰,使得这个全局变量只能在本源文件内使用,不能在其他源文件内使用。( 即链接属性改变,从外部链接属性变为内部链接属性,作用域变小)
(3) 修饰函数(具有外部链接属性)
- //代码1
- //add.c
- int Add(int x, int y)
- {
- return c+y;
- }
- //test.c
- int main()
- {
- printf("%%d
", Add(2, 3));
- return 0;
- }
- //代码2
- //add.c
- static int Add(int x, int y)
- {
- return c+y;
- }
- //test.c
- int main()
- {
- printf("%%d
", Add(2, 3));
- return 0;
- }
代码1正常,代码2在编译的时候会出现连接性错误.
结论: 一个函数被static修饰,使得这个函数只能在本源文件内使用,不能在其他源文件内使用.(与修饰全局变量一致,将外部链接属性改为内部链接属性)
7. #define定义常量和宏
- //define定义标识符常量
- #define MAX 1000
- //define定义宏
- #define ADD(x, y) ((x)+(y))
- #include <stdio.h>
- int main()
- {
- int sum = ADD(2, 3);
- printf("sum = %%d
", sum);
-
- sum = 10*ADD(2, 3);
- printf("sum = %%d
", sum);
-
- return 0;
- }
注: (1)#define定义的宏为预处理指令,即运算不先算,如下:
- #include <stdio.h>
- #define s(a) a*a
- int main()
- {
- int x = s (2 + 3);
- printf("%%d",x);
- return 0;
- }
-
-
- //结果为 11
- //2 + 3 * 2 + 3 = 11
- //预处理指令2+3不先运算
(2)#define 定义的标识符常量一般习惯大写
8. 指针
1. 内存
内存是电脑上特别重要的存储器,计算机中程序的运行都是在内存中进行的 。 所以为了有效的使用内存,就把内存划分成一个个小的内存单元,每个内存单元的大小是1个字节。 为了能够有效的访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为该内存单元的地址。
变量是创建内存中的(在内存中分配空间的),每个内存单元都有地址,所以变量也是有地址的。 取出变量地址如下:
- #include <stdio.h>
- int main()
- {
- int num = 10;
- #//取出num的地址
- //注:这里num的4个字节,每个字节都有地址,取出的是第一个字节的地址(较小的地址)
- printf("%%p
", &num);//打印地址,%%p是以地址的形式打印
- return 0;
- }
注:%%p 为打印地址
%%s 为打印字符串
& 为取地址操作符 (&a; //取出的是所占4个字节空间的第一个字节的地址,也就是地址更小的那一个字节)
* 为解引用操作符 / 间接访问操作符
那地址如何存储,需要定义指针变量
- int num = 10;
- int *p;//p为一个整形指针变量
- p = #
注:int * p 表p为一个指针变量,* 是指针的标志,int为原来变量的数据类型(与原变量的数据类型需一致),p表示为变量名
指针的使用实例:
- 例1:
- #include <stdio.h>
- int main()
- {
- int num = 10;
- int *p = #
- *p = 20;
- return 0;
- }
-
-
- 例2:
- int main()
- {
- int a = 10;
- //%%p - 打印的格式来打印
- printf("%%p
", &a);
-
- int * p = &a;//p是用来存放地址的,所以我们把p称为指针变量
- *p = 20;//*的解引用操作符,*p的意思就是通过p中的值,找到p所指向的对象,也就是说*p就是a
-
- printf("%%d
", a);
- printf("%%d
", sizeof(p));
-
- printf("%%p
", p);
- printf("%%p
", &a);
-
- return 0;
- }
除int * 类型外,还有char * ......
2. 指针变量的大小
- #include <stdio.h>
- //指针变量的大小取决于地址的大小
- //32位平台下地址是32个bit位(即4个字节)
- //64位平台下地址是64个bit位(即8个字节)
- int main()
- {
- printf("%%d
", sizeof(char *));
- printf("%%d
", sizeof(short *));
- printf("%%d
", sizeof(int *));
- printf("%%d
", sizeof(double *));
- return 0;
- }
( 指针变量的大小由编译程序时的编译程序决定 )
指针大小在32位平台是4个字节,64位平台是8个字节
9. 结构体(针对复杂的对象,如人,书 等等)
结构体是C语言中特别重要的知识点,结构体使得C语言有能力描述复杂类型。
比如描述学生,学生包含: 名字+年龄+性别+学号 这几项信息。
这里只能使用结构体来描述了。
注:
. 结构体成员访问的操作符
结构体变量.结构体成员
-> 结构体成员访问的操作符
结构体指针->结构体成员
( 汉字占两个字节 )
- struct Stu
- {
- char name[20];//名字
- int age; //年龄
- char sex[5]; //性别
- char id[15]; //学号
- };
结构体的初始化:
- //打印结构体信息
- struct Stu s = {"张三", 20, "男", "20180101"};
- //.为结构成员访问操作符
- printf("name = %%s age = %%d sex = %%s id = %%s
", s.name, s.age, s.sex, s.id);
- //->操作符
- struct Stu *ps = &s;
- printf("name = %%s age = %%d sex = %%s id = %%s
", ps->name, ps->age, ps->sex, ps-
- >id);
- #include <string.h>
- //结构体类型的定义
- struct Stu
- {
- //结构体的成员
- char name[20];
- int age;
- char sex[10];
- };
-
- int main()
- {
- //创建结构体变量,并且初始化
- struct Stu zhangsan = {"张三", 30, "男"};
- struct Stu lisi = {"李四", 24, "保密"};
-
- //->这个操作符
- struct Stu * pl = &lisi;
- printf("%%s %%d %%s
", (*pl).name, (*pl).age, (*pl).sex);
- printf("%%s %%d %%s
", pl->name, pl->age, pl->sex);
-
- //打印结构体的数据
- //printf("%%s %%d %%s
", zhangsan.name, zhangsan.age, zhangsan.sex);
- //printf("%%s %%d %%s
", lisi.name, lisi.age, lisi.sex);
-
- return 0;
- }
-
-