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'表示,空白字符串使用双引号表示 ""

相关推荐
小+不通文墨1 小时前
--no-multibyte-chars 解决OLED_data.c移植后中文乱码问题
c语言·经验分享·笔记·学习
q27551300422 小时前
AS717 Type-C转DP 8K方案外维少 AS717电路图
c语言·开发语言
自然常数e3 小时前
顺序表专题
c语言·数据结构·visual studio
j7~3 小时前
【数据结构初阶】队列的实现(链式队列 + 循环队列)--详解
c语言·开发语言·数据结构·学习·队列·queue·c\c++
草莓熊Lotso3 小时前
【Linux网络】深入理解Linux IO多路复用:select服务器完善、内核原理与poll实战
linux·运维·服务器·c语言·网络·c++
king_linlin4 小时前
算法基础——算法复杂度
c语言·开发语言·数据结构·算法
xxwxx__4 小时前
51单片机电机控制全攻略:直流电机、舵机与步进电机
c语言·单片机·嵌入式硬件·51单片机
king_linlin5 小时前
数据结构——顺序表(附图文讲解|超详细)
c语言·数据结构·算法
2601_9545267514 小时前
【工业传感与算法实战】温漂补偿与零点抗漂破局:基于二阶多项式拟合的 C/C++ 边缘校准算法,深度拆解“压力变送器什么牌子好”的技术硬指标
c语言·c++·算法
qq_4480111615 小时前
C语言中的变量和函数的定义与声明
android·c语言·开发语言