C语言中,容易中招的陷阱
发布日期:2021-05-07 22:09:34 浏览次数:20 分类:精选文章

本文共 2133 字,大约阅读时间需要 7 分钟。

陷阱目录

一、运算符的优先级问题

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和bluecase 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++中的静态联编和动态联编
下一篇:OpenCV的stitching.hpp 和X11的Xlib.h的‘Status’ 冲突解决方法

发表评论

最新留言

做的很好,不错不错
[***.243.131.199]2025年04月18日 08时52分02秒