论文部分内容阅读
摘要:C语言中的++运算符是一种特殊的运算符,其特殊性在于一个运算符包含两个操作,不同的编译器对这两个操作在复合表达式中的处理机制不同,而同一个编译器对其在程序中的不同位置也有不同的处理。教材中仅仅对++运算符作了最简单的介绍,并没有对++运算的左连接和右连接同时参与运算时的处理规则作介绍,本文对++运算在不同情况下的求解进行了深入研究,得出对++运算符的运算要根据一定的程序环境和编译器环境而定。
关键词:C语言;表达式;++运算符
中图分类号:TP301 文献标识码:A文章编号:1009-3044(2007)06-11675-02
1 引言
C语言中的++运算符是一种特殊的运算符,++运算主要用来代替循环结构程序设计中步长为1的循环变量的增值运算,即对于i=i+1,在C语言中可以用i++或者++i简化表示,因此,大多数教材中将++运算符也称作自增或者自加运算符。但是,i++或者++i运算并不完全等价于i=i+1,它是C语言中用一个运算符号表示两步不同操作的符号。C语言程序设计的教材中都是简单介绍它的基本运算,并没有深入讲解++运算在复合表达式中的求解。因此,在具体的表达式求解中经常出错,究其原因不外乎这两种情况:一是与表达式在程序中的位置有关(将其称之为软件相关性),二是不同的编译器对++运算在复合表达式中的处理机制有关(将其称之为硬件相关性)。下面我们通过对具有代表性的表达式的计算来说明++运算的求解。
在介绍++运算的时候,经常以赋值表达式j=(i++)+(i++)+(i++)或者j=(++i)+(++i)+(++i)作为例子来讲解其运算规则,在《C程序设计》(谭浩强主编)一书中也对其求解过程作了详细介绍,但是,如果将上面赋值表达式的++表达式作一变换,如j=(i++)+(++i)+(i++)或者j=(++i)+(i++)+(++i),书中并没有给出求解过程。
甚至在输出函数中的这两种形式:
在《C程序设计》(王柏盛主编)一书中作者给出“在教学和科研中发现Tubro C在表达式中存在严重的不一致性,这实在是一个遗憾”。那么对于++表达式的复合运算究竟该如何求解呢?
随着计算机编程语言功能的不断完善和强大,C语言编译器出现了多种不同版本,由于面向对象以及可视化编程环境的影响,一些《C程序设计》也开始使用Microsoft VC++ 6.0或者Dev C++编译器作为C源程序的编程环境。那么在不同的编程环境中上面表达式的求解结果是否一样?经过在程序中编译运行,笔者发现在不同的编译器中求解的结果有所差异,现将同一个表达式在Tubro C 3.0环境下在程序中不同位置的运算结果作一比较。如下表所示。
说明:
(1)作为表达式是指++表达式在程序中作为单独的一条赋值表达式,程序如下:
(2)作为printf参数是指++表达式在程序中作为输出函数的输出列表参数,程序如下:
从表格中可以看出,同一个++表达式在Tubro C 3.0的编程环境中作为不同的成分得到的结果是不尽相同的,那么如何解释这种现象呢?下面我们对不同的结果进行分析。
2 单个++运算在表达式中的求解
我们知道,++运算在C语言中规定为优先级是第2级的单目运算符,而且++运算符要求只能用于单变量,不能用于常量或表达式,++运算符与单变量的结合方式有两种:i++和++i,分别成为左连接和右连接。只有一个++运算符的操作分为两步,即:
左连接的第二步与右连接的第一步被称为自增或自加运算。在表达式中不论那种形式,只有单个i能直接参与整个表达式的运算,而i=i+1仅仅对i的值产生影响,并不直接参与整个表达式的运算。因此对于赋值表达式,j=i++其运算分为 ,即先取出变量i的原值赋值给变量j,然后使i的值变为加1后的值,即实现i的自增;但是对于赋值表达式j=i++,其运算分为,即先使i的值变为加1后的值,即实现i的自增,然后才取出i变化后的值赋值给变量j。
单个++表达式的求解比较简单,i的自增对整个赋值表达式的影响也较明显,但是如果一个表达式中既包含左连接也包含右连接,那么整个表达式的求解就会变得复杂。
3 Tubro C 3.0环境下对++运算表达式的求解
经过对不同的++表达式在程序的不同位置得到的结果进行分析,我发现造成结果不同的原因在于编译器对++表达式作为不同成分的两步运算的处理顺序不同造成的。
3.1 第一步优先法
对于包含有多个++表达式,在特定的编译器(如Tubro C 3.0),对任何一个++表达式的两步运算严格按照第一步比第二步优先处理,我将其成为“第一步优先法”或者“全局处理法”。即编译器对第二个++表达式的第一步处理比第一个++表达式的第二步处理优先。
现在我们对上表中的++表达式在不同环境和程序中的不同成分利用表格法进行求解分析。假设我们将++运算的两步用一个2行1列的表格表示,并按照顺序将第一步放在第一行,第二步放在第二行。
如果i的原值为3,那么j=(i++)+(i++)+(i++)的值为多少。
分析:首先将赋值表达式j=(i++)+(i++)+(i++)表示成如下形式:
对于这样的一个赋值表达式,j的值实际上是三个i的值相加而得到。但是对于用表格法表示的式子中第二个和第三个i的值该如何取值呢?根据在Tubro C3.0环境下++运算作为表达式的运行结果来看,i=3时,j=9。那么最好的解释就是编译器首先扫描赋值表达式,在对整个表达式求解一开始时先执行每个++运算的第一步,即先把每个i的原值(3)取出来,作为整个表达式中i的值,相加得9。然后再实现i的自增,i最后得6。因此,对程序1中的++表达式的处理实际上是按照下图中123456的顺序执行的。
同样,对于j=(++i)+(++i)+(++i),我们也可以把它表示成如下形式:
整个赋值表达式还是求三个变量i相加的和。但是从表中来看j=18,若i的原值为3,i每次只能加1,那么要想得到18,从3开始怎么也不可能得到,对于这个整个赋值表达式只能是三个6相加得到,即编译器在处理整个表达式时,先对i执行三次自增得6,然后进行j=6+6+6的运算,故得18。
上面这两个表达式都是由三个相同格式的++表达式组成的,其结果比较容易理解,我们也可以理解成“第一步优先法”,即j=(i++)+(i++)+(i++)中第二个i++的第一步比第一个i++的第二步先运算。问题是如果整个表达式是由多个不同的表达式组成,那整个表达式的结果该如何求解?如j=(i++)+(++i)+(i++)或者j=(++i)+(i++)+(++i)。我们先来看在不同的环境得到的结果分别为j=12和j=15。对于用表格表示的表达式形式:
同样在Tubro C 3.0环境下i=3,编译器先扫描整个表达式,按照“第一步优先法”,可以看出第二个++表达式的第一步并不是取i的原值,而是要对i进行一次自增运算,因此,按照+(加法)运算符的结合性为自左至右的结合方向,第一个++表达式的i取值为3,第三个++表达式的i就应该取4,这是因为第二个++表达式的i已经进行了一次自增运算,最后对第二行扫描时,第一个++表达式的i再进行一次自增运算,使得i的值变为5,这样第二个++表达式的i取值就为5,加上第三个++表达式的i最后进行一次自增运算,i的值最终为6。那么整个表达式的结果j=3+4+5=12。同理,对j=(++i)+(i++)+(++i)进行“第一步优先法”分析,j=4+5+6=15。
经过对其他形式的赋值表达式进行“第一步优先法”分析,都能得到对应的结果。这说明在《C程序设计》(谭浩强主编)一书中对++复合表达式是以Tubro C 2.0/3.0为编译器并按照“第一步优先法”求解的。
3.2 第二步优先法
对于包含有多个++表达式,在特定的编译器(如Tubro C 3.0),对扫描到的++表达式按照顺序依次进行两步运算处理,我将其成为“第二步优先法”或者“局部处理法”。即编译器对第一个++表达式的第二步处理比第二个++表达式的第一步处理优先。
下面我们来看j=(i++)+(++i)+(i++)的求解过程。
分析:当j=(i++)+(++i)+(i++)作为printf()函数的参数时,编译器扫描整个表达式,并对扫描到得每个++表达式按照“第二步优先法”依次进行处理,即:对程序2中的++表达式的处理实际上是按照上图中所示123456的顺序执行。
①先取出i的原值3;
②执行i=i+1,i的值变为4;
③执行i=i+1,i的值变为5;
④取出i的值5;
⑤取出i的值5;
⑥执行i=i+1,i的值变为6。
最后执行j=3+5+5=13。
经过对其他表达式作为printf()函数的参数进行分析,均能得到相应的结果。
因此,在Tubro C 2.0/3.0环境下,对++运算的处理是与编译器软件的编写有关,编译器对含有++运算符的表达式进行整体扫描,并将整个表达式的操作数和运算符按照一定的原理压入堆栈,最后求得整个表达式的结果。
4 Microsoft VC++ 6.0环境下对++运算表达式的求解
由于Tubro C 2.0/3.0是基于DOS系统下的编译环境,随着计算机的不断发展,DOS系统已经被整合到Windows操作系统中,DOS命令也不再被讲授,同时,面向对象和可视化编译系统的出现,使得现在的《C程序设计》也开始使用高版本的编译器(如Microsoft VC++ 6.0或者Dev C++)。那么对上表中的++表达式是否在Microsoft VC++ 6.0或者Dev C++也能得到相同的结果呢?下面我将同一个表达式在Microsoft VC++ 6.0环境下在程序中不同位置的运算结果作一比较。如下表所示。
从表中可以看出,在Microsoft VC++ 6.0环境下不管作为表达式还是作为printf()参数,得到的结果是相同的,这说明在Microsoft VC++ 6.0环境下对++运算的处理是统一的,但是与Tubro C 2.0/3.0环境下的结果相比却出现一些差异。
造成上述结果出现差异的原因我认为Microsoft VC++ 6.0编译器并没有对表达式进行求值处理,而是将其交给操作系统的硬件加法器。下面我们来看一个++表达式在Microsoft VC++ 6.0中是如何处理的。
若i=3,则j=(++i)+(i++)+(++i)的结果是多少?
用表格法将该赋值表达式表示成下面的形式。
从表中可以看出j=13,实际上j等于三个i相加的结果,而已知i的初值为3,怎么才能得到13呢?经过研究发现j只能是对i分别取4,4和5相加得到的,下面对其求解决过程进行说明。
“i+1优先法”:在硬件加法器所要求存取的操作数(如按照加法运算符要求两个)中,若对存取的i之前有自增运算则先对所有的自增运算进行处理,然后再存取所有i的值;若对存取的i之前没有任何一步自增运算,则直接存取所有i的值,并将对应++运算的自增操作放在整个表达式求解结束后再进行。
编译器将整个表达式的求解交给硬件加法器,硬件加法器根据+(加法)运算规则首先取硬件规定的操作数(如两个),因为最终参与整个表达式运算的变量是i,所以,硬件加法器扫描前两个++运算,并结合“i+1优先法”,对整个表达式进行运算。
根据硬件加法器原理将运算的结果并入一个存储器中,继续取下一个操作数,按照“i+1优先法”依次取下去,直到运算结束。所以上面的赋值表达式就可以理解为:首先扫描要求的操作数,按照“i+1优先法”,发现在存取第一个++运算的i值前有自增运算,所以先进行i自增运算得4,然后取出i的值4,这时对于第二个++运算,自增运算是在第二步,并不影响i的取值,因此i直接取值4,并将自增运算放在最后求解;根据硬件加法器,求解完前两个变量的和以后,继续取操作数,对于第三个++运算,第一步为自增运算,所以先进行i自增运算得5,然后取出i的值5参与第二次求和运算,得j的值为4+4+5=13。因此,对上面赋值表达式的求解可以认为按照上图中所示123564的顺序执行的。再比如,对j=(i++)+(++i)+(i++)的求解按照下图中的314526的顺序。
经过对其他赋值表达式进行上述分析,均得到相应的结果。
5 结束语
因此,在Microsoft VC++ 6.0环境下,对++运算的处理是与操作系统的硬件加法器有关,并结合“i+1优先法”,如果存取的操作数中第一步既有取i值的操作,又有改变i值的自增操作(如j=(i++)+(++i)+(i++) 或者j=(++i)+(i++)+(++i),或者存取的操作数中都要求先对i进行自增操作(如j=(++i)+(++i)+(++i),则优先进行第一步改变i值的自增操作,然后再进行取i值的操作,并且取i值时不分顺序,但将第二步中改变i值的自增操作放在整个表达式的值求解完以后再进行;如果对存取的操作数中都要求先对i进行取值操作(如j=(i++)+(i++)+(i++)),则直接取i的值参与对整个表达式求值的运算,并把改变i值的自增操作放在整个表达式的值求解完以后再进行。
参考文献:
[1] 谭浩强. C程序设计[M]. 清华大学出版社,1998.3.
[2] 蒋春蕾,等. C语言中的函数应用时易出现的错误[J]. 西昌学院学报(自然科学版),2005.9.
[3] 王柏盛. C程序设计[M]. 高等教育出版社, 2005.1.
本文中所涉及到的图表、注解、公式等内容请以PDF格式阅读原文。
关键词:C语言;表达式;++运算符
中图分类号:TP301 文献标识码:A文章编号:1009-3044(2007)06-11675-02
1 引言
C语言中的++运算符是一种特殊的运算符,++运算主要用来代替循环结构程序设计中步长为1的循环变量的增值运算,即对于i=i+1,在C语言中可以用i++或者++i简化表示,因此,大多数教材中将++运算符也称作自增或者自加运算符。但是,i++或者++i运算并不完全等价于i=i+1,它是C语言中用一个运算符号表示两步不同操作的符号。C语言程序设计的教材中都是简单介绍它的基本运算,并没有深入讲解++运算在复合表达式中的求解。因此,在具体的表达式求解中经常出错,究其原因不外乎这两种情况:一是与表达式在程序中的位置有关(将其称之为软件相关性),二是不同的编译器对++运算在复合表达式中的处理机制有关(将其称之为硬件相关性)。下面我们通过对具有代表性的表达式的计算来说明++运算的求解。
在介绍++运算的时候,经常以赋值表达式j=(i++)+(i++)+(i++)或者j=(++i)+(++i)+(++i)作为例子来讲解其运算规则,在《C程序设计》(谭浩强主编)一书中也对其求解过程作了详细介绍,但是,如果将上面赋值表达式的++表达式作一变换,如j=(i++)+(++i)+(i++)或者j=(++i)+(i++)+(++i),书中并没有给出求解过程。
甚至在输出函数中的这两种形式:
在《C程序设计》(王柏盛主编)一书中作者给出“在教学和科研中发现Tubro C在表达式中存在严重的不一致性,这实在是一个遗憾”。那么对于++表达式的复合运算究竟该如何求解呢?
随着计算机编程语言功能的不断完善和强大,C语言编译器出现了多种不同版本,由于面向对象以及可视化编程环境的影响,一些《C程序设计》也开始使用Microsoft VC++ 6.0或者Dev C++编译器作为C源程序的编程环境。那么在不同的编程环境中上面表达式的求解结果是否一样?经过在程序中编译运行,笔者发现在不同的编译器中求解的结果有所差异,现将同一个表达式在Tubro C 3.0环境下在程序中不同位置的运算结果作一比较。如下表所示。
说明:
(1)作为表达式是指++表达式在程序中作为单独的一条赋值表达式,程序如下:
(2)作为printf参数是指++表达式在程序中作为输出函数的输出列表参数,程序如下:
从表格中可以看出,同一个++表达式在Tubro C 3.0的编程环境中作为不同的成分得到的结果是不尽相同的,那么如何解释这种现象呢?下面我们对不同的结果进行分析。
2 单个++运算在表达式中的求解
我们知道,++运算在C语言中规定为优先级是第2级的单目运算符,而且++运算符要求只能用于单变量,不能用于常量或表达式,++运算符与单变量的结合方式有两种:i++和++i,分别成为左连接和右连接。只有一个++运算符的操作分为两步,即:
左连接的第二步与右连接的第一步被称为自增或自加运算。在表达式中不论那种形式,只有单个i能直接参与整个表达式的运算,而i=i+1仅仅对i的值产生影响,并不直接参与整个表达式的运算。因此对于赋值表达式,j=i++其运算分为 ,即先取出变量i的原值赋值给变量j,然后使i的值变为加1后的值,即实现i的自增;但是对于赋值表达式j=i++,其运算分为,即先使i的值变为加1后的值,即实现i的自增,然后才取出i变化后的值赋值给变量j。
单个++表达式的求解比较简单,i的自增对整个赋值表达式的影响也较明显,但是如果一个表达式中既包含左连接也包含右连接,那么整个表达式的求解就会变得复杂。
3 Tubro C 3.0环境下对++运算表达式的求解
经过对不同的++表达式在程序的不同位置得到的结果进行分析,我发现造成结果不同的原因在于编译器对++表达式作为不同成分的两步运算的处理顺序不同造成的。
3.1 第一步优先法
对于包含有多个++表达式,在特定的编译器(如Tubro C 3.0),对任何一个++表达式的两步运算严格按照第一步比第二步优先处理,我将其成为“第一步优先法”或者“全局处理法”。即编译器对第二个++表达式的第一步处理比第一个++表达式的第二步处理优先。
现在我们对上表中的++表达式在不同环境和程序中的不同成分利用表格法进行求解分析。假设我们将++运算的两步用一个2行1列的表格表示,并按照顺序将第一步放在第一行,第二步放在第二行。
如果i的原值为3,那么j=(i++)+(i++)+(i++)的值为多少。
分析:首先将赋值表达式j=(i++)+(i++)+(i++)表示成如下形式:
对于这样的一个赋值表达式,j的值实际上是三个i的值相加而得到。但是对于用表格法表示的式子中第二个和第三个i的值该如何取值呢?根据在Tubro C3.0环境下++运算作为表达式的运行结果来看,i=3时,j=9。那么最好的解释就是编译器首先扫描赋值表达式,在对整个表达式求解一开始时先执行每个++运算的第一步,即先把每个i的原值(3)取出来,作为整个表达式中i的值,相加得9。然后再实现i的自增,i最后得6。因此,对程序1中的++表达式的处理实际上是按照下图中123456的顺序执行的。
同样,对于j=(++i)+(++i)+(++i),我们也可以把它表示成如下形式:
整个赋值表达式还是求三个变量i相加的和。但是从表中来看j=18,若i的原值为3,i每次只能加1,那么要想得到18,从3开始怎么也不可能得到,对于这个整个赋值表达式只能是三个6相加得到,即编译器在处理整个表达式时,先对i执行三次自增得6,然后进行j=6+6+6的运算,故得18。
上面这两个表达式都是由三个相同格式的++表达式组成的,其结果比较容易理解,我们也可以理解成“第一步优先法”,即j=(i++)+(i++)+(i++)中第二个i++的第一步比第一个i++的第二步先运算。问题是如果整个表达式是由多个不同的表达式组成,那整个表达式的结果该如何求解?如j=(i++)+(++i)+(i++)或者j=(++i)+(i++)+(++i)。我们先来看在不同的环境得到的结果分别为j=12和j=15。对于用表格表示的表达式形式:
同样在Tubro C 3.0环境下i=3,编译器先扫描整个表达式,按照“第一步优先法”,可以看出第二个++表达式的第一步并不是取i的原值,而是要对i进行一次自增运算,因此,按照+(加法)运算符的结合性为自左至右的结合方向,第一个++表达式的i取值为3,第三个++表达式的i就应该取4,这是因为第二个++表达式的i已经进行了一次自增运算,最后对第二行扫描时,第一个++表达式的i再进行一次自增运算,使得i的值变为5,这样第二个++表达式的i取值就为5,加上第三个++表达式的i最后进行一次自增运算,i的值最终为6。那么整个表达式的结果j=3+4+5=12。同理,对j=(++i)+(i++)+(++i)进行“第一步优先法”分析,j=4+5+6=15。
经过对其他形式的赋值表达式进行“第一步优先法”分析,都能得到对应的结果。这说明在《C程序设计》(谭浩强主编)一书中对++复合表达式是以Tubro C 2.0/3.0为编译器并按照“第一步优先法”求解的。
3.2 第二步优先法
对于包含有多个++表达式,在特定的编译器(如Tubro C 3.0),对扫描到的++表达式按照顺序依次进行两步运算处理,我将其成为“第二步优先法”或者“局部处理法”。即编译器对第一个++表达式的第二步处理比第二个++表达式的第一步处理优先。
下面我们来看j=(i++)+(++i)+(i++)的求解过程。
分析:当j=(i++)+(++i)+(i++)作为printf()函数的参数时,编译器扫描整个表达式,并对扫描到得每个++表达式按照“第二步优先法”依次进行处理,即:对程序2中的++表达式的处理实际上是按照上图中所示123456的顺序执行。
①先取出i的原值3;
②执行i=i+1,i的值变为4;
③执行i=i+1,i的值变为5;
④取出i的值5;
⑤取出i的值5;
⑥执行i=i+1,i的值变为6。
最后执行j=3+5+5=13。
经过对其他表达式作为printf()函数的参数进行分析,均能得到相应的结果。
因此,在Tubro C 2.0/3.0环境下,对++运算的处理是与编译器软件的编写有关,编译器对含有++运算符的表达式进行整体扫描,并将整个表达式的操作数和运算符按照一定的原理压入堆栈,最后求得整个表达式的结果。
4 Microsoft VC++ 6.0环境下对++运算表达式的求解
由于Tubro C 2.0/3.0是基于DOS系统下的编译环境,随着计算机的不断发展,DOS系统已经被整合到Windows操作系统中,DOS命令也不再被讲授,同时,面向对象和可视化编译系统的出现,使得现在的《C程序设计》也开始使用高版本的编译器(如Microsoft VC++ 6.0或者Dev C++)。那么对上表中的++表达式是否在Microsoft VC++ 6.0或者Dev C++也能得到相同的结果呢?下面我将同一个表达式在Microsoft VC++ 6.0环境下在程序中不同位置的运算结果作一比较。如下表所示。
从表中可以看出,在Microsoft VC++ 6.0环境下不管作为表达式还是作为printf()参数,得到的结果是相同的,这说明在Microsoft VC++ 6.0环境下对++运算的处理是统一的,但是与Tubro C 2.0/3.0环境下的结果相比却出现一些差异。
造成上述结果出现差异的原因我认为Microsoft VC++ 6.0编译器并没有对表达式进行求值处理,而是将其交给操作系统的硬件加法器。下面我们来看一个++表达式在Microsoft VC++ 6.0中是如何处理的。
若i=3,则j=(++i)+(i++)+(++i)的结果是多少?
用表格法将该赋值表达式表示成下面的形式。
从表中可以看出j=13,实际上j等于三个i相加的结果,而已知i的初值为3,怎么才能得到13呢?经过研究发现j只能是对i分别取4,4和5相加得到的,下面对其求解决过程进行说明。
“i+1优先法”:在硬件加法器所要求存取的操作数(如按照加法运算符要求两个)中,若对存取的i之前有自增运算则先对所有的自增运算进行处理,然后再存取所有i的值;若对存取的i之前没有任何一步自增运算,则直接存取所有i的值,并将对应++运算的自增操作放在整个表达式求解结束后再进行。
编译器将整个表达式的求解交给硬件加法器,硬件加法器根据+(加法)运算规则首先取硬件规定的操作数(如两个),因为最终参与整个表达式运算的变量是i,所以,硬件加法器扫描前两个++运算,并结合“i+1优先法”,对整个表达式进行运算。
根据硬件加法器原理将运算的结果并入一个存储器中,继续取下一个操作数,按照“i+1优先法”依次取下去,直到运算结束。所以上面的赋值表达式就可以理解为:首先扫描要求的操作数,按照“i+1优先法”,发现在存取第一个++运算的i值前有自增运算,所以先进行i自增运算得4,然后取出i的值4,这时对于第二个++运算,自增运算是在第二步,并不影响i的取值,因此i直接取值4,并将自增运算放在最后求解;根据硬件加法器,求解完前两个变量的和以后,继续取操作数,对于第三个++运算,第一步为自增运算,所以先进行i自增运算得5,然后取出i的值5参与第二次求和运算,得j的值为4+4+5=13。因此,对上面赋值表达式的求解可以认为按照上图中所示123564的顺序执行的。再比如,对j=(i++)+(++i)+(i++)的求解按照下图中的314526的顺序。
经过对其他赋值表达式进行上述分析,均得到相应的结果。
5 结束语
因此,在Microsoft VC++ 6.0环境下,对++运算的处理是与操作系统的硬件加法器有关,并结合“i+1优先法”,如果存取的操作数中第一步既有取i值的操作,又有改变i值的自增操作(如j=(i++)+(++i)+(i++) 或者j=(++i)+(i++)+(++i),或者存取的操作数中都要求先对i进行自增操作(如j=(++i)+(++i)+(++i),则优先进行第一步改变i值的自增操作,然后再进行取i值的操作,并且取i值时不分顺序,但将第二步中改变i值的自增操作放在整个表达式的值求解完以后再进行;如果对存取的操作数中都要求先对i进行取值操作(如j=(i++)+(i++)+(i++)),则直接取i的值参与对整个表达式求值的运算,并把改变i值的自增操作放在整个表达式的值求解完以后再进行。
参考文献:
[1] 谭浩强. C程序设计[M]. 清华大学出版社,1998.3.
[2] 蒋春蕾,等. C语言中的函数应用时易出现的错误[J]. 西昌学院学报(自然科学版),2005.9.
[3] 王柏盛. C程序设计[M]. 高等教育出版社, 2005.1.
本文中所涉及到的图表、注解、公式等内容请以PDF格式阅读原文。