可变参数列表剖析

1、main函数的参数解析:

栈帧的学习我们知道一个程序并不是从一开始就开始调用main函数的,main函数是被_CRTmainstartup调用的。
其实main函数是有参数的,我们来看看他的原型:

int main(int argc, char*argv[], char*envp[])
{
    program - statements

}

argc是整形变量,表示参数的个数。
argv是指针数组(元素为字符型指针,指向字符串)。
envp是指针数组(每一个元素是一个指向环境变量(字符串)的字符指针)

  #include
int main(int argc, char*argv[], char*envp[])
{
    int i = 0;
    for (i = 0; i < argc; i++)
    {
        printf("%s\n", argv[i]);
    }
    return 0;
}
```![输出结果](https://img-blog.csdn.net/20171111213447667?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3gyNDc5NzUwMTk2/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
右击源文件,点击属性-调试,在列表中写hello world,就会显示如下结果![显示hello world](https://img-blog.csdn.net/20171111213927116?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3gyNDc5NzUwMTk2/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

分析:![第一个参数argc](https://img-blog.csdn.net/20171111214807307?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3gyNDc5NzUwMTk2/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
分析第三个参数:`#include
int main(int argc, char*argv[], char*envp[])
{
    int i = 0;
    while (envp[i] != NULL)
    {
        printf("%s\n", envp[i]);
        i++;
    }
    system("pause");
    return 0;
}`
执行结果:![结果显示环境变量,最后一个元素也是NULL指针](https://img-blog.csdn.net/20171111215145955?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY3gyNDc5NzUwMTk2/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)




##可变参数列表解析: 作用:通过将函数实现为可变参数的形式,使函数可以接受一个以上的任意多个参数 例子:求平均值`
#include #include int average(int n,...) { va_list arg; int i = 0; int sum = 0; va_start(arg, n); for (i = 0; i < n; i++) { sum += va_arg(arg, int); } return sum / n; va_end(arg); } int main() { int ret = average(3, 2, 3, 4); printf("%d\n", ret); system("pause"); return 0; }` 求最大值:`#include #include int MAX(int n, ...) { int i = 0; va_list arg; va_start(arg, n); int max = 0; for (i = 0; i < n; i++) { int res=va_arg(arg, int); if (res>max) { max = res; } } return max; va_end(arg); } int main() { int ret = MAX(3, 3, 4, 5); printf("%d\n", ret); system("pause"); return 0; } `模拟实现printf函数:

include

可变参数的限制:

1、可变参数必须从头到尾逐个访问。访问了几个之后可以半途而止,但是不可以从中间访问参数是不可行的。
2、参数列表中至少有一个命名参数,如果没有参数就无法使用va_atart。
3、这些宏是无法直接判断实际存在参数的数量。
4、这些宏无法判断每个参数的类型。
5、如果在va_arg中指定了错误的类型,那么后果不可测。

你可能感兴趣的:(c语言)