C和C++中的可变参数(上)

简介: C和C++中的可变参数(上)

一、缘由

之前一直有见识过可变参数,但是没有机会使用,也没理解其背后的机制,今天不如写篇博客,研究研究~

二、情景作业

老师布置作业:
写一个程序:要求得到平均数,且用户可以输入任意数量的参数 要解决该问题有两个难点
下面几位同学的做法:

2.1 二傻小憨

疯狂地枚举出各种情况,从用户输入1个参数到用户输入100个参数

float average(int a)
{
   
return a;
}
float average(int a,int b)
{
   
return (a+b)/2;
}
...........

float average(int a,int b,int c......,int n)
{
   
return (a+b+c+......n)/2;
}

最终得分:0

2.2 机智源源

#include<stdarg.h>
#include <cstdarg>
#include<iostream>
using namespace std;
float average(int n_values, ...)
{
   
    va_list arg;
    int count;
    float sum = 0;
    /*准备访问可变参数*/
    va_start(arg, n_values);
    /*添加取自可变参数列表的值*/
    for (count = 0; count < n_values; ++count)
    {
   
        sum = sum + va_arg(arg, int);
    }
    /*完成可变参*/
    va_end(arg);
    return sum / n_values;
}
int main(int n, char**)
{
   
    cout << "平均值是:" <<average(4,10,90,20,80)<< endl;
    return 0;
}

得分:100

三、讲解作业

3.1 stdarg

通过此宏可以实现可变参,包含头文件:stdarg .h中,它是标准库的一部分。该头文件包括一个类型三个宏这几个宏配合使用,访问参数的值。

类型:
va_list
宏:
va_start、va_arg、va_end

3.1 省略号...

省略号:...中,它提示此处可能传递数量和类型未确定的参数。在编写这个函数的原型时,也要使用相同的记法。

3.2 va_listva_start

函数声明了一个类型为va_list名叫 arg的变量,它用于访问参数列表的未确定部分。这个变量通过调用var_start来初始化。初始化过程把arg变量设置为指向可变参数部分的第1个参数。

var_start([va_list类型的名字],[省略号前最后一个有名字的参数])

3.3 va_arg宏、va_end

为了访问参数,需要使用va_arg,这个宏接受两个参数:

va_arg([va_list类型参数],参数列表中下一个参数)

当访问完毕最后一个可变参数之后,我们需要调用va_end

注意🎈:在这个例子中,所有的可变参数都是整型。在有些函数中,你可能要通过前面获得的数据来判断下一个参数的类型2。va arg返回这个参数的值,并使 var arg 指向下一个可变参数。
## 3.4 __VA_ARGS__
cpp #define debug(...) print(cout,__VA_ARGS__) #define debug2(os, ...) print(os, __VA_ARGS__) //#define debug2(format, args...) print(format, ##args)//win32不支持 debug2(cout,"this ", " year");//"this year"
# 四、总结
| 用法总结|
|:--|
| va_list ptr: 定义一个指向可变参数列表的指针
va_start(ptr,a):初始化指针,其中第二个参数为函数可变参数列表之前的固定参数
va_arg(ptr,int):取出指针指向的元素,第二个参数为元素的类型,返回值为取出的元素,同时指针后移。
va_end(ptr): 还原 ptr指针 |

# 五、可变参数的限制
注意: 可变参数必须从头到尾按照顺序逐个访问。
如果你在访问了几个可变参数后想半途中止,这是可以的。但是,如果你想一开始就访问参数列表中间的参数,那是不行的。
由于表中的可变参数部分并没有原型,所以,所有作为可变参数传递给函数的值都将执行缺省参数类型提升。
相关文章
|
4月前
|
安全 JavaScript Java
C++11:可变参数模板
C++11:可变参数模板
|
5月前
|
存储 C++
【C++】可变参数模板使用总结(简洁易懂,详细,含代码演示)
【C++】可变参数模板使用总结(简洁易懂,详细,含代码演示)
|
5月前
|
存储 编译器 C语言
【C++11特性篇】模板的新一力将:可变参数模板 [全解析]
【C++11特性篇】模板的新一力将:可变参数模板 [全解析]
|
8月前
|
编译器 C++
【c++11】新的类功能和可变参数包
【c++11】新的类功能和可变参数包
|
7月前
|
机器学习/深度学习 编译器 C++
C++11:类的新功能和可变参数模板
C++11:类的新功能和可变参数模板
53 1
|
2月前
|
存储 安全 C语言
C++中灵活 处理可变参数的多种方式:优缺点、应用场景及示例对比
C++中灵活 处理可变参数的多种方式:优缺点、应用场景及示例对比
75 1
|
2月前
|
存储 安全 C++
【C++ 泛型编程 高级篇】C++可变参数模板探索:编程技巧与实战应用
【C++ 泛型编程 高级篇】C++可变参数模板探索:编程技巧与实战应用
54 0
|
2月前
|
存储 安全 C语言
不只是printf:探究C/C++语言中的可变参数函数
不只是printf:探究C/C++语言中的可变参数函数
27 0
|
2月前
|
安全 编译器 程序员
【C++ 泛型编程 进阶篇】C++ 可变参数模板的妙用:解决参数不足问题
【C++ 泛型编程 进阶篇】C++ 可变参数模板的妙用:解决参数不足问题
34 0
|
2月前
|
编译器 C语言 C++
【C++】—— C++11之可变参数模板
【C++】—— C++11之可变参数模板