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

可变参数列表解析

程序员文章站 2022-07-15 08:53:29
...

可变参数的作用和使用

一般写的代码每个函数的参数都是给定的,给定两个实参,那么函数调用后就只能使用两个参数,如果数目不统一,编译器就会报错。通过将函数实现为可变参数的形式,可以使得函数可以接受1个以上任意多的参数。

***求三个数的平均数***
#include<stdio.h>
#include<stdlib.h>
#include<stdarg.h>

int avergae(int n, ...)
{
    va_list arg;//字符指针 typedef char* va_list;
    int i = 0;
    int sum = 0;
    va_start(arg, n);//把上面获得的字符指针,向后移动四个字节,跳过 n 的内存地址
    for(i=0;i<n;i++)
        sum = sum + va_arg(arg, int);//arg向后移动四个字节(sizeof(int)大小)
    return sum / n;
    va_end(arg);//结束标志
}

int main()
{
    int a = 1;
    int b = 2;
    int c = 3;
    int avg1 = avergae(3, a, b, c);
    printf("平均数=%d\n", avg1);
    system("pause");
    return 0;
}

可变参数列表分析

  1. va_list arg;
    typedef char* va_list 就是一个字符指针;
  2. va_start(arg,n) 其本身定义为宏,在预处理阶段会进行替换
    可变参数列表解析
    替换之后为:arg=(char*)&n+_INTSIZEOF(n) 就是给n的地址加上一个sizeof(n)的4个字节的大小。
    #define _INTSIZEOF(n) ((sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1))目的是把 sizeof(n) 的结果变成 sizeof(n) 的整数倍,用来在结构中实现按 int 的倍数对齐。

  3. va_arg(arg,int) 其本身定义为宏,在预处理阶段会进行替换
    可变参数列表解析
    替换之后为:sum=sum+( * (int * )((arg+=4)-4);让arg下移,令arg指向第二个参数的地址,然后在(arg+=4)-4,表达式有指向第一个参数,在强制转换为 int *,然后解引用得到第一个参数的值。在下一次循环时,arg指向第二个参数。
    4.va_end(arg); 其本身定义为宏
    #define __crt_va_end(ap) ((void)(ap = (va_list)0))
    替换之后为arg=char*(0);给arg赋值空指针,保证程序安全性;

    可变参数的限制

    1、 可变参数必须从头到尾逐个访问。不可能从中间开始访问。
    2、可变参数列表中至少有一个命名参数。如果连一个命名参数都没有,就无法使用va_start。
    3、 如果在va_arg中指定了错误的类型,那么其后果是不可预测的。
    4、这些宏无法直接判断实际 存在参数的数量。

相关标签: C语言