最近写代码的时候本想着用点小trick,结果一不小心踩了个坑。
一个例子:
#include <stdio.h>
int main()
{
int id = 0;
printf("%d,%d\n", id++, id++);
printf("%d,%d\n", id++, id);
printf("%d,%d\n", id, id++);
printf("%d,%d\n", ++id, ++id);
printf("%d,%d\n", id, ++id);
printf("%d,%d\n", ++id, id);
printf("%d\n", id);
return 0;
}
用gcc编译,-Wall打开warning,输出如下,显然这种在函数调用的参数中使用自增运算是不太好的做法,may be undefined:
test.c: In function ‘main’:
test.c:7:28: warning: operation on ‘id’ may be undefined [-Wsequence-point]
printf("%d,%d\n", id++, id++);
^
test.c:8:22: warning: operation on ‘id’ may be undefined [-Wsequence-point]
printf("%d,%d\n", id++, id);
^
test.c:9:26: warning: operation on ‘id’ may be undefined [-Wsequence-point]
printf("%d,%d\n", id, id++);
^
test.c:10:26: warning: operation on ‘id’ may be undefined [-Wsequence-point]
printf("%d,%d\n", ++id, ++id);
^
test.c:11:24: warning: operation on ‘id’ may be undefined [-Wsequence-point]
printf("%d,%d\n", id, ++id);
^
test.c:12:20: warning: operation on ‘id’ may be undefined [-Wsequence-point]
printf("%d,%d\n", ++id, id);
^
运行输出是:
1,0
2,3
4,3
6,6
7,7
8,8
8
具体的分析参考:
函数参数进栈以及自增运算在函数调用中的trick
C语言 printf函数对参数的计算顺序自加自减的讨论
需要注意这么几点:
1.函数调用时参数的入栈顺序,从右到左。
2.前缀式和后缀式的区别
1.为了与内置类型一致,前缀式操作符应返回被增量或减量对象的引用
2.为了与内置类型一直,后缀式操作符应返回旧值(即,尚未自增或自减的值),并且,应作为值返回,而不是返回应用。
3.在不同的编译器中可能会得到不同的结果,例如VC++6.0后自增运算是要在整条语句结束以后才自加1的。
4.C++中, 前缀式自增(或自减)可以用来当做左值使用,但是后缀式自增(或自减)不能被当做左值使用。