自增自减从右至左_对C语言自增自减运算符的分析
[摘要]详细归纳使用自增自减运算符时的注意事项,并且结合运算符的优先级和自增自减运算本身的特点,对TurboC环境下的自增自减运算符在不同表达式中的运算规则进行详细分析与总结。
[关键词]C语言自增自减运算符运算规则
中图分类号:TP3文献标识码:A文章编号:1671-7597(2009)1120062-01
C语言具有丰富的运算符,对于各个运算符,不仅规定了操作量的类型、优先级别,还规定了结合方向,使得C语言的表达式具有简洁、高效、使用灵活的特点。在诸多运算符中,最难理解、最容易出错的便是自增、自减运算符。但是,在C语言的众多教材和参考书中,对C语言中的自增、自减运算符并没有作详细地论述,从而导致各种不同的解释,造成理解上的混乱。下面将对Turbo C环境中自增、自减运算符的功能及运算规则作一些详细分析。
一、自增、自减运算符的作用及表现形式
自增运算符为“++”,其作用是使变量的值增1;自减运算符为“--”,其作用是使变量的值减1。自增、自减运算符包括两种形式:前缀式(++i,--i)和后缀式(i++,i--)。前缀式中先加减i的值再使用变量i,后缀式中先使用i的值,再加减i的值,即前缀运算是“先变后用”,而后缀运算是“先用后变”。例如:
x=y=3;
z=++x;/*先使x增1,再将x的值赋给z,运算结果:z=4,x=4*/
N=y++;/*先将y的值赋给n,再使y增1,运算结果:n=3,y=4*/
二、自增、自减运算符的操作对象
自增、自减运算符的操作对象只能是变量,而不能是常量或表达式。因为自增自减运算符具有对运算量重新赋值的功能,常量、表达式并无存储单元可言,自然不能做自增、自减的运算。只要是标准类型的变量,不论整型、实型、字符型还是枚举型都可以作为这两个运算符的运算对象。
如以下四个表达式都是合法的:i+++j++、++i+(++j)、++a+b++、++array[--j];而++6、(i+j)++、"A"++、++i+++j、(&p)++这五个表达式却是不合法的。为什么i+++j++合法,而++i+++j却不合法?因为C的编译器对程序编译时,是从左到右尽可能多地将字符组合成一个运算符或标识符,因此i+++j++等效于(i++)+(j++),两个“++”作用的对象都是变量,这是合法的;而++i+++j等效于++(i++)+j,第1个“++”作用的对象是表达式“i++”,这是不允许的。
三、自增自减运算符的运算规则
很多C语言教材和参考书对自增运算符运算规则的叙述是“按照‘自右至左’的结合性进行自增自减运算”。但在实际的编程过程中我们发现,自增自减运算符在不同表达式中的运算规则却不尽相同,下面我们从以下几方面来分析。
(一)赋值表达式中的自增自减运算符
程序1:main()
程序运行结果如下:k=9,i=6;k=18,i=6;k=15,i=6。
分析:在赋值语句中,自增、自减运算符若作为前缀式,其运算优级高于其他算术运算,即先按照“从右至左”的结合性进行自增、自减运算,再进行其他运算;若作为后缀式,其运算优先级低于其他算术运算,即先进行其他算术运算,再按照“从右至左”的结合性进行自增、自减运算。
在表达式k=(i++)+(i++)+(i++)中,自增运算是后缀式,其运算规则低于算术运算。因此,变量i本身先参与算术运算,即k=3+3+3=9,再按照“从右至左”的结合性进行自增运算,即i++;i++;i++;最后,i的值为6。
在表达式k=(++i)+(++i)+(++i)中,自增运算是前缀式,其运算规则高于算术运算。因此先从右至左,依次计算++i;++i;++i;i的值变为6,再进行加法运算,即k=6+6+6=18。
在表达式k=(++i)+(i++)+(++i)中,是两个前缀式和一个后缀式混合运算的情况。根据我们的理解,i先进行两次加1运算,++i;++i;i的值变为5,然后,再参与加法运算,即k=5+5+5=15,最后,进行i++运算,i的值变为6。
(二)逻辑表达式中的自增自减运算符
在这里主要讨论逻辑与(&&)运算符和逻辑或(||)运算符。单纯从优先级来考虑,这两个逻辑运算符的优先级远低于自增运算符。但在实际运算中不能仅仅从运算符优先级的观点考虑问题;
程序2:main()
{int a,x=0,y=0,z=0;a=++x||++y&&++z;
printf(“a=%d,x=%d,y=%d,z=%d\n”,a,x,y,z);}
程序运行结果如下:a=1,x=1,y=0,z=0。
分析:如果按照自增运算符在赋值表达式中的运算规则,应该先计算++x、++y和++z,三个变量自增结束后再执行++x||++y&&++z,则输出结果应该是a=1,x=1,y=1,z=1。但TurboC 2.0中的实际结果却是a=1,x=1,y=0,z=0。也就是只有++x被执行,++y和++z都没有被执行。这是因为在C语言中针对||运算符和&&运算符这两个逻辑运算符有一个规定:在一个复杂的逻辑表达式中,若前面的子表达式的值能决定整个表达式的值,则后面的子表达式无需计算。在表达式a=++x||++y&&++z中,++x的值为1,它与后面的表达式进行||运算,它能决定整个表达式的值,帮后面的++y和++z都没有被执行,自增也就无从谈起了。
(三)函数实参表达示中的自增自减运算符
我们以自增表达式作printf函数的参数为例来说明函数实参表达示中的自增自减运算符的运算规则。
程序3:main()
程序输出结果为:k=12;k=15 ;k=14。
分析:程序3和程序1的不同之处仅在于把自增表达式放到了printf函数的参数位置,除此之外没有任何的变化。但结果却大相径庭,从9,18,
15变成了12,15,14。这说明一般语句中的自增自减运算规则与函数中的自增自减运算规则并不相同。作为函数时自增自减表达式满足“自左至右”的运算规则。
在表达式k=(i++)+(i++)+(i++)中,依据“自左至右”的运算规则,i的取值依次为3,4,5,故k=3+4+5=12。在表达式k=(i++)+(i++)+(i++)中,i的取值依次为4,5,6,故k=4+5+6=15。在表达式k=(++i)+(i++)+(++i)中,i的取值依次为4,4,6,故k=4+4+6=14。
四、小结
自增自减运算符是C程序设计语言中特有的常用的运算符,但对于初学者而言,比较难以理解这两个运算符的运算实质。在计算自增自减表达式时,除了了解表达式的类型,掌握运算规则外,还要清楚自增自减表达式所处的位置,对不同位置的自增自减表达要灵活处理。
注:本文为2009年度湖南省高等学校科学研究项目课题,课题名称:NAT-PT系统负载均衡的研究,课题编号:09C1226,主持人:肖辽亮
参考文献:
[1]谭浩强,C程序设计(第二版)[M].北京:清华大学出版社,2002.
[2]薛钢等,C语言实用教程[M].长春:吉林科学技术出版社,1997.
本文为全文原貌 未安装PDF浏览器用户请先下载安装 原版全文
