c语言中为函数输入可变长的参数

今天在《征服C指针》的书里面看到了一个很有意思的函数写法。即写一个输入的参数数量是可变的。

一个典型的可变输入函数就是printf(),该函数根据解析字符串中的%s, %d,%p等,就可以知道后面带有多少个参数。

但实际上,由于c语言数据的压栈方式,我们只需要知道第一个参数的位置,后续的参数就可以按顺序读取。也就是说我们要做的就是告诉函数,参数的起止,以及参数的格式,让函数能正确地读取参数。

ANSI C通过头文件stdarg.h提供了一组可用于可变参数的宏。代码如下。

c 复制代码
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>

void tiny_printf(char *format, ...)
{
    int i;
    va_list ap;

    va_start(ap, format);

    for(i = 0; format[i] != '\0'; i++)
    {
        switch (format[i])
        {
            case 's':
                /* code */
                printf("%s ", va_arg(ap, char*));
                break;
            case 'd':
                /* code */
                printf("%d ", va_arg(ap, int));
                break;
            
            default:
                assert(0);
        }
    }
    va_end(ap);
    putchar('\n');
}
int main(void)
{
    tiny_printf("ssdd", "hu", "cong", 6, 6);
    return 0;
}

注意到上述的代码,输入处的"..."代表着输入处不用进行参数的检查。

其中声明了va_list 类型的变量,可以看作某种指针,va_start(ap, format);代表将ap指向format后面的下一参数的位置,然后在循环中每次调用va_arg都会指向下一个参数,然后通过format中的指示,告诉我们第几个参数是哪种格式,就能正确地读取参数。比如上述代码中"ssdd"代表第一个和第二个是字符串,三个和第四个是整型。如此可依次取出所有参数。

va_end是对应于va_start的函数,在可变长参数的传递过程中,由va_start分配内存并将参数保存其中,最后由va_end释放内存。

输出结果如下:

复制代码
hu cong 6 6 

注意:代码中出现了许多单引号和双引号,很多时候他们并不能相互替换,因为其表示的含义不同。

'A' 表示单个字符大写字母A,占用1个字节空间

"A" 表示字符串,该字符串只有1个大写字母A组成,占用2个字节空间,每个字符串末尾自动会加上一个空字符 '\0'

空字符常量使用转义符号 '\0'表示,空白字符串使用双引号表示 ""

相关推荐
kkkkkkkkkk_Z12 分钟前
学嵌入式和C语言编程数据结构|学习日记Day21:内核链表与队列学习
c语言·数据结构·学习
不正经学生22 分钟前
C语言结构体:自定义数据类型,让变量打包出行
java·c语言·开发语言·数据结构·算法
老一岁32 分钟前
c问题总结(1)
c语言·开发语言
一木 之林1 小时前
三、内存管理、指针与堆栈
c语言·jvm·c++
笨笨饿1 小时前
#110_SCH3000 平台图传系统配置指南:从 DVP 摄像头到 UVC/WiFi 双通道传输
c语言·stm32·单片机·嵌入式硬件·物联网·vim
caimouse2 小时前
ReactOS 窗口系统分析(20):光标与图标 — cursoricon.c
c语言·开发语言
H_oRIZoN_2 小时前
Linux入门DAY23(C语言树形结构)
linux·c语言·数据结构
caimouse5 小时前
ReactOS 窗口系统分析(25):标题栏显示与系统按钮 — nonclient.c 标题栏专题
c语言·开发语言
caimouse6 小时前
ReactOS 窗口系统分析(14):计时器/属性/加速键/热键 — timer.c + prop.c + accelerator.c + hotkey.c
c语言·开发语言·reactos
水饺编程6 小时前
第5章,[Win32 章节] :贝塞尔样条曲线(一)
c语言·c++·windows·visual studio