zoukankan      html  css  js  c++  java
  • c的可变参数(va_arg,va_list,va_start,va_end)

    首先是头文件. <stdarg.h>

    其次, 我们的目的是实现支持变长参数的函数, 但并不是说,这个函数参数可以全都是变的. 不行. 函数的参数列表中, 一定至少要有一个有name的参数. 比如printf, 它的定义是printf(const char * restrict format, ...);也是有restrict format这个有name的参数的. 变参正如printf显示的那样, 是...

    好了, 怎么用呢. 我们拿一个网上博客的例子. 出处是深入C语言可变参数(va_arg,va_list,va_start,va_end)

    #include <stdio.h>
    #include <stdarg.h>
    
    void print_args(int count, ...);
    
    int main(int argc, char* argv[]) {
    	print_args(5,1,2,3,4,5);
    	return 0; 
    }
    
    void print_args(int count, ...) {
    	int i, value;
    	va_list arg_ptr;
    	va_start(arg_ptr, count);
    	for(i=0; i<count; i++) {
    		value = va_arg(arg_ptr,int);
    		printf("position %d = %d
    ", i+1, value);
    	}
    	va_end(arg_ptr);
    }
    

    首先看函数的定义, 有一个有name的参数count, 除此之外就是变参...
    要获得变参, 首先需要定义一个va_list类型的变量, 这里是va_list arg_ptr;. 这个类型的变量, 之后会遍历获取到所有的参数, 这个变量我们会一直用, 一直到参数解析完毕.
    但这个变量使用前必须初始化, 我们看到是va_start(arg_ptr, count);, 这个函数实际上是一个宏. 它需要两个参数, 第一个是va_list类型的遍历变量, 第二个参数是这个函数最后一个有name的参数, 这里就是count. 但是va_start的作用是什么呢?

    The macro va_start initializes ap to point to the first unnamed argument.
    让它指向第一个unnamed的参数.
    好了, 那么怎么获得变参呢? 这就是value = va_arg(arg_ptr,int);, 第一个参数自然是va_list类型, 第二个参数是指定类型, 这样才知道它占的内存大小, 才知道它占了多少, 下一步该到内存什么位置. 返回就会返回int类型的. 这个va_arg应该也是宏.
    最后必须在函数返回前调用va_end, K&R是这么说的:
    Finally, va_end does whatever cleanup is necessary.

    好了再总结使用要点:

    • 头文件是<stdarg.h>
    • 先定义va_list变量, 然后va_start它, 第二个参数是最后一个named参数
    • va_arg(va_list变量, 类型)解析参数, 返回就是我们调用的参数.
    • 最后用va_end释放va_list变量.
  • 相关阅读:
    查看mysql版本的四种方法及常用命令
    newInstance和new的区别(good)
    Citrix 服务器虚拟化之六 Xenserver虚拟机创建与快照
    Java实现 蓝桥杯 算法训练 排序
    Java实现 蓝桥杯 算法训练 排序
    Java实现 蓝桥杯 算法训练 排序
    Java实现 蓝桥杯 算法训练 2的次幂表示
    Java实现 蓝桥杯 算法训练 2的次幂表示
    Java实现 蓝桥杯 算法训练 前缀表达式
    Java实现 蓝桥杯 算法训练 前缀表达式
  • 原文地址:https://www.cnblogs.com/Tokubara/p/14036688.html
Copyright © 2011-2022 走看看