vsprintf 函数研究--可变参数列表

vsprintf 函数研究--可变参数列表
函数原型:
int vsprintf(char *string, char *format, va_list param);

看不懂的就是va_list

找一个实例代码做测试, 如下例.

$ cat main.cpp
#include <stdio.h>
#include <stdarg.h>
char str[50];


/* 这个函数是可变参数的, 其堆栈可以传递很多参数 */
int vspf(const char*fmt,...)
{
     va_list argp;		// 变参数列表 argp, 具体定义与平台有关
     int a;
     va_start(argp,fmt); // 让argp 指向 &fmt, 具体实现与平台有关
	 //vsprintf 第3个参数是va_list 参数
	 //格式化输出, argp 会随fmt 中的%而自动递长,从而访问到先入栈的参数
     a=vsprintf(str,fmt,argp);
     va_end(argp);//停止使用可变参数, 可保持结构的完整性
     return(a);
}
int main(void)
{
     int i=35;/*定义变量*/
     float f=12.4;
     char s[4]="old";
     vspf("%d,%f,%s\n",i,f,s);/*调用自定义函数,压栈了若干个参数*/
     printf("%s ",str);/*输出字符串*/
     return 0;
}

3点说明:
1. 可变参数函数. 传到函数堆栈中的参数不知道有多少个.
2. va_list 是什么类型?
    我用gdb 在linux 下打印了一下:

(gdb) ptype va_list
  type = struct typedef __va_list_tag __va_list_tag {
      unsigned int gp_offset;
      unsigned int fp_offset;
      void *overflow_arg_area;
      void *reg_save_area;
  } [1]

3. argp 是如何变化的?
开始时的 argp
(gdb) print argp
  $2 = {{
      gp_offset = 0,
      fp_offset = 0,
      overflow_arg_area = 0x0,
      reg_save_area = 0x0
    }}
用fmt 初始化后的argp
(gdb) p argp
  $3 = {{
      gp_offset = 8,
      fp_offset = 48,
      overflow_arg_area = 0x7fffffffdcc0,
      reg_save_area = 0x7fffffffdc00
    }}

用vsprintf 使用过后的argp
(gdb) p argp
  $6 = {{
      gp_offset = 24,
      fp_offset = 64,
      overflow_arg_area = 0x7fffffffdcc0,
      reg_save_area = 0x7fffffffdc00
    }}

argp地址是比format 地址大的地址,都在堆栈中放着呢.
argp 到底从堆栈中拿多少参数,由format 中的内容%个数来决定.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值