C语言进阶44:函数参数的秘密《上》——参数访问顺序和程序点

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

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

观察下面代码,判断输出:  

	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语言中变量修改的最晚时机

猜你喜欢

转载自blog.csdn.net/qq_28388835/article/details/80380800