va_list

VA_LIST
C语言中解决变参问题的一组宏,变参问题是指参数的个数不定,可以是传入一个参数也可以是多个;可变参数中的每个参数的类型可以不同,也可以相同。

va_list 用法:

  • 在函数里定义一具VA_LIST型的变量,这个变量是指向参数的指针;
  • 然后用VA_START宏初始化变量刚定义的VA_LIST变量;
  • 然后用VA_ARG返回可变的参数,VA_ARG的第二个参数是你要返回的参数的类型(如果函数有多个可变参数的,依次调用VA_ARG获取各个参数);
  • 最后用VA_END宏结束可变参数的获取。

va_list 用法示例:

#include 
#include 
#include 

void write_log( char *fmt, ...){
    va_list va;
    char buf[1024];   
    va_start(va, fmt);
    memset(buf, 0, 1024);
    (void) vsprintf(buf, fmt, va);
    va_end(va);   
    printf("%s-%s", "my_log_prehead", buf);
}

void read_num(int num, ...)
{
    va_list va;             /*point to each unamed variables in arg list*/
    va_start(va, num);      /*start va_list from num, and va goes to the second one, and this is the first vary variable*/
    while(num--) {
    	printf("%d\t", va_arg(va, int)); /*get a arg, va goes to the next*/
    }
    va_end(va);             /*end the va*/
}

int main(){
    write_log("%s\n", "hello world!");
    read_num(3, 111, 222, 333);
    return 0;
}

结果输出:

my_log_prehead-hello world!
111 222 333

va_list 原理:

  • 简化版定义:
#define  va_list              char *
#define  va_start(p, first)   (p = (va_list)&first + sizeof(first))
#define  va_arg(p, next)      (*(next*)((p += sizeof(next) ) - sizeof(next)))
#define  va_end(p)            (p = (va_list)NULL)
  • 由于参数的地址用于VA_START宏,所以参数不能声明为寄存器变量,或作为函数或数组类型。

你可能感兴趣的:(C)