C语言中,容易中招的陷阱

陷阱目录

  • 一、运算符的优先级问题
    • 1.1 C语言中有哪些运算符
    • 1.2 个运算符的优先级
    • 1.3 易错总结
  • 二、条件判断语句易出中招陷阱
    • 2.1 switch......case语句省略break后的陷阱
    • 2.2 else带来的陷阱

一、运算符的优先级问题

1.1 C语言中有哪些运算符

C语言的运算符主要有六类:算术运算符、关系运算符、逻辑运算符、位运算符、赋值运算符和杂项运算符。

算术运算符主要是进行数学运算,主要如下表

算术运算符 描述
+ 加法运算符
- 减法运算符
* 乘法运算符
/ 除法运算符
% 取模运算符,或者叫取余运算符
++ 自加运算符
自减运算符

关系运算符,主要是指用来进行比较的运算符,详细如下表:

关系运算符 描述
== 确定符号两边的值是否相等,是则为真,否则为假
!= 确定等号两边的值是否不相等,是则为真,否则为假
> 确定符号左边的值是否大于右边的,是为真,否则为假
< 确定符号左边的值是否小于右边的,是为真,否则为假
>= 确定符号左边的值是否大于等于右边的,是为真,否则为假
<= 确定符号左边的值是否小于等于右边的,是为真,否则为假

逻辑运算符,主要是用来通过符号两边的操作数来确定条件的真假,如下表所示:

逻辑运算符 描述
&& 符号两边的操作数都为真,则表示的条件才为真,否则为假
|| 符两边的操作数有一个为真,则表示的条件就为真,否则为假
! 符号右边的为假,则表示的条件为真,否者为假

位运算符使用来对二进制数进行的操作,主要包括下表几个操作:

位运算符 描述
& 二进制数按位取与运算
| 按位取或运算
^ 按位取异或运算

赋值运算符是用来,将一个变量的值经过操作后赋值到另一个变量上去,详细如表所示:

赋值运算符 描述
= 将符号右边的值赋给左边的变量
+= 将符号右边的值加上符号左边的值赋给左边的变量
-= 意义类同上
*= 意义类同上
/= 意义类同上
%= 意义类同上
<<= 意义类同上
>>= 意义类同上
&= 意义类同上
|= 意义类同上
^= 意义类同上

其余的运算符。如下表所示:

杂项运算符 描述
(), [], ->, . 后缀
sizeof 取变量或数据结构的字节数
& 取址运算符
* 解地址运算符
?: 条件表达式

1.2 个运算符的优先级

以上几类的运算符优先级。从上到下一次递减,图下表所示:

运算符 结合性
() [] . -> 自左向右
! ~ ++ – - (type) * & sizeof 自右向左
* / % 自左向右
+ - 自左向右
<< >> 自左向右
< <= > >= 自左向右
== != 自左向右
& 自左向右
^ 自左向右
| 自左向右
&& 自左向右
|| 自左向右
?: 自右向左
所有的赋值运算符 自右向左
, 自左向右

1.3 易错总结

  • sizeof() 是一个运算符而不是一个函数
  • 位移运算和算术运算混合:
int hi =1; // hi r的高四位
int low = 0; // low r的低四位
// 假设r是一个8位的整数,hi和low也是
int r = hi << 4 + low; // 该等式是错的,因为加法运算符的优先级高于位移运算符,所以相当于:int r= hi << (4 + low);
// 正确的如下
int r = (hi << 4) + low;

逻辑运算符和按位运算符混用:

// 本来的意思是0和1进行按位与之后是否等于0,但是按下面的方式就成了1是否等于0,然后在按位与
if(0 & 1 == 0);
// 正确如下
if((0 & 1) == 0);

二、条件判断语句易出中招陷阱

2.1 switch…case语句省略break后的陷阱

在switch…case语句中若是不注意省略了每一个case后的break,则程序将后紧接着运行按着的下一个case中的语句,不管是否满足条件

int flag = 2;
switch(flag){
case 1:printf("red\n");
		break;
case 2:printf("green\n");
		// break; //若省略掉这个break则将会输出:green和blue
case 3:printf("blue\n")
		break;
		
}

2.2 else带来的陷阱

if…else…语句是C语言编程中常用的判断语句,常常会因为省略掉“{}”,而导致很难排查的错误

if(flag == 0)
	if(x ==0) printf("no data\n"); // 这里出错
else{
	int y = x / flag;
	return y;
}

上述判断中是为了避免除数flag为0而做出的判断,但是由于第一个if语句没有加大括号,是编译器误认else语句是第二个if的else,整理一下就清晰了:

if(flag == 0)
	if(x ==0) printf("no data\n"); // 这里出错
	else{
		int y = x / flag;
		return y;
	}

因此为了避免这种错误,就不要为了怕麻烦,而省略掉大括号了,上述代码正确如下:

if(flag == 0){
	if(x ==0) printf("no data\n"); 
}// 加上大括号
else{
	int y = x / flag;
	return y;
}

你可能感兴趣的:(C/C++,编程基础学习)