zoukankan      html  css  js  c++  java
  • C++:可变参数函数

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

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

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

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

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

    主要用到该头文件中的 三个 宏  和 一个类型 , 分别是 :   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(指向参数列表的指针  ,  第一个参数  )

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

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

     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("%d\n",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

  • 相关阅读:
    解决 minwidth 在 IE6 中无效的方法
    SmallSlider 图片轮播插件
    css li中a的高端与li的高端不一致,解决方案
    为什么height:5px在IE6里显示不正常?
    命令提示符下不能输入中文
    Sql中日期差 Sql中 DateDiff Sql 中时间差
    20100420 18:17 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state\Parameters
    多个表结果的并列显示
    linux系统下载地址
    VMware中Shared Folders(共享文件夹)的配置
  • 原文地址:https://www.cnblogs.com/wowk/p/3127653.html
Copyright © 2011-2022 走看看