2025.4.22_C_可变参数列表

1.使用方法

cpp 复制代码
int func_name(int arg1, ...);

2.原理

在c语言中,函数的形参都是按照顺序存储在一个连续空间中的,如以下的代码:

cpp 复制代码
void Myprintf(int a,...)
{
	printf("&a = %p , a = %d\n", &a , a);
	printf("&a+1 = %p ,*(a+1) = %d\n", &a+1, *(&a + 1));
	printf("&a+2 = %p ,*(a+2) = %d\n", &a+2, *(&a + 2));
}


int main()
{
	Myprintf(10, 20 ,30);
}

它的运行结果为:

由此可以得出:实参10,20,30对应的形参在函数Myprintf中是按照地址从低到高存储的,也就是说,只要知道他们的类型,就能通过最后一个固定参数(这里指的是a)依次访问,那怎么判断是否访问了所有的形参呢?答案是通过固定参数传递可变参数的个数,然后再通过循环将指针向后移动不断访问数据。

3.stdarg.h

1.使用方法

  • 在函数定义中创建一个 va_list 类型变量,该类型是在 stdarg.h 头文件中定义的。
  • 使用 int 参数和 va_start() 宏来初始化 va_list 变量为一个参数列表。宏 va_start() 是在 stdarg.h 头文件中定义的。
  • 使用 va_arg() 宏和 va_list 变量来访问参数列表中的每个项。
  • 使用宏 va_end() 来清理赋予 va_list 变量的内存。

2.va_start

va_start(ap, last_arg):初始化可变参数列表。ap 是一个 va_list 类型的变量,last_arg 是最后一个固定参数的名称(这里是a)。该宏将 ap 指向可变参数列表中的第一个参数。

3.va_arg

va_arg(ap, type):获取可变参数列表中的下一个参数。ap 是一个 va_list 类型的变量,type 是下一个参数的类型。该宏返回类型为 type 的值,并将 ap 指向下一个参数。

4.va_end

va_end(ap):结束可变参数列表的访问。ap 是一个 va_list 类型的变量。该宏将 ap 置为 NULL

4.具体案例(求平均数)

cpp 复制代码
double average(int num,...)
{
 
    va_list valist;
    double sum = 0.0;
    int i;
 
    /* 为 num 个参数初始化 valist */
    va_start(valist, num);
 
    /* 访问所有赋给 valist 的参数 */
    for (i = 0; i < num; i++)
    {
       sum += va_arg(valist, int);
    }
    /* 清理为 valist 保留的内存 */
    va_end(valist);
 
    return sum/num;
}
相关推荐
海边的Kurisu1 小时前
苍穹外卖日记 | Day1 苍穹外卖概述、开发环境搭建、接口文档
java
C雨后彩虹4 小时前
任务最优调度
java·数据结构·算法·华为·面试
heartbeat..4 小时前
Spring AOP 全面详解(通俗易懂 + 核心知识点 + 完整案例)
java·数据库·spring·aop
Jing_jing_X4 小时前
AI分析不同阶层思维 二:Spring 的事务在什么情况下会失效?
java·spring·架构·提升·薪资
SmartRadio6 小时前
CH585M+MK8000、DW1000 (UWB)+W25Q16的低功耗室内定位设计
c语言·开发语言·uwb
少林码僧6 小时前
2.31 机器学习神器项目实战:如何在真实项目中应用XGBoost等算法
人工智能·python·算法·机器学习·ai·数据挖掘
钱彬 (Qian Bin)6 小时前
项目实践15—全球证件智能识别系统(切换为Qwen3-VL-8B-Instruct图文多模态大模型)
人工智能·算法·机器学习·多模态·全球证件识别
元Y亨H6 小时前
Nacos - 服务发现
java·微服务
微露清风6 小时前
系统性学习C++-第十八讲-封装红黑树实现myset与mymap
java·c++·学习
dasi02276 小时前
Java趣闻
java