va_list可变参数的秘密

va_list可变参数的秘密

在这里插入图片描述


我们知道在 c++里面,如果无法确认传入的参数个数以及类型的时候,那么可以使用 省略号来指定参数列表

比如

void fun1(int a, ...)
void fun2(...)

其中比较典型的就是printf函数

printf (const char *__restrict __fmt, …)

调用

printf(“ssss %d”,10)

那么其函数内部实现的是如何的

值得注意的是

  • \1. 变参处的定义或声明, 用 … 代替参数类型.
  • \2. 变参 … 只能放在参数列表最末尾.

内部实现原理

其实其内部的机制就是val_list

val_liststdarg.h头文件

type va_arg(
   va_list arg_ptr,
   type 
);
void va_end(
   va_list arg_ptr 
);
void va_start(
   va_list arg_ptr,
   prev_param 
);

其中type是指定回去参数的类型. arg_ptr是指向参数列表的指针. pre_param是指向最后一个显示声明的参数,用来回去第一个变长参数的位置

使用步骤

a)定义一个va_list类型的变量,变量是指向参数的指针。

b)va_start初始化刚定义的变量,第二个参数是最后一个显式声明的参数(也就是...之前的参数)。

c)va_arg返回变长参数的值,第二个参数是该变长参数的类型。

d)va_end将a)定义的变量重置为NULL。

具体的含义是

val_list定义一个变量列表的指针类型

va_start是将va_list对象绑定到有n个变量的传入参数列表上

va_arg是从参数列表中逐个去除数据,取出数据的类型有type决定,返回type类型的值.并且使得agv_ptr指向参数列表中的下一个参数.

当函数结束的时候调用va_end来清除va_list指向的空间,不然会发生内存泄露

所以必须知道传入参数的个数不然va_start无法绑定

例子

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

void myprint(const char* format, ...) {
  va_list va;
  va_start(va, format);
  char ch;
  while (ch = *format++) {
    if (ch == '%') {
      ch = *format++;
      if (ch == 's') {
        char* ss = va_arg(va, char*);
        while (*ss) {
          putchar(*ss++);
        }
      } else if (ch == 'd') {
        putchar(va_arg(va, int) + '0');
      }
    } else {
      putchar(ch);
    }
  }
  va_end(va);
}

int main() { myprint("hello world %s years %d\n", "!!!", 9); }
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值