欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

44-45-函数参数的秘密

程序员文章站 2022-05-11 13:09:30
...

1、函数参数

44-45-函数参数的秘密

2、参数求值顺序

44-45-函数参数的秘密

int func(int i, int j)
{
    printf("%d, %d\n", i, j);
    return 0;
}

int main()
{
    int k = 1;
    func(k++, k++);
    printf("%d\n", k);
    return 0;
}
输出:
i = 2,j = 1
k = 3;
func函数参数的初始值是函数调用时的实参,
而函数参数调用的顺序一般是从右向左(依赖编译器)
也就是先计算第二个参数k++,此时将k=1 传递给参数j=1,然后此时k=2;
然后k=2,在计算第一个参数k++,此时k=2,传递给参数i=2,此时k=3
然后开始进行函数内部计算,打印出i=2,j=1;函数返回后,最终打印k=3;
所以函数调用时所有实参求值完成后(进入函数体之前)要将实参赋值给形参


3、顺序点

44-45-函数参数的秘密

4、一般的顺序点存在之处

44-45-函数参数的秘密

int  k = 2;
k = k++ + k++;
分析:首先执行k++,此时k值仍为2,悬挂一次++
然后再执行第二个k++,此时k的内存值仍为2,又悬挂一次++
此时k的内存值为4,最后看到分号表示表达式结束,但是还有两次++操作没有完成,便对k=4进行两次++操作,最终k=6,结束。

5、小结

44-45-函数参数的秘密

6、参数入栈顺序

44-45-函数参数的秘密

7、调用约定

44-45-函数参数的秘密
44-45-函数参数的秘密

9、可变参数

44-45-函数参数的秘密

10、可变参数限制

44-45-函数参数的秘密

11、小结

44-45-函数参数的秘密

#include <stdio.h>
#include <stdarg.h>
float average(int n, ...)
{
    va_list args;
    int i = 0;
    float sum = 0;
    va_start(args, n);
    for(i=0; i<n; i++)
    {
        sum += va_arg(args, int);
    }
    va_end(args);
    return sum / n;
}
int main()
{
    printf("%f\n", average(5, 1, 2, 3, 4, 5));
    printf("%f\n", average(4, 1, 2, 3, 4));
    return 0;
}
3.000000
2.500000