函数的可变参数传参

一.前言

可变参数传参是C语言的一种高级用法。


二. 用法示例

求任意个 int 类型数据的平均值。

点击查看代码
double avg_int(int count, ...)
{
    va_list ap;                   /* 2. 声明参数列表变量 */
    int sum = 0;

    va_start(ap, count);          /* 3. 用最后一个固定参数初始化 */
    for (int i = 0; i < count; ++i)
        sum += va_arg(ap, int);   /* 4. 逐个取 int 数据累加 */
    va_end(ap);                   /* 5. 清理 */

    return count ? (double)sum / count : 0.0;
}

三.参数布局

若调用函数avg_int(3, 10, 20, 30),在x86-64 System V ABI(Linux/macOS 64 位)典型布局(简化):

高地址
+-----------+
| 30 | <-- 第四个实参
+-----------+
| 20 | <-- 第三个实参
+-----------+
| 10 | <-- 第二个实参
+-----------+
| 3 | <-- 第一个实参(count)
+-----------+
| ret addr |
低地址

三个宏的真身(简化版,glibc 实现)

点击查看代码
typedef char *va_list;              /* 只是字节指针 */

#define va_start(ap, last)          \
    ((ap) = (char *)&(last) + sizeof(last))

#define va_arg(ap, type)            \
    (*(type *)((ap) += sizeof(type), (ap) - sizeof(type)))

#define va_end(ap)                  \
    ((ap) = (char *)0)
被调用函数看到的栈/寄存器里,这些值连续排布,顺序与实参顺序一致。
posted @ 2025-11-07 22:03  Charles_hui  阅读(4)  评论(0)    收藏  举报