函数参数在本质上与局部变量相同,都是在栈上分配空间
2、&&、||、?:以及逗号表达式的每个参数计算之后;
3、函数调用时所有实参求值完成后(进入函数体之前)。
函数参数的初始值是函数调用时的实参值
观察下面代码,判断输出:
int k=1; printf("%d, %d\n", k++, k++); (划重点) printf("%d\n", k);
编译运行后输出结果:
~/will$ ./a.out 2, 1 3
所以我们必须注意,函数参数的求值顺序依赖于编译器的实现
不能假设从左到右的实现顺序,这个顺序是依赖于编译器的行为。
再看下面代码:
int f() { return 1; } int g() { return 2; } int main() { int k = 0; k = f() * g (); printf("%d\n", k); return 0; }
我们能得到正确的结果,但是无法简单的认为
k = f() * g ();
这行代码是从左到右的。
其实大多数情况下,都是从右往左进行求值的。
程序中的顺序点:
程序中存在一定的顺序点
顺序点指的是执行过程中修改变量值的最晚时刻
在程序到达顺序点的时候,之前所做的一切操作必须完成
C语言中的程序点
1、每个完整表达式结束时,即分号处;2、&&、||、?:以及逗号表达式的每个参数计算之后;
3、函数调用时所有实参求值完成后(进入函数体之前)。
int k =2; k = k++ + k++; k = ?
编译运行: k=6;
顺序点:程序先做加法运算——左右操作数(一个为2,一个为2),往后遇见分号(顺序点),然后2+2=4,然后进行两次++操作。(定义1)
int main() { int k = 2; int a = 1; k = k++ + k++; printf("k = %d\n", k); if( a-- && a ) //&&也是一个顺序点,在此之前,a--的值为0,条件为假,不打印(定义2) { printf("a = %d\n", a); } return 0; }
小结:
函数的参数在栈上分配空间
函数的实参并没有固定的计算次序
顺序点是C语言中变量修改的最晚时机