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

相关推荐
陌路201 小时前
C语言基础入门阶段
c语言
胖咕噜的稞达鸭1 小时前
二叉树搜索树插入,查找,删除,Key/Value二叉搜索树场景应用+源码实现
c语言·数据结构·c++·算法·gitee
清风wxy2 小时前
C语言基础数组作业(冒泡算法)
c语言·开发语言·数据结构·c++·windows·算法
仲星(._.)2 小时前
C语言:自定义类型
c语言·开发语言
懒羊羊不懒@3 小时前
算法入门数学基础
c语言·数据结构·学习·算法
Aurorar0rua3 小时前
C Primer Plus 11.12 复习题
c语言·开发语言
坚持编程的菜鸟5 小时前
LeetCode每日一题——矩阵置0
c语言·算法·leetcode·矩阵
坚持编程的菜鸟11 小时前
LeetCode每日一题——困于环中的机器人
c语言·算法·leetcode·机器人
Aurorar0rua12 小时前
C Primer Plus Notes 09
java·c语言·算法
我是华为OD~HR~栗栗呀16 小时前
华为od-21届考研-C++面经
java·c语言·c++·python·华为od·华为·面试