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变量.
  • 相关阅读:
    【SQL注入】之SQLMAP工具的使用
    【漏洞复现】之PHP-FRM远程代码执行漏洞(CVE-2019-11043)复现
    利用PHPStudy搭建伪静态页面
    【渗透测试小白系列】之利用PHPMyAdmin Getshell
    【渗透测试小白系列】之Docker入门以及漏洞环境搭建
    web服务器是什莫: tomcat各个目录简介
    equals和==的区别
    ln命令
    head tail ln sort uniq指令
    rpm包安装
  • 原文地址:https://www.cnblogs.com/Tokubara/p/14036688.html
Copyright © 2011-2022 走看看