C++:可变参数函数

可变参数 函数 的 定义也是从 C 继承过来的

对于可变参数函数来说 , 参数最少也要有 1 个 ,该参数作为第一个参数, 对于函数声明中已经列出的参数而言 , 其类型可以为任何类型

定义形式为 : type function( argument1 , ... );

例如 printf 的定义就是 int printf(const char* , ... );

实现可变参数的函数的时候 ,要包含的头文件 为 在C++中就是

主要用到该头文件中的 三个 宏 和 一个类型 , 分别是 : va_start() va_arg() va_end() 和 va_list 类型

va_list 类型用来定义指向参数列表的指针

va_start( va_list 参数列表类型的指针 , int 参数个数 ): 该宏用于 让 va_list 指向参数列表 , 并告知要取几个参数

va_arg(va_list ,类型名 type) : 该宏 返回 type 类型的 参数

va_end( va_list) : 结束获取参数列表只的参数

根据以上描述 , 写出一下的示例代码

1 #include<iostream>
 2 #include<string>
 3 #include<cstdarg>
 4 
 5 using    namespace    std;
 6 
 7 void    func(int i, ...)
 8 {    
 9     
10     int    index = 0;
11     va_list    arg_ptr;
12     va_start(arg_ptr ,i );
13     for(; index <  i ; index ++){
14         cout << va_arg(arg_ptr , int ) <<endl;
15     }
16     va_end(arg_ptr);
17 }
18 
19 int    main()
20 {
21     func(10,1,2,3,4,5,6,7,8,9,0);
22     return    0;
23 }

输出的结果如下

1

2

3

4

5

6

7

8

9

0

结果出来了 是正确无误的 , 那么现在就来看看 可变参数的原理 。

对于C++来说 , 调用函数的时候, 参数通常会被放在 空闲的寄存器中, 如果 没有空闲的 寄存器 , 参数就会 压到栈中 。

而对于可变参数的函数 , 编译器编译的时候不会指定 寄存器用来存放 参数 , 而是统一的使用栈 。

va_start(指向参数列表的指针 , 第一个参数 )

我们知道 , 在函数调用时参数压栈的顺序是 从右向左 依次压栈的 , 那么 第一个参数就是处在栈顶的位置 , 然而 , 在操作系统中

栈顶的位置是位于高地址的 , 栈是向低地址方向增长的 ,所以可知 , 第一个参数所在的地址为所有参数所在的地址中 最小的。

C++:可变参数函数

func(10,1,2,3,4,5,6); 在栈中的情况如上图所示

实际上 , 在可变参数函数被调用的时候 , 栈中所有的类型都按 4字节 边界对齐

下面看自己实现的获取可变参数列表的代码

1 #include<iostream>
 2 #include<string>
 3 #include<cstdarg>
 4 
 5 using    namespace    std;
 6 struct    abc{
 7     double    n1;
 8     char        n2;
 9     int        n3;
10     short        n4;
11     int        n5;
12 };
13 void    func(int i,...)
14 {    
15     char    *p = reinterpret_cast<char*>(&i);
16     for(int index = 0 ; index < 7 ; index++){
17         if(index == 3 ){
18             cout<< *reinterpret_cast<double*>(p) <<endl;
19             p += sizeof(double);
20         }else if(index == 5){
21             cout<< "结构体变量a" <<endl;
22             p += sizeof(struct abc);
23         }else{
24             cout<< *reinterpret_cast<int*>(p) <<endl;
25             p += sizeof(int);
26         }    
27     }
28 }
29 
30 int    main()
31 {
32     struct    abc   a = {1,2,3,4,5};
33     printf("%dn",sizeof(a));
34     func(10,(char)1,(short)2,3.14159,4,a,6);
35     return    0;
36 }

执行结果如下:

24

10

1

2

3.14159

4

结构体变量a

6

原文链接: https://www.cnblogs.com/wowk/archive/2013/06/08/3127653.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/91601

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月10日 上午1:15
下一篇 2023年2月10日 上午1:15

相关推荐