C语言可变参数

一、可变参数

有时,您可能会碰到这样的情况,您希望函数带有可变数量的参数,而不是预定义数量的参数。C 语言为这种情况提供了一个解决方案,它允许您定义一个函数,能根据具体的需求接受可变数量的参数。下面的实例演示了这种函数的定义。

int func(int, ... ) {
   .
   .
   .
}
 
int main(){
   func(2, 2, 3);
   func(3, 2, 3, 4);
}
二、函数参数的传递原理

函数参数是以数据结构:栈的形式存取,从右至左入栈。
首先是参数的内存存放格式:参数存放在内存的堆栈段中,在执行函数的时候,从最后一个开始入栈。因此栈底高地址,栈顶低地址,举个例子如下:
void func(int x, float y, char z);
那么,调用函数的时候,实参 char z 先进栈,然后是 float y,最后是 int x,因此在内存中变量的存放次序是 x->y->z,因此,从理论上说,我们只要探测到任意一个变量的地址,并且知道其他变量的类型,通过指针移位运算,则总可以顺藤摸瓜找到其他的输入变量。

三、可变参数相关函数
函数\宏描述
typedef char* va_list;这是一个适用于 va_start()、va_arg() 和 va_end() 这三个宏存储信息的类型。
void va_start(va_list ap, last_arg) ;初始化 ap 变量。
这个宏必须在使用 va_arg 和 va_end 之前被调用。
参数:
ap 这是一个 va_list 类型的对象,它用来存储通过 va_arg 获取额外参数时所必需的信息。
last_arg是最后一个传递给函数的已知的固定参数,即省略号之前的参数。
type va_arg ( va_list ap, type );返回函数参数列表中类型为 type 的下一个参数。
参数:
ap 这是一个 va_list 类型的对象,存储了有关额外参数和检索状态的信息。
type 这是一个类型名称。该类型名称是作为扩展自该宏的表达式的类型来使用的。
void va_end ( va_list ap );允许使用了 va_start 宏的带有可变参数的函数返回。如果在从函数返回之前没有调用 va_end,则结果为未定义。
int vsprintf(char *str, const char *format, va_list arg)使用参数列表发送格式化输出到字符串。
参数:
str 这是指向一个字符数组的指针,该数组存储了 C 字符串。
format是字符串,包含了要被写入到字符串 str 的文本格式。
arg一个表示可变参数列表的对象。
四、示列

1.1 示列一

#include <stdio.h>
#include <string.h>
#include <stdarg.h>

void tLog(char *sInfo, ...);

int main(int argc, char *argv[]) {
    char str[4+1] = {0};
    strcpy(str,"INFO");
    tLog(str,argv[1],argv[2],argv[3]);
    return 0;
}
void tLog(char *sInfo, ...) {
    char *str   = NULL;
    char *str1 = NULL;
    char *str2 = NULL;
    va_list sArgv;          // 申请参数列表变量
    va_start(sArgv, sInfo); // 申明最后一个传递给函数的已知的固定参数
    /* 依次读取固定参数 sInfo 后的 参数 */
    str   = va_arg(sArgv, char*);
    str1 = va_arg(sArgv, char*);
    str2 = va_arg(sArgv, char*);
    va_end(sArgv);
    printf("运行输出:[%s,%s%s%s]\n",sInfo,str,str1,str2);
}

1.2 vsprintf

#include <stdio.h>
#include <stdarg.h>

char buffer[80];
int vspfunc(char *format, ...)
{
   va_list aptr;
   int ret;

   va_start(aptr, format);
   ret = vsprintf(buffer, format, aptr);
   va_end(aptr);

   return(ret);
}

int main()
{
   int i = 5;
   float f = 27.0;
   char str[50] = "mp.csdn.net";

   vspfunc("%d %f %s", i, f, str);
   printf("%s\n", buffer);
   
   return(0);
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

书香水墨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值