求值顺序区别于运算符优先级
c语言中只有四个运算符存在规定的运算顺序
&& || ?:和,
&&和||首先对左侧操作数求值,只有需要时才对右侧操作数求值
(a>b)&&(c>d)
先计算a>b的值,只有当a>b值为真时才计算c>d的值
?:运算符运算顺序:
a?b:c
先计算a的值,再根据a的值计算b或c的值
,逗号运算符先计算左侧操作数,然后该值丢弃,在对右侧操作数计算,而分隔函数参数的逗号并不是逗号运算符,如f(x,y)中x和y的运算顺序并未确定,而对于函数g((x,y)),则先计算x再计算y
c语言中其余运算符均未规定操作数求值顺序,需特别注意赋值运算符并不保证任何求值顺序,因此下面代码段存在问题
i=0;
while(i<n)
y[i]=x[i++];
i的自增操作和y[i]地址的计算两个操作的顺序并未确定
应该为
for(i=0;i<n;i++)
y[i]=x[i]
c语言中两类逻辑运算符
- & | ~
- && || !
第一类为按位运算符,处理方式是将操作数视作一个二进制序列,分别对其每个位进行操作。
如10&12=8
(1010)&(1100)=(1000)
只有当对应位置的那一位均为1时,这一位的结果才为1,否则为0。
10|12=14
(1010)|(1100)=(1110)
当对应位置的那一位均为0时,这一位的结果才为0,否则为1。
~10=-11
~(1010)=(11…110101)
第二类逻辑运算符则是将操作数视作“真”或“假”,通常0视作“假”,非0视作“真”,运算结果为“真”时返回1,结果为“假”时,返回0。
10&&12=1 因为10和12均不为0
10||12=1因为10和12中存在不为0的数
!10=0因为10不为0
对于运算符||和&&而言,当左侧操作数的值可以确定最终结果时,右侧操作数则不会进行计算
对于两个逻辑运算符,只有当操作数取值只有“0”和“1”时,两类运算符的结果总是相同
i=0;
while(i<tabsize&&tab[i]!=x)
x++;
遍历tab中所有元素,查找tab中是否存在元素x,上述程序段可以正常工作
i=0;
while(i<tabsize&tab[i]!=x)
x++;
上述程序段看似也可以“正常”工作,但只是侥幸而已,&运算符两个操作都是比较运算,返回值只有1和0,因此运算结果和&&完全相同。当i等于tabsize时,左侧运算结果为0,结果为0,对于&&运算符便不会再计算右侧操作数,而运算符&仍计算右侧运算tab[i]!=x,而tab[tabsize]这个元素不存在,由于只是读取元素,并未进行改变,所以没有什么危险。