表达式和基本语句

2016-12-14 09:56:52来源:http://blog.csdn.net/wzhwho/article/details/4560428作者:wzhwho人点击

第七城市

表达式和基本语句


1.表达式


1.1. 算术运算符


算术运算符包括一元运算符和二元运算符。


运算符的优先级和结合性



二元运算符(即*、/、%、+和-)都是左结合的,所以


i-j-k 等价于 (i-j)-k



一元运算符(+和-)都是右结合的,所以


-+i 等价于 -(+i)



1.2. 赋值运算符


1.2.1. 简单赋值


赋值运算符(=)是右结合的,所以


i=j=k=0;


等价于


i=(j=(k=0));



1.2.2. 左值


赋值运算符要求它左边的操作数必须是左值(lvalue)。左值表示存储在计算机内存中的对象,而不是常量和计算结果。变量是左值,而诸如10或2*1这样的表达式则不是左值。


下列赋值式子都是不合法的:


12 = i; /** WRORG**/


i + j = 0; /** WRORG**/


-i = j; /** WRORG**/


编译器将会检查出这个自然错误,并且显示出诸如”Lvalue required”这样的错误信息。



1.2.3. 复合赋值


复合赋值运算符:=、*=、/=、%=、+=、-=


例如:v+=e 表示v加上e,然后结果存在v中。



复合赋值运算符是右结合的,所以


i += j += k;


等价于


i += (j += k);



注意:表达式i += j与表达式 i = +j是不一样的。



1.3. 自增运算符和自减运算符


++(自增)和—(自减)


++i意味着“立即增一”,而i++则意味着“现在先用i的原始值,稍后再自增-”。



注意:后缀++和后缀—比一元的正号、负号优先级高,而且都是左结合的。前缀++和前缀—与一元的正号、负号优先级相同,而且都是右结合的。



1.4. 关系运算符


关系运算符:<、<=、>和>=


关系运算符在C语言的表达式时产生的结果是0或1。关系运算符可以用来比较整数和浮点数,以及允许的混合类型的操作数。关系运算符的优先级低于算术运算符,且是左结合的。比如


i


等价于


(i


也就是说,表达式先检测i是否小于j,然后用比较后的结果1或0来和k进行比较。



1.5. 判等运算符


判等运算符(==和!=)也是左结合的,而且也是产生了0或1作为结果。判等运算符的优先级低于关系运算符。例如


i 等价于表达式 (i



1.6. 逻辑运算符


!是一元运算符,而&&和||是二元运算符。逻辑运算符所产生的结果是0或1。


运算符&&和||都对操作数进行“短路”计算。也就是说首先计算出左侧操作数的值,然后是右侧操作数。如下:


(i != 0) && (j/i > 0)


为了得到此表达式的值,首先必须计算表达式(i != 0)的值。如果i不等于0,那么需要计算表达式(j/i > 0)的值,确定整个表达式的值为真还是为假。



运算符!的优先级和一元运算符正号、负号的优先级相同。运算符&&和||的优先级低于关系运算符和判等运算符。运算符!是右结合的,运算符&&和||是左结合的。



1.7. 条件表达式


表达式1?表达式2:表达式3


称为三元运算符,读作“如果表达式1成立,那么表达式2,否则表达式3“


条件运算符的优先级低于先前介绍过的所有运算符。



1.7. 逗号运算符


表达式1,表达式2


逗号表达式的计算通过两步来实现:第一步,计算表达式1并且扔掉计算出的值;第二步,计算表达式2的值,把这个值作为整个表达式的值。例如


++i,i+j时变量i先进行自增,然后在计算i+j,所以表达式的值为7。


逗号运算符的优先级低于所有其他运算符,是左结合的。


i=1,j=2,k=i+j;


等价于


((i=1,j=2),k=i+j;)




1.8. Q&A


问:如何对对数进行幂操作?


答:通过重复乘法运算的方法可以进行整数的小范围正整数次幂运算(i*i*i是i的立方运算)。如果想计算数的非正整数次幂运算,可以调用pow函数。



问:如果想吧%运算符用于浮点数,而程序又无法编译通过,怎么办?


答: %要求整数操作数,所以可以调用fmod函数。



问:为什么v+=e不等价于v=v+e?


答:计算v+=e只是导致求一次v的值,而v=v+e则会求两次v的值。任何副作用都能导致两次求v的值,在下面的例子中,i自增一次:


a[i++] += 2;


如果用=代替+=,则i会自增两次:


a[i++] = a[i++] +2;



问:++和—是否可以处理float型变量?


答:可以。自增和自减运算可以用于所有数值类型。



问:当用=代替==时编译器没有发出警告。是否有方法可以强制编译器注意这类问题?


答:可以。if(i == 0) …


习惯上改写成


if(0 == i) …


如果运算符==意外地写成了=;


if(0 = i) …


因为不可能给0赋值,所以编译器会产生错误信息。



2. 基本语句


2.1. if语句


if(表达式)


语句


else if(表达式)


语句


。。。


else if(表达式)


语句


else


语句


当嵌套if语句时,注意“悬空else“的问题。C语言遵循的规则是else子句应该属于离它最近的且还没有和其他else匹配的if语句。例如


if(y > 0)


if(x > 0)


result = x / y;


else


printf(“ERROR: y is equal to 0/n”);



为了使else子句属于外层的if语句,可以把内层的if语句用大括号括起来:


if(y > 0) {


if(x > 0) result = x / y; }


else


printf(“ERROR: y is equal to 0/n”);


2.2. switch语句


switch (表达式){


case 常量表达式:多条语句


break;


。。。


case 常量表达式:多条语句


break;


case 常量表达式:多条语句


break;


default:多条语句


break;


}


switch语句等价于级联if语句。



2.3. while语句


while (表达式)语句



2.4. do语句


do 语句 while (表达式);


do语句本质上就是while语句,只不过do语句是在每次执行循环体之后对控制表达式进行判断。



2.5. for语句


for (表达式1;表达式2;表达式3)语句



除了极少数情况以外,for循环总可以用等价的while循环替换:


表达式1;


while(表达式2){


语句


表达式3;


}


for循环体内含有continue语句时,for循环不再等价于while循环。



for语句中省略表达式


如果忽略第一个表达式,那么在执行循环语句前没有初始化操作;


如果忽略第三个表达式,那么循环体有责任要确认第二个表达式的值最终会变为假。


如果忽略第一个和第三个表达式,循环结果和while语句没有任何分别。


如果忽略第二个表达式,那么它默认为真值,因此for语句不会终止。



2.6. break语句


break语句可以用来退出while、do和for循环,不过当出现循环嵌套时,只能跳出一层嵌套。



2.7. continue语句


continue语句把程序控制正好转移到循环体结束之前的一点,会把程序控制留在循环内。



2.8. goto语句


goto 标示符;


goto语句可以跳出多层嵌套。建议少用、慎用goto语句。



2.9. Q&A


问:如果i是int型变量,而f是float型变量,那么条件表达式(i>0?i:f)是哪一种类型的值?


答:当int和float型的值混合在一个条件表达式中,表达式的类型float型。如果i>0,那么变量i转化为float型后的值就是表达式的值。



问:下面哪种写法,循环语句的效率更高?












for (row=0; row<100; row++)


{


for ( col=0; col<5; col++ )


{


sum = sum + a[row][col];


}


}



for (col=0; col<5; col++ )


{


for (row=0; row<100; row++)


{


sum = sum + a[row][col];


}


}




(a)长循环在最外层 (b)长循环在最内层


答:C++/C循环语句中,for语句使用频率最高,while语句其次,do语句很少用。在多重循环中,如果有可能,应当将最长的循环放在最内层,最短的循环放在最外层,以减少CPU跨切循环层的次数。例如(b)的效率比(a)的高。



问:下面哪种写法,循环语句的效率更高?












for (i=0; i


{


if (condition)


DoSomething();


else


DoOtherthing();


}



if (condition)


{


for (i=0; i


DoSomething();


}


else


{


for (i=0; i


DoOtherthing();


}




(c) 逻辑判断在循环体内 (d) 逻辑判断在循环体外


答:如果循环体内存在逻辑判断,并且循环次数很大,宜将逻辑判断移到循环体的外面。示例(c)的程序比示例(d)多执行了N-1次逻辑判断。并且由于前者老要进行逻辑判断,打断了循环“流水线”作业,使得编译器不能对循环进行优化处理,降低了效率。如果N非常大,最好采用(d)的写法,可以提高效率。如果N非常小,两者效率差别并不明显,采用示例(c)的写法比较好,因为程序更加简洁。



3. 运算符的优先级


C++/C语言的运算符有数十个,运算符的优先级与结合律下表所示。注意一元运算符 + - * 的优先级高于对应的二元运算符。






































































优先级



运算符



结合律

















( ) [ ] -> .



从左至右



! ~ ++ -- (类型) sizeof


+ - * &



从右至左




* / %



从左至右



+ -



从左至右



<< >>



从左至右



< <= > >=



从左至右



== !=



从左至右



&



从左至右



^



从左至右



|



从左至右



&&



从左至右



||



从右至左



?:



从右至左



= += -= *= /= %= &= ^=


|= <<= >>=



从左至右




运算符的优先级与结合律



第七城市

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台