【知识点1】C语言的关键字
在C语言中,有32个特殊含义的保留关键字
1 数据的存储
1.1 计算机中的数据
计算机中的文本、图像、音频、视频等所有的数据,都采用的二进制方式进行存储
二进制数据:每一位的数据编码由0和1构成。最终的数据为二进制编码序列表示。
数据的整体读写不方便,对于某一位的读写比较方便。
十进制数据:每一位的数据编码由0~9十种状态构成。
数据的整体读写方便;对于某位的状态获取较麻烦,不利于计算机数据的表示。
为了能够更好的表示计算机数据,并且便于人的阅读,提供了八进制和十六进制表示。
八进制:每一位数据由0~7八种状态构成,数据的起始使用0表示; 0777;
十六进制:每一位数据由0~9和a~f十六种状态构成,数据的起始使用0x表示; 0x12345678
1.2 进制之间的转换
1.2.1 整数的进制转换
- 十进制转换为:对应的二进制、八进制和十六进制编码形式。
循环将需要转换的十进制数据 对转换的编码进行取余和取整,直到整数为零结束;
- 对应的二进制、八进制和十六进制转十进制
将数据编码的位编码 * 进制的位次方并累加的结果;
1.2.2 小数的进制转换
小数转换位二进制编码:乘2取整,在循环对小数部分转换。
1.3 数据的存储
正数存储的数据的源码:其源码为数据本身的二进制编码
负数存储的数据的补码: -124
负数的补码,实质就是数据的正数部分的二进制编码取反+1
1) 正数部分的源码,也就是124的二进制编码: 0111 1100
2) 反码,是将源码的所有位取反,包括符号位:1000 0011
3) 补码:是反码+1 1000 0100
2 C语言数据类型关键字
C语言提供了12个数据类型关键字。
2.1 基本数据类型
- 整型数据
char 字节型数据 所占存储空间的大小:1字节
值域范围:
无符号数据:unsigned char 数据的位都为数据位,char数据位占8位,值域范围:0~255
有符号数据:signed char 符号位(1位) + 数据位(7位)
最高位为符号位:0 = 正数;1 = 负数
-128 存储编码(也就是补码)和128的源码一致。
short 短整型数据 所占存储空间的大小:2字节file:///C:/Users/Administrator/Desktop/截图.png
int 整型数据 所占存储空间的大小:2字节(16位系统)、4字节(32位系统)
long 长整型数据 所占存储空间的大小:4字节(32位系统)、8字节(64位系统)
- 浮点数据
float 单精度浮点型数据 所占存储空间大小:4字节
#include <stdio.h> int main() { float f = 23.625; int *p = &f; printf("%x\n", *p); }
double 双精度浮点型数据 所占存储空间大小:8字节
2.2 构造数据类型
struct 结构体数据类型关键字
union 共用体数据类型关键字
enum 枚举类型关键字
2.3 特殊数据类型关键字
void 不能用来定义数据类型变量,可以修饰函数的参数和返回值数据类型,以及用来定义指针类型变量。
3 存储类型关键字
3.1 常量和变量
在计算机中的数据,可以使用常量和变量存储。
3.1.1 常量
所谓的常量,指的是不能被修改的量,称为常量。
3.1.1.1 基本数据常量
- 整型常量
所谓的整型常量,指的是数值为整型值的常量,在C语言中可以使用十进制(123)、十六进制(0x7b)、八进制(0173)表示。
- 字符常量
所谓的字符常量,是特殊的整型常量。使用单引号包含的字符(字母、数字和特殊符号)数据。实际在内存中数据存储为字符的ASCII编码。例如:'a'
- 字符串常量
所谓的字符串常量,是由多个连续的字符组合且使用双引号所包含的数据,称为字符串常量,在字符串常量的末尾默认由字符'\0'结尾。例如:"hello C";
- 浮点型常量
所谓的浮点型常量,指的是数值为浮点型数据的常量,默认情况浮点型数据类型为double类型。34.567
- 指数常量
所谓指数常量,是特殊的浮点型常量,可以用于表示较大或者较小的浮点型数据。
格式:+/-Me+/-N
3.1.1.2 标识符常量
所谓的标识常量,指的是使用标识符标识常量值,可以直接通过标识符访问,可以增强代码的可读性。
格式:
#define 标识符号 常量值
注意:
标识符的定义满足标识符定义的语法规则:
1) 由数字、下划线、字母构成;
2) 不能以数字开头;
3) 尽可能做到见名知意的效果;
4) 不能和关键字同名;
常量值:
1) 是任意基本数据常量;
2) 是常量表达式;
3) 特殊语句功能块
1) 宏函数功能实
在定义宏函数的时候,尽可能的多添加圆括号,保证语句的语义不出现歧义。
2) DEBUG调试宏语句
标准C库的宏定义: __FUNCTION__ 或者 __func__ : 表示调用该宏定义的函数名称 __FILE__ 表示调用该宏定义的文件名称 __LINE__ 表示调用该宏定义的行数
标识符常量的作用时间:
程序分为编辑、编译和执行;
程序的编译:预处理、编译、汇编和链接四个阶段;、
预处理阶段:注意实现宏替换、选择编译;将源程序预处理得到预处理文件
gcc -E hello.c -o hello.i
标识符常量作用在预处理阶段,实现符号的替换。
#include <stdio.h> #define MAXN 10 #define ONE 1 #define TWO ONE+ONE #define ADD(x, y) ((x)+(y)) #define SUB(x, y) ((x)-(y)) #define MUL(x, y) ((x)*(y)) #define TEST 0 #if TEST /* 预处理指令:条件成立则选择编译,不成立则不编译 */ #define DEBUG printf("%s:%d:%s\n", __FILE__, __LINE__, __func__) #else #define DEBUG #endif void test(void) { printf("%s:%d:%s:%s`\n", __FILE__, __LINE__, __FUNCTION__, __DATE__); } int main() {printf("%f\n", 234.567); printf("%e\n", -0.00000000000123456); test(); printf("%d\n", ONE); printf("%d\n", TWO); DEBUG; /* 根据TEST条件,选择替换 */ printf("%d\n", MUL(3, 4)); printf("%f\n", MUL(3.1, 4.3)); printf("%d\n", MUL(3+1, 4)); printf("%d\n", MUL(ADD(3,2), SUB(5,2))); printf("%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); }
3.1.2 变量
所谓的变量,指的是数值可以发生改变的量称为变量。
- 语法:
存储类型 数据类型 变量名;
数据类型:可以是任意数据类型,可以基本数据类型和构造数据类型;
变量名:是变量的标识符,满足表示符定义的语法规则。
存储类型:修饰变量的存储属性。
- 全局变量和局部变量
全局变量:存储位置为静态存储区,生命周期为程序执行到程序结束,作用域为全局域(整个程序域中都可以访问)。
局部变量:存储位置为栈区,生命周期为程序语句执行到模块结束,作用域为模块域。
3.2 存储类型关键字
- auto
为自动存储类型关键字,只能修饰局部变量,不能修饰全局变量;
使用auto修饰的变量一定存储栈区,生命周期为语句执行到模块结束,作用域为模块域;
对于未被其它存储类型关键字修饰的局部变量,自动为auto类型变量。
- register
为寄存器类型关键字,所修饰的变量存储在寄存器中,不存在内存中;并且只能修饰局部变量不能修饰全局变量。
对于寄存器变量不能取地址运算。
寄存器变量的运行效率较高;
由于寄存器数量有限,不能定义太多的寄存器变量,如果定义失败,默认为auto类型变量。
- extern
作为外部声明引用关键字,不用于变量的定义,用于函数和变量的外部声明引用。
- static
修饰静态存储变量关键字
1) 修饰全局变量和函数:
改变变量的作用域:
未被static修饰的全局变量和函数,作用域为程序域;使用static修饰的全局变量和函数,作用域为文件域。
2) 修饰局部变量
改变变量的存储位置和生命周期
未被static修饰的局部变量,存储位置为栈区,生命周期为语句执行到模块结束;
使用static修饰的局部变量,存储位置为静态存储区,生命周期为程序执行到程序结束。下一次执行访问到上一次执行的结果。
3.3 C语言中的运算符
- 算术运算符
+、-、*、/、%、++、--
/:操作数为整数,取整运算;操作数为浮点型数据,除法运算;
%:操作数只能是整数,表示取余运算。
++:
前加加:++a 先完成自加运算,在取值。
后加加:a++ 先取值,在完成自加运算。
- 关系运算和逻辑运算符
关系运算符和逻辑运算符的处理结果为真(true、非零)和假(false、为零)
关系运算符:>、=、
逻辑运算符:
! :逻辑非,输入为真输出为假;输入为假输出为真;
&& :逻辑与,输入都为真,输出才为真;否则输出为假。在表达式1为假的时候表达式2不会在执行,只有在表达式1为真的时候表达式2才会执行。
|| :逻辑或,输入都为假,输出才为假;否则输出为真。在表达式1为真的时候表达式2不会在执行,只有在表达式1为假的时候表达式2才会执行。
- 位运算:
~ :按位取反,将数据的所有位(包含符号位)取反;
& :按位相与,两个数据的对应位都为1结果为1,否则结果为0。用于将数据的某位清零(设置为0);
| :按位相或,两个数据的对应位都为0结果为0,否则结果为1。用于将数据的某位置位(设置为1);
^ :按位异或,两个数据的对应位相同为0,不同结果为1。
>> :右移位运算符
1) 逻辑右移: 数据的二进制编码依次向右移动n位,右边的n位溢出,左边的n位使用0补充
2) 算术右移: 数据的二进制编码依次向右移动n位,右边的n位溢出,左边的n位使用符号位(负数 = 1, 正数 = 0)
补充
3) 数据的右移方式由系统决定。
- 赋值和复合赋值运算符
=、+=、-=、*=、/=、%=、&=、|=、^=、>=
- sizeof运算符
计算数据所占存储空间的大小:变量、常量、指针和数据类型;
- 条件运算符:
条件表达式?表达式1:表达式2 当条件表达式成立执行表达式1,否则条件表达式不成立执行表达式2;
- 逗号运算符
将将圆括号中的多个表达式使用逗号进行分隔,其结果由最后一个表达式决定。
注意运算符的运算符的优先级:
单目运算符的优先级高于双目运算符优先级;
非、算、关、与或、赋,优先级递减。
4 控制语句关键字
在C语言中,一个提供了12个控制语句关键字,有三种语句结构
4.1 顺序执行语句
C语言中程序执行按照语句的先后顺序执行。
4.2 条件分支语句
4.2.1 if...else...条件分支语句
1. if 语句 if(条件表达式) { 执行语句单元; /* 当条件表达式结果为true的时候,进入到内部执行 */ } 2. if……else 语句 if (条件表达式) { 执行语句单元1; /* 当条件表达式结果为true的时候,进入单元1部分执行 */ } else { 执行语句单元2; /* 当条件表达式结果为false的时候,进入单元2部分执行 */ } 3. if...else if 语句 也称为if...else嵌套语句 #include <stdio.h> int main() { int score; scanf("%d", &score); if (score < 0 || score > 100) { printf("score error\n"); } else if (score >= 90) { printf("A\n"); } else if (score >= 80) {printf("B\n"); } else if (score >= 70) { printf("C\n"); } else if (score >= 60) { printf("D\n"); } else { printf("E\n"); /* 随心条件语句的嵌套层次越多,执行效率月底 */ } return 0; }
4.2.2 switch多路分支语句
switch(条件表达式) { /* 条件表达式的结果只能是整型数据,不能是浮点型数据 */ case 条件值1: /* case作为条件入口语句,当条件值和条件表达式结果值一致的时候,进入该部分开始顺序执行 */ 执行语句部分 break; /* break作为条件执行结束语句,可以省略,break和case不一一对应,可以是多个case对应一个break */ case 条件值2: 执行语句部分 break; default: /* 条件的其它情况,在case语句中找不到对应的条件结果,自动进入到default语句开始执行 */ 执行语句; break; }
4.3 循环控制语句
4.3.1 for循环控制语句
for(表达式1; 表达式2; 表达式3) { 循环体执行语句单元; } 执行过程: 1) 执行表达式1,一般用于条件参数的初始化设置,可以省略。 2) 执行表达式2(是作为条件表达式,如果条件成立进入到循环体中执行,如果条件不成立结束整个循环体的执行) 可以忽略,此时表示调节始终成立 3) 在表达式2条件成立的情况进入循环体中执行1次 4) 执行表达式3,做参数的调节;可以省略。 5) 在进入到表达式2执行
4.3.2 while循环控制语句
1. while...do循环执行语句 while(条件表达式) { 循环体执行语句部分; } 2. do...while语句 do { 循环体执行语句部分; } while(条件表达式);
4.4 特殊控制语句
4.4.1 goto跳转语句
按照goto 后面标签进行跳转执行,可以向前向后跳转;
4.4.2 break结束语句
- 在switch语句中的使用
表示条件分支执行语句的结束;
- 在循环控制语句中使用
表示整个循环执行的结束,进入到循环体后面的语句开始执行。
4.4.3 continue语句
只能在循环控制语句中使用;表示结束本次循环进入到下一次循环条件的判断,在本次循环体中continue后的所有语句不在执行。
4.4.4 return语句
表示在函数模块内使用,结束整个函数体的执行,同时还可以将处理结果进行返回。
【知识点2】数组
1 数组的定义
所谓的数组,指的是具有相同数据类型的多个元素的集合,在内存空间中连续存储。
2 数组的分类
2.1 按照数组元素的维度
可以分为一维数组、二维数组和多
2.2 按照数组元素的数据类型
int整型数组、char字符数组、float浮点型数组 ……
3 一维数组
3.1 一维数组的定义
存储类型 数据类型 数组名[常量表达式];
1) 数据类型:表示数组元素的数据类型,可以是基本数据类型和构造数据类型;
2) 存储类型:表示整个数组集合的存储类型,同时也是每一个数组元素的数据类型。
3) 数组名,作为整个集合变量空间的名称,满足标识符的命名规则;
4) 常量表达式:一定使用常量表达式表示数组元素的个数。
3.2 数组元素的访问
数组元素不能整体访问,只能逐一元素访问;
访问形式:数组名[下标]; 下标范围介于[0, 数组元素的个数)区间;
注意,在对数组元素逐一访问的时候,不要越界;否则会导致未知异常情况:
1) 程序正常运行且结果无影响;
2) 程序正常运行但是结果异常;
3) 程序异常执行。
3.3 一维数组元素的初始化
3.3.1 只做定义不做初始化
- 全局变量和static修饰的局部变量,元素的初始值为零值;
- auto的局部变量,元素的初始值为随机值;
3.3.2 定义同时设置初始值
- 全部元素初始化
int arr[5] = {1,2,3,4,5}; 逐一将初始化数据赋值给数组元素;需要注意初始数据元素的个数 == 常量表达式的值; int arr[] = {1,2,3,4,5};
- 部分元素初始化
int arr[5] = {1,2,3}; 不能省略常量表达式,并实现逐一元素初始化,未设置初始值的元素初始值为0
3.4 一维字符数组
所谓的一维字符数,数组元素的类型为char类型,满足一维数组的索引的特性;
注意:
在访问的时候,可以逐一单个元素访问
1) %d ==> 访问字符元素的ASCII编码值;
2) %c ==> 访问字符符号;
3) %s ==> 从起始元素开始逐一元素顺序访问,遇到'\0'结束;
在初始化元素时候:
1) 可以给元素逐一设置ASCII编码值;
2) 可以给元素逐一设置字符符号;
3)可以使用字符串常量整体赋值(其实质逐一元素赋值)。
char buf1[5] = {'h','e','l','l','o'};
char buf2[6] = {"hello"}; char buf3[] = "hello";
4 二维数组
4.1 二维数组的定义
存储类型 数据类型 数组名[行常量表达式][列常量表达式];
二维数组在内存中依然线性顺序存储。
4.2 二维数组元素的访问
不能整体访问,只能逐一元素访问;
数组名[行下标][列下标]; 行下标的范围介于:[0, 行数);列下标的访问:[0,列数)
行数 = sizeof(a)/sizeof(a[0]);
列数 = sizeof(a[0])/sizeof(a[0][0]);
4.3 二维数组的元素初始化
4.3.1 只做定义不做初始化
- 全局变量和static修饰的局部变量,元素的初始值为零值;
- auto修饰的局部变量,元素的初始值为随机值;
4.3.2 定义同时设置初始值
- 全部元素初始
-
int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12}; int a[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}}; /* 在全部初始化的时候可以省略行常量表达式,不可省略列常量表达式 */ int a[][4] = {1,2,3,4,5,6,7,8,9,10,11,12}; int a[][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
- 部分元素初始化
-
int a[3][4] = {1,2,3,4,5,6}; int a[3][4] = {{1,2,3},{5,6},{9,10,11,12}}; int a[3][4] = {{1,2,3,4},{5,6,7,8}}; /* 在全部初始化的时候可以省略行常量表达式,不可省略列常量表达式 */ int a[][4] = {1,2,3,4,5,6,7,8,9}; int a[][4] = {{1,2},{5,6,7},{9,10,11,12}};
-
4.4 二维字符数组
同样满足二维数组的所有属性;同时使用字符和字符串设置。
-
练习:
- 杨辉三角的输出:分别使用二维数组和一维数组实现。
- 实现常用的排序算法;