可变参数列表

来源:互联网 发布:好桌道软件下载 编辑:程序博客网 时间:2024/05/29 13:14

可变参数列表的使用是很有必要的一件事情,在实现某个功能时,你可能不知道传几个参数。下面简单介绍一下可变参数列表的使用。

可变参数列表是通过宏来实现的,定义与stdarg.h头文件中。

void va_start(va_list ap, last); //va_start用来初始化参数列表t
type va_arg(va_list ap, type); //va_arg用来获取参数列表中的一个参数,类型为type。
void va_end(va_list ap); //va_end用来清理参数列表。
void va_copy(va_list dest, va_list src); //va_copy用来拷贝参数列表

下面是这些函数宏的实现

typedef char * va_list; //字符串指针#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1)& ~(sizeof(int) - 1) )#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )#define va_end(ap) ( ap = (va_list)0 )

下面是宏的具体作用
va_list

typedef char * va_list; /*宏的定义把char*重命名为va_list,使得va_list定义的指针变量可以访问到未知参数列表*/

va_start

#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )/*初始化参数列表 _INTSIZEOF(v)的作用是跳过最后一个已知变量v,ap取到未知参数列表的第一个参数,完成参数列表的初始化*/

va_arg

#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)))/*取出当前参数t是未知参数列表中参数的类型。((ap += _INTSIZEOF(t)) - _INTSIZEOF(t))的作用是使得每次调用va_arg都能使指针自动往后移动一位,本次对本参数访问的同时,下次可以访问到下一个参数。/

va_end

#define va_end(ap) ( ap = (va_list)0 )/*清空参数列表把指向参数列表的指针置为0,达到清理参数列表的目的*/

接下来具体介绍可变参数列表的使用

1.求n 个数的平均数

#include<stdarg.h>#include<stdio.h>int Average(int n,...){    int i = 0;    int sum = 0;    va_list arg;     //char* arg 类型重命名    va_start(arg, n);    // #define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) ) 宏的实现    // 替换后  ( arg = (char*)&n + 4 )    for (i = 0; i < n; i++)    {        sum += va_arg(arg, int);        //#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t))) 宏的实现        //替换后 sum += ( *(int*)((arg += 4) - 4))     }    va_end(arg);    //#define va_end(ap) ( ap = (va_list)0 )    //替换后 (arg = (char*)0 );    return sum / n;}int main(){    int ave = Average(3, 1, 2, 3);    printf("ave = %d\n", ave);    system("pause");    return 0;}

2.求取参数部分n个里面的最大值

#include<stdarg.h>#include<stdio.h>int Max(int n, ...){    int i = 0;    va_list arg;    va_start(arg, n);    int tmp = va_arg(arg, int); //tmp 用来保存第一个数 即-3    for (i = 0; i < n-1; i++)    {        int tmp1 = va_arg(arg, int); // 此时 tmp1 用来保存后面的数 ,即循环一次访问一个接下来元素        if (tmp < tmp1)        {            tmp = tmp1;        }    }    return tmp;}int main(){    int max = Max(3, -3, -1, -2);    printf("max = %d\n", max);    system("pause");    return 0;}

3.printf函数的模拟实现

#include<stdarg.h>#include<stdio.h>#include<assert.h>void display(int n){    if (n > 9)    {        display(n / 10);    }    putchar(n % 10 + '0');}void print(char *format, ...){    assert(format != NULL);    va_list arg;    va_start(arg, format);    while (*format)    {        switch (*format)        {            case 's':            {                    char *ret = va_arg(arg, char*);                    while (*ret)                    {                        putchar(*ret);                        ret++;                    }            }                break;            case 'c':            {                    char ret = va_arg(arg, char);                    putchar(ret);            }                break;            case 'd':                display(va_arg(arg, int));                break;            default:                putchar(*format);                break;        }        format++;    }}int main(){    print("s ccc d.\n", "hello", 'B', 'A', 'T', 100);    system("pause");    return 0;}以上就是我对可变参数列表的一些理解,有不对的地方还希望指正。
0 0
原创粉丝点击