第44课 - 函数参数的秘密(上)

1、函数参数 

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

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

        



        函数参数的求值顺序依赖于编译器的实现 

            下面的程序输出什么?为什么?

        

        包括+、-、*、/等等左右操作数谁先计算的顺序c语言并未规定,要根据编译器


3、实例分析 

函数参数的求值顺序     44-1.c 

  1. #include <stdio.h>  
  2.   
  3. int func(int i, int j)  
  4. {  
  5.     printf("%d, %d\n", i, j);  
  6.       
  7.     return 0;  
  8. }  
  9.   
  10. int main()  
  11. {  
  12.     int k = 1;  
  13.       
  14.     func(k++, k++);  
  15.       
  16.     printf("%d\n", k);  
  17.       
  18.     return 0;  
  19. }  

                    

            即先计算的是右边k++


当修改

  1. #include <stdio.h>  
  2.   
  3. int func(int i, int j)  
  4. {  
  5.     printf("%d, %d\n", i, j);  
  6.       
  7.     return 0;  
  8. }  
  9.   
  10. int main()  
  11. {  
  12.     int k = 1;  
  13.   
  14.     int j = 2;  
  15.       
  16.     func(k++, j++);  
  17.       
  18.     printf("%d\n", k);  
  19.   
  20.     printf("%d\n", j);  
  21.       
  22.     return 0;  
  23. }  

                    

                                    可以清晰看到先执行j++,再i++,再call函数


                                                    

                        这是常见大多数编译器的执行方式,然而C语言并未规定

                        对于加减乘除等大多数选择先左操作数,再右操作数


4、程序中的顺序点 

            程序中存在—定的顺序点 

            顺序点指的是执行过程中修改变量值的最晚时刻 

            在程序到达顺序点的时候,之前所做的—切操作必须完成 


5、C语言中的顺序点 

            每个完整表达式结束时,即分号处 

            &&, ||, ?:, 以及逗号表达式的每个参数计算之后 

            函数调用时所有实参求值完成后(进入函数体之前) 

            下面的程序运行结束后k的值为多少

                

6、编程实验 

程序中的顺序点 44-2.c

  1. #include <stdio.h>  
  2.   
  3. int main()  
  4. {  
  5.     int k = 2;  
  6.     int a = 1;  
  7.       
  8.     k = k++ + k++;  
  9.       
  10.     printf("k = %d\n", k);  
  11.       
  12.     if( a-- && a )  
  13.     {  
  14.         printf("a = %d\n", a);  
  15.     }  
  16.       
  17.     return 0;  
  18. }  

                            

VS2015

                

                当计算2+2后,发现“;”,这是改变内存的最晚时刻,所以对内存

                            的操作必须完成,即“悬挂的”两个++再计算

            当发现&&时,对内存操作必须完成,所以a- -结果为0

            在bcc,gcc编译器环境下测试,结果同为6,但不排除其它编译器结果

        同样在44-1.c中,两个++操作就在调用函数之前必须完成

        在vs2015下编译44-1.c

                                        

            即编译器先取右k值为1给j,此时一个++”悬挂着”,还未到内存操

            作最晚时间,接着,取左边k值为1给i,此时又“悬挂着”一个++,

            接着到了内存操作最晚时刻,所以连续两次++,k=3,i=1,j=1


7、小结 

            函数的参数在栈上分配空间 

            函数的实参并没有固定的计算次序 

            顺序点是C语言中变量修改的最晚时机

猜你喜欢

转载自blog.csdn.net/qq_39654127/article/details/80198237
今日推荐