乐趣区

44_函数参数的秘密 (上)

函数参数

函数参数在本质上与局部变量相同在栈上分配空间

函数参数的初始值是函数调用时的实参值

函数参数的求值顺序依赖于编译器的实现
操作符的求值顺序依赖于编译器的实现(+-*/…)

下面的程序输出什么?为什么呢?
int k = 1;
printf(“%d, %d\n”, k++, k++);
实例分析:函数参数的求值顺序
#include <stdio.h>

int func(int i, int j)
{
printf(“i = %d, j = %d\n”, i, j);
}

int main()
{
int k = 1;

func(k++, k++);

printf(“%d\n”, k);
}
输出:【gcc】
i = 2, j = 1
3

特别说明:此处暂时没有找到有其它求值顺序的编译器来输出说明。由于 C 语言未明确规定函数参数的求值顺序,其交由具体的编译器厂商决定,因此为了提高程序的可移植性,不可依赖某一编译器的求值顺序行为。
程序中的顺序点

程序中存在一定的顺序点
顺序点是指执行过程中修改变量值 (内存) 的最晚时刻
在程序到达顺序点的时候,之前所作的一切操作必须完成

C 语言中的顺序点

每个完整表达式结束时,即分号处
&&, ||, ?: 及 逗号表达式 的每个参数计算之后
函数调用时所有实参求值完成后(进入函数体之前)

下面的程序运行结束后 k 的值为多少呢?
int k = 2;
k = k++ + k++;
编程实验:程序中的顺序点
test_1.c
#include <stdio.h>

int main()
{
int k = 2;
int a = 1;

k = k++ + k ++;

printf(“k = %d\n”, k);

if(a– && a)
{
printf(“a = %d\n”, a);
}

return 0;
}
输出【gcc】:
k = 6

输出【vs2010】:
k = 6

发生了什么?
test2.c
#include <stdio.h>

int func(int i, int j)
{
printf(“i= %d, j = %d\n”, i, j);

return 0;
}

int main()
{
int k = 1;

func(k++, k++);

printf(“%d\n”, k);

return 0;
}
输出:【gcc】
i = 2, j = 1
3

输出:【vs2010】
i = 1, j = 1
3

小结

函数的参数在栈上分配空间
函数的实参并没有固定的计算次序
顺序点时 C 语言中变量修改的最晚时机

以上内容参考狄泰软件学院系列课程,请大家保护原创!

退出移动版