请教一个C语言顺序点的问题。。。。
各位大神,小生才疏学浅请教一个c语言顺序点问题,代码如下:
#include “stdio.h” void f(int i,int j) { printf("%d ,%d n",i,j); } int main() { int k=1; f(k,k++); return 0; }
根据顺序点的知识,为什么k传入的值是2,而k++传入的值是1?小生编译器是gcc,是因为编译器不同,顺序就运算顺序就不同吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
引用来自“中山野鬼”的评论
从右向左,解析并编译。哈。理解这个就ok了。另外给楼主个提示,我学习和开发c语言的程序,也快20年了。类似你这样的问题,从来不纠结。。对于++i,i++,我一向保持,仅发生在通用实现方式,或独立一条语句中。哈,所谓通用实现方式,例如:
for(i = 0; i < 10 ;i++)
*p1++= *p2++;
其他情况几乎都是独立一个语句折腾,省得自己或别人对代码还要反复核对。。。累不累?反正我是累了。
关于顺序点, side effect的定义和说明在ISO/IEC 9899:1990的5.1.2.3节和Annex C
这个就是sequence point和side effect问题.
func(f1(),g1());
上面的表达式到底先执行那个函数 顺序是不确定的. 是Unspecified.
函数调用会产生一个side effect, 而调用函数之前是一个Sequence Point. 所以可以确定func()将会在f1(), g1()之后执行. 同时两个Sequence Point之间的side effect执行顺序是unspecified的. 所以先执行f1()还是先执行g1() 是不确定的.
这个用clang去编译得到的编译器警告就说的很清楚了,
引用来自“中山野鬼”的评论
从右向左,解析并编译。哈。理解这个就ok了。另外给楼主个提示,我学习和开发c语言的程序,也快20年了。类似你这样的问题,从来不纠结。。对于++i,i++,我一向保持,仅发生在通用实现方式,或独立一条语句中。哈,所谓通用实现方式,例如:
for(i = 0; i < 10 ;i++)
*p1++= *p2++;
其他情况几乎都是独立一个语句折腾,省得自己或别人对代码还要反复核对。。。累不累?反正我是累了。
根据你的描述是,函数f()的解析是从右到左的,而i++的i是用了再加,所以i++传入的值是1,自加后i的值就是2了。
从右向左,解析并编译。哈。理解这个就ok了。另外给楼主个提示,我学习和开发c语言的程序,也快20年了。类似你这样的问题,从来不纠结。。对于++i,i++,我一向保持,仅发生在通用实现方式,或独立一条语句中。哈,所谓通用实现方式,例如:
for(i = 0; i < 10 ;i++)
*p1++= *p2++;
其他情况几乎都是独立一个语句折腾,省得自己或别人对代码还要反复核对。。。累不累?反正我是累了。
仅供参考!不一定对喃!
k++是指先运行表达式,再加1;
k先赋值给方法,然后加1,然后k值变成了2,然后k再赋值给函数,最后调用函数,所以有先2后1的输出。
核心细节 可能 是表达式计算用的先进后出
可以在深入解释下:动态变化参数个数 的意思吗?
参数入栈顺序是和具体编译器实现相关的。
C方式参数入栈顺序(从右至左)的好处就是可以动态变化参数个数。通过栈堆分析可知,自左向右的入栈方式,最前面的参数被压在栈底。除非知道参数个数,否则是无法通过栈指针的相对位移求得最左边的参数。这样就变成了左边参数的个数不确定,正好和动态参数个数的方向相反。
因此,C语言函数参数采用自右向左的入栈顺序,主要原因是为了支持可变长参数形式。