C语言之“可变参数与<stdarg.h>头文件”

目录

序列文章

前言

stdarg.h头文件

实例:遍历并求和所有传递给sum函数的额外实际参数


序列文章

<C语言错误处理> <errno.h>头文件与<error.h>头文件:http://t.csdnimg.cn/T1swf

<C语言错误处理> strerror和perror函数以及断言处理方式:http://t.csdnimg.cn/87bt6

<C语言错误处理> <signal.h>头文件及signal函数等内置函数:http://t.csdnimg.cn/RWl4l

<C语言错误处理> 非局部跳转<setjmp.h>头文件:http://t.csdnimg.cn/LpFDZ

<你想看的我这里都有😎 > 

前言

        有时我们会希望函数带有可变数量的参数就像printf(cosnt char* format ...)和scanf(cosnt char* format ...)那样除了有一个参数 format 固定以外,后面的参数其个数和类型都是可变的,用三个点“…”作为参数占位符,而不是预定义(固定)数量的参数......

stdarg.h头文件

概念:我们可以利用C语言中<stdarg.h>头文件提供给我们的工具来编写带有变长参数列表的函数,stdarg.h头文件声明了一种va_list类型并定义了三个宏va_start(ap,v) 、va_arg(ap, type)、va_end(ap) 

关于va_list类型的解释:一个用于存储可变参数信息的类型。在使用可变参数之前,需要先声明一个 va_list 类型变量来保存参数列表

关于va_start(ap,v) 宏的解释:该宏用于初始化 va_list类型的变量,并将其与第一个有准确命名的参数关联起来(通过地址实现,类似于数组的形式),这样可以在后续代码中逐个访问每个可变参数

关于va_arg(ap, type) 宏的解释:该宏用于从已初始化的 va_list 类型的变量中获取下一个可变参数,并指定其期望的类型。通过多次调用此宏可以逐步遍历所有传递给函数或宏作为额外实际参数(而不是具名形式) 的所有额外实际值

关于va_end(ap) 宏的解释:该宏负责清理并释放由 va_start()宏初始化的资源。通常,在使用完所有可变数量的实参之后应调用此宏以确保正确结束处理过程

关于宏的具体定义如下,但为了方便理解不做过多解释,只需要知道大概的使用方式即可:

typedef char * va_list;
 
// 把 n 圆整到 sizeof(int) 的倍数
#define _INTSIZEOF(n)       ( (sizeof(n)+sizeof(int)-1) & ~(sizeof(int)-1) )
 
// 初始化 ap 指针,使其指向第一个可变参数。v 是变参列表的前一个参数
#define va_start(ap,v)      ( ap = (va_list)&v + _INTSIZEOF(v) )
 
// 该宏返回当前变参值,并使 ap 指向列表中的下个变参
#define va_arg(ap, type)    ( *(type *)((ap += _INTSIZEOF(type)) - _INTSIZEOF(type)) )
 
// /将指针 ap 置为无效,结束变参的获取
#define va_end(ap)             ( ap = (va_list)0 )typedef char * va_list;
 

注意事项:

1、C99中增加了一个宏va_copy

2、ap 是一个 va_list 类型的变量

3、type 是参数的类型

具体使用步骤:

  • 定义一个函数,第一个参数是指定类型,后续参数用省略号代替
  • 在函数定义中创建一个 va_list 类型变量
  • 使用第一个参数和 va_start() 宏初始化 va_list类型的变量为一个参数列表
  • 使用 va_arg() 宏和 va_list 变量来访问参数列表中的每个项
  • 使用宏 va_end() 来清理赋予 va_list 类型变量的内存

实例:遍历并求和所有传递给sum函数的额外实际参数

#include <stdio.h>
#include <stdarg.h>

int sum(int count, ...) {
    int total = 0;
    va_list args;

    va_start(args, count);

    for (int i = 0; i < count; i++) {
        int num = va_arg(args, int);
        total += num;
    }

    va_end(args);

    return total;
}

int main() {
    int result = sum(4, 10, 20, 30, 40);
    printf("Sum: %d\n", result);

    return 0;
}

~over~

  • 35
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值