研究va_list

测试代码

#include <stdarg.h>
#include <stdio.h>
void s(const char* str1, const char* str2, ...)
{
    va_list va_list_;
    va_start(va_list_, str1);
    const char* p1 = va_arg(va_list_, const char*);
    printf("p1 : [%p] [%s]\n", p1, p1);
    const char* p2 = va_arg(va_list_, const char*);
    printf("p2 : [%p] [%s]\n", p2, p2);
    const char* p3 = va_arg(va_list_, const char*);
    printf("p3 : [%p] [%s]\n", p3, p3);
    const char* p4 = va_arg(va_list_, const char*);
    printf("p4 : [%p] [%s]\n", p4, p4);
    const char* p5 = va_arg(va_list_, const char*);
    printf("p5 : [%p] [%s]\n", p5, p5);
    const char* p6 = va_arg(va_list_, const char*);
    printf("p6 : [%p] [%s]\n", p6, p6);
    //const char* p7 = va_arg(va_list_, const char*);
    //printf("p7 : [%p] [%s]\n", p7, p7);
    //const char* p8 = va_arg(va_list_, const char*);
    //printf("p8 : [%p] [%s]\n", p8, p8);
    //const char* p9 = va_arg(va_list_, const char*);
    //printf("p9 : [%p] [%s]\n", p9, p9);
    //const char* p10 = va_arg(va_list_, const char*);
    //printf("p10 : [%p] [%s]\n", p10, p10);
    va_end(va_list_);
}
int main()
{
    s("11", "22", "33", "44", "55");
    return 0;
}

windows下运行打印结果

p1 : [00076BA4] [22]
p2 : [00076BA0] [33]
p3 : [00076B9C] [44]
p4 : [00076B98] [55]
p5 : [0007104B] [闋]
p6 : [0007104B] [闋]

可以看到,如果使用str1作为va_start的参数,那么第一次调用va_arg返回的指针,指向的是str2。多次调用va_arg后,返回的指针的地址间隔为4,并且是从高地址向低地址排列,依此指向所传递的字符串。

p1 : [00BA6B68] [33]
p2 : [00BA6B54] [44]
p3 : [00BA6B40] [55]
p4 : [00BA104B] [闋]
p5 : [00BA104B] [闋]
p6 : [0060A000] []

如果使用str2作为va_start的参数,那么第一次调用va_arg返回的指针,指向的是“33”。多次调用va_arg后,返回的指针的地址间隔是20

linux下运行打印结果(为了研究指针偏移量更改了字符串字符数)

p1 : [0x400ba3] [33333333]
p2 : [0x400b9a] [44444444]
p3 : [0x400b91] [55555555]
p4 : [(nil)] [(null)]
p5 : [(nil)] [(null)]
p6 : [0x7f332ccb7555] [����w]

相同点

va_arg执行多次后,windows与linux下程序都会崩溃。

va_arg返回的指针的地址都是从高向低排列。

不同点

va_start的第二个参数。

windows,va_start通过第二个参数指定起始的字符串后,后面调用va_arg时是获取到的下一个参数。

linux,va_start通过第二个参数指定起始的字符串后,后面调用va_arg时获取到的参数跟va_start里面指定的无关,获取到的一定是...表示的参数里的第一个参数。

va_arg返回的指针的偏移

windows,指针的偏移是固定的,这个是操作系统决定的。

linux,指针的偏移是跟传递的字符串参数相关的,偏移的大小是字符串字符数+1。

va_arg遍历参数结束时返回的指针

windows,遍历可变参数表结束后返回的头两个指针不是空,但地址相同。

linux,遍历可变参数表结束后返回的头两个指针都是空。

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值