C语言表达式计算顺序的一个小问题
2010-12-29 22:48
246 查看
http://sunxiunan.com/?p=1742
浏览Q.yuhen的博客这篇文章 http://www.rainsts.com/article.asp?id=959 发现一个小问题,估计有类似想法的同学也有,所以记录一下。
问题在于这句话:
“很显然,依据 cdecl 规则,"printf(…, test(2), test(1))" 中的 printf 函数参数依次从右向左 "入栈"(暂且用这个说法)。因此 test(1) 被先调用,然后才是 test(2),上面的汇编代码也说明了这点。”
尽管事实是这样的,但这是一个有问题的说法。
cdecl的入栈顺序是没错的,这个入栈顺序是针对每个逗号分隔的表达式结果而言。也就是说对于每个结果一定是这样的顺序。但是表达式计算顺序(或者说每个逗号分割的函数调用)其实是没有规定的。这在K&R影印版第二版52页最末一段说的非常清楚,下面的f和g不一定谁先调用:
C, like most languages, does not specify the order in which the operands of an operator are evaluated. (exceptions are && || ?: and ",") for example x = f() + g();
另外在63页开始:
The commas that separate function arguments, variables in declarations, etc., are NOT comma operators, and do NOT guarantee left to right evaluation.
这也就是说逗号分隔的函数参数与逗号操作符是不一样的,不保证从左至右的计算顺序(当然也没有保证从右至左)。
注意这个evaluation,其实就是对test(2), test(1)的调用。如果这些调用有边界效应,在不同编译器、操作系统上可能会得到不同的结果。另外类似的问题有对在参数列表中,同一个变量调用++两次以上。
如果要保证求值顺序(注意不是求值结果的入栈顺序),只能用临时变量保存调用结果,或使用逗号操作,&& || :? 这样可以保证求值顺序的操作才行。
其实我在前面这篇博客已经提到了这个问题,只是看到这个提法再重申一次。“C语言中的表达式求值问题”http://sunxiunan.com/?p=1684
参考资料:
http://www.andromeda.com/people/ddyer/topten.html 参考第七条
C陷阱与缺陷 3.7求值顺序
浏览Q.yuhen的博客这篇文章 http://www.rainsts.com/article.asp?id=959 发现一个小问题,估计有类似想法的同学也有,所以记录一下。
问题在于这句话:
“很显然,依据 cdecl 规则,"printf(…, test(2), test(1))" 中的 printf 函数参数依次从右向左 "入栈"(暂且用这个说法)。因此 test(1) 被先调用,然后才是 test(2),上面的汇编代码也说明了这点。”
尽管事实是这样的,但这是一个有问题的说法。
cdecl的入栈顺序是没错的,这个入栈顺序是针对每个逗号分隔的表达式结果而言。也就是说对于每个结果一定是这样的顺序。但是表达式计算顺序(或者说每个逗号分割的函数调用)其实是没有规定的。这在K&R影印版第二版52页最末一段说的非常清楚,下面的f和g不一定谁先调用:
C, like most languages, does not specify the order in which the operands of an operator are evaluated. (exceptions are && || ?: and ",") for example x = f() + g();
另外在63页开始:
The commas that separate function arguments, variables in declarations, etc., are NOT comma operators, and do NOT guarantee left to right evaluation.
这也就是说逗号分隔的函数参数与逗号操作符是不一样的,不保证从左至右的计算顺序(当然也没有保证从右至左)。
注意这个evaluation,其实就是对test(2), test(1)的调用。如果这些调用有边界效应,在不同编译器、操作系统上可能会得到不同的结果。另外类似的问题有对在参数列表中,同一个变量调用++两次以上。
如果要保证求值顺序(注意不是求值结果的入栈顺序),只能用临时变量保存调用结果,或使用逗号操作,&& || :? 这样可以保证求值顺序的操作才行。
其实我在前面这篇博客已经提到了这个问题,只是看到这个提法再重申一次。“C语言中的表达式求值问题”http://sunxiunan.com/?p=1684
参考资料:
http://www.andromeda.com/people/ddyer/topten.html 参考第七条
C陷阱与缺陷 3.7求值顺序
相关文章推荐
- C语言printf函数输出表达式中的计算顺序
- C语言printf函数输出表达式中的计算顺序
- 杂:表达式计算顺序,参数传递顺序,typedef和define一个区别
- C语言printf函数输出表达式中的计算顺序
- C语言用数组1. 简单约瑟夫环问题: N个人,编号从1~N围成一圈,输入一个数T,从1号开始报数,报到T的人出圈;下一人又从1开始报数,下一个报到T的人出圈,输出出圈顺序。 考虑问实现约瑟夫环问题
- C语言printf函数输出表达式中的计算顺序
- num++和++num在逗号表达式中的计算顺序
- 一个有趣的C语言问题
- 逆波兰表达式的计算问题
- 读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。
- 我就给一个PHP逆波兰表达式的算法吧---工资计算专用
- 关于一个C语言二维数组的问题
- 初学c语言--Linux下的gets命令,对n个数的顺序排列 计算字符串里的单词数 n个数里取m的方法 杨辉三角
- 开博第一篇:一个关于正则表达式相关的问题
- day08之元素出栈、入栈顺序的合法性+计算一个整数二进制位中1的个数
- 一个关于局域网中【并行计算】的问题
- C中参数压栈及表达式计算顺序
- 一个表上的多个触发器执行顺序问题
- C语言实现二叉树的建立、遍历以及表达式的计算
- [Happy Coding] 一个正则表达式,支持逻辑和关系运算符组成的表达式计算