变量基础
在C语言中,变量是程序中最基本的数据存储单元,用于存储各种类型的数据。
变量的声明与初始化
变量需要先声明后使用,声明格式:数据类型 变量名;
// 变量声明示例
int age; // 声明整型变量
float salary; // 声明浮点型变量
char grade; // 声明字符型变量
// 变量初始化
int count = 0; // 声明并初始化
double pi = 3.14; // 声明并初始化
变量的命名规则
- 只能包含字母、数字和下划线
- 必须以字母或下划线开头
- 不能使用C语言关键字
- 区分大小写
练习题
1. 下列哪个是合法的变量名?
答案:C. _var
解析:变量名不能以数字开头(A错误),不能包含连字符(B错误),不能使用关键字(D错误)。以下划线开头的变量名是合法的。
2. 关于变量声明,以下说法正确的是?
答案:C. 变量声明指定了变量的数据类型
解析:在C语言中,变量必须先声明后使用(A错误),声明时可以不需要初始值(B错误),变量名不能包含空格(D错误)。
3. 下列代码的输出结果是?
int a = 5;
int b = a++;
printf("%d", a);
答案:B. 6
解析:a++是后置递增运算符,先使用a的值赋值给b,然后a自增1,所以a的值变为6。
4. 在C语言中,变量的作用域可以是?
答案:D. 以上都是
解析:C语言中变量可以具有局部作用域(在函数内部)、全局作用域(在所有函数外部)或文件作用域(使用static关键字)。
5. 下列哪个数据类型占用内存空间最小?
答案:C. char
解析:char类型通常占用1字节,int和float通常占用4字节,double通常占用8字节。
位运算
位运算是指对操作数以二进制位(bit)为单位进行的数据处理。每一个二进制位只能存放一位二进制数"0"或"1"。
位运算符
| 运算符 | 含义 | 优先级 | 格式 |
|---|---|---|---|
| ~ | 取反 | 2 | ~a |
| << | 左移n位 | 5 | a<<n |
| >> | 右移n位 | 5 | b>>n |
| & | 按位与 | 8 | a&b |
| ^ | 按位异或 | 9 | a^b |
| | | 按位或 | 10 | a|b |
取反运算是单目运算,其余为双目运算。运算的操作数只能是整数或字符型数据,不能为实型数据。
逻辑位运算符的求值规律
| a | b | ~a | a&b | a^b | a|b |
|---|---|---|---|---|---|
| 1 | 1 | 0 | 1 | 0 | 1 |
| 1 | 0 | 0 | 1 | 1 | |
| 0 | 1 | 1 | 0 | 1 | 1 |
| 0 | 0 | 0 | 0 | 0 |
从表中可以得出以下结论:
① ~运算,0变1,1变0。
② &运算,当两个对应位均为1时,结果为1,否则为0。
③ ^运算,当两个对应位不同时,结果为1,否则为0。
④ |运算,当两个对应位均为0时,结果为0,否则为1。
代码示例
unsigned char a = 2, b = 4, c = 5, d = 16, e = 7, y;
y = a & b; // y = (00000010) & (00000100) = 0
y = a | b; // y = (00000010) | (00000100) = (00000110) = 6
y = a ^ c; // y = (00000010) ^ (00000101) = (00000111) = 7
y = a << 2; // y = (00000010) << 2 = (00001000) = 8
y = d >> 2; // y = (00010000) >> 2 = (00000100) = 4
y = ~e; // y = ~(00000111) = (11111000) = 248
y = d & e << 2; // y = d & (e << 2) = (00010000) & (00011100) = (00010000) = 16
练习题
1. 表达式 13 & 17 的值是?
答案:A. 1
解析:13的二进制是1101,17的二进制是10001,按位与操作后得到00001,即1。
2. 表达式 5 | 12 的值是?
答案:C. 13
解析:5的二进制是0101,12的二进制是1100,按位或操作后得到1101,即13。
3. 表达式 9 << 2 的值是?
答案:C. 36
解析:9的二进制是1001,左移2位后得到100100,即36。
4. 表达式 ~0 的值是?
答案:C. -1
解析:0的二进制表示全为0,按位取反后全为1,在补码表示中全1表示-1。
5. 表达式 15 ^ 9 的值是?
答案:A. 6
解析:15的二进制是1111,9的二进制是1001,按位异或操作后得到0110,即6。
强制类型转换
强制类型转换是将表达式的结果类型强制转换成指定类型的操作。
强制类型转换运算符
运算符为(类型),优先级为2。
格式: (类型)表达式
功能: 将表达式的结果类型强制转换成指定类型。
代码示例
(int) 3.14 // 结果为整型3
(float) 1 // 结果为浮点型1.0
1 / 2 // 结果为0
(float) 1 / 2 // 结果为0.5
注意:类型名应加圆括号。例如,float(2+5)是错误的,正确的写法是(float)(2+5)。
练习题
1. 表达式 (int)3.14 + 5.2 的值是?
答案:A. 8.2
解析:(int)3.14将3.14转换为整型3,然后3+5.2=8.2。
2. 表达式 (float)(5/2) 的值是?
答案:B. 2.0
解析:5/2是整数除法,结果为2,然后强制转换为float类型,结果为2.0。
3. 表达式 (int)(7.5 + 3.2) 的值是?
答案:A. 10
解析:7.5+3.2=10.7,然后强制转换为int类型,结果为10。
4. 下列哪个表达式的结果是2.5?
答案:B. (float)5/2
解析:(float)5/2将5转换为float类型,然后除以2,结果为2.5。其他选项:A结果为2.0,C结果为2,D结果为2.0。
5. 关于强制类型转换,以下说法正确的是?
答案:B. 只影响当前表达式的计算
解析:强制类型转换只是临时改变表达式的类型,不会改变原变量的类型。它可以用于各种类型,但必须使用圆括号。
知识点总结与易错点
知识点总结
- 变量:需要先声明后使用,具有特定的数据类型和作用域
- 位运算:对二进制位进行操作,包括取反(~)、左移(<<)、右移(>>)、按位与(&)、按位异或(^)、按位或(|)
- 强制类型转换:使用(类型)运算符,临时改变表达式的类型
易错点
- 混淆位运算(&,|,^)和逻辑运算(&&,||,!)
- 忘记位运算只能用于整数和字符类型,不能用于浮点数
- 混淆左移/右移运算符的方向
- 忘记强制类型转换的优先级,导致意外的计算结果
- 混淆整数除法和浮点数除法的结果
- 忘记强制类型转换不会改变原变量的类型
综合练习题
1. 表达式 3 & 5 | 2 的值是?
答案:C. 3
解析:先计算3&5=1,然后1|2=3。
2. 表达式 (float)(10/3) 的值是?
答案:B. 3.0
解析:10/3是整数除法,结果为3,然后强制转换为float类型,结果为3.0。
3. 表达式 8 >> 1 + 1 的值是?
答案:A. 2
解析:加法优先级高于移位运算符,所以先计算1+1=2,然后8>>2=2。
4. 下列代码的输出结果是?
int a = 5, b = 2;
float c = (float)a / b;
printf("%.1f", c);
答案:C. 2.5
解析:将a强制转换为float类型,然后除以2,结果为2.5。
5. 表达式 ~1 & 3 的值是?
答案:C. 2
解析:~1的二进制是11111110(假设8位),3的二进制是00000011,按位与操作后得到00000010,即2。