本文共 3470 字,大约阅读时间需要 11 分钟。
(转自:)
int printf(const char* format,…)int scanf(const char *format,…)就拿 printf 来说吧,它除了有一个参数 format 固定以外,后面的参数其个数和类型都是可变的,用三个点“…”作为参数占位符。
x86平台VC6.0编译器中,stdarg.h头文件内变参宏定义如下:
typedef char * va_list;// 把 n 圆整到 sizeof(int) 的倍数#define _INTSIZEOF(n) ( (sizeof(n)+sizeof(int)-1) & ~(sizeof(int)-1) )// 初始化 ap 指针,使其指向第一个可变参数。v 是变参列表的前一个参数#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )// 该宏返回当前变参值,并使 ap 指向列表中的下个变参#define va_arg(ap, type) ( *(type *)((ap += _INTSIZEOF(type)) - _INTSIZEOF(type)) )// /将指针 ap 置为无效,结束变参的获取#define va_end(ap) ( ap = (va_list)0 )
例如,若1≤sizeof(n)≤4,则_INTSIZEOF(n)=4;若5≤sizeof(n)≤8,则_INTSIZEOF(n)=8。
显式提供变参数目或设定遍历结束条件
显式提供变参类型枚举值,或在固定参数中包含足够的类型信息(如printf函数通过分析format字符串即可确定各变参类型) 主调函数和被调函数可约定变参的数目和类型 …
#include运行结果如下:#include void parse_valist_by_num(int arg_cnt, ...);int main(void){ parse_valist_by_num(4,1,2,3,4); parse_valist_by_num(4,1,2,3); parse_valist_by_num(4,1,2,3,4,5); //多余的变参被忽略}//第一个参数定义可变参数的个数void parse_valist_by_num(int arg_cnt, ...){ va_list p_args; va_start(p_args, arg_cnt); int idx; int val; for(idx = 1; idx <= arg_cnt; ++idx){ val = va_arg(p_args, int); printf("第 %d 个参数: %d\n", idx, val); } printf("---------------\n"); va_end(p_args);}
注意第2个结果,第4个参数是一个魔数,这是因为打印出了栈中参数3上方的参数值。
#include运行结果是:#include void parse_valist_by_flag(int num_1, ...);int main(void){ parse_valist_by_flag(1,-1); parse_valist_by_flag(1,2,3,5,-1); parse_valist_by_flag(-1); }//函数定义一个结束标记(-1),调用时通过最后一个参数传递该标记,以结束变参的遍历打印。//最后一个参数作为变参结束符(-1),用于循环获取变参内容void parse_valist_by_flag(int num_1, ...){ va_list p_args; va_start(p_args, num_1); int idx = 0; int val = num_1; while(val != -1){ ++idx; printf("第 %d 个参数: %d\n", idx, val); val = va_arg(p_args, int); //得到下个变参值 } va_end(p_args); printf("---------------\n");}
在C语言中,调用不带原型声明或声明为变参的函数时,主调函数会在传递未显式声明的参数前对其执行缺省参数提升(default argument promotions),将提升后的参数值传递给被调函数。
提升操作如下:
参考资料
https://www.cnblogs.com/clover-toeic/p/3736748.html ———————————————— 版权声明:本文为CSDN博主「ARM的程序员敲着诗歌的梦」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/longintchar/article/details/85490103