Do you know ? 函数的参数数目可变化大小!!!

可变参数列别解析

前言很多朋友都不清楚c语言中关于函数还有一个很有意思的东西——“可变参数列表”。那么本主今天就借助模拟实现printf()函数的例子给大家说道说道关于“函数可变参数列表”的事情!

例码:print()函数

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

void display(int n)//打印n的每一位,例如:n = 123 将打印出 1 2 3
{
    if (n > 9)
    {
        display(n/10);
    }
    putchar((n % 10) + '0');
}

void print(char *format, ...)
{
    va_list arg;
    va_start(arg, format);
    char tmp;
    while ((tmp = *format ) != '\0')
    {
        format++;
        switch (tmp)
        {
        case 's'://如果字符串内字符为 'S',将执行字符串打印工作
                {
                    char *ret = va_arg(arg, char *);
                    while (*ret != '\0')//字符串打印工作
                    {
                        putchar(*ret);
                        ret++;
                    }
                }
            break;
        case 'c'://如果字符串内字符为 'C',将执行字符打印工作
                {
                    char ret = va_arg(arg, char);
                    putchar(ret);//字符打印工作
                }
            break;
        case 'd'://如果字符串内字符为 'd',将执行整形数值(十进制)打印工作
                {
                    int ret = va_arg(arg, int);
                    display(ret); //执行整形数值(十进制)打印工作
                }
            break;
        default:
            putchar(tmp);//否则,原样输出
            break;
        }
    }
}

int main()
{
    print("s ccc d%.\n", "hello", 'b', 'i', 't',100);
    return 0;
}

说明:

  • 我们必须要清楚函数调用时形参实例化的过程,参数是“从右向左”依次入栈的。如下图:
    这里写图片描述
  • void print(char *format, ...)参数列表后面的“ …”表示参数个数不固定。
  • 可变参数必须从头到尾依次访问,不可跳转访问,当然,如果你在访问几个参数后不想继续访问后边的参数也是可以的。
  • 可变参数列表前面必须至少有一个命名参数,否则,将不能使用va_start进行初始化。
  • 函数实现中使用的va_*系列宏无法直接判断可变参数个数、每个参数类型。
  • 在使用va_arg时,如果指定了错误的类型,那么后果将非常严重“一步失足,满盘皆输”。

正文:

调用print("s ccc d%.\n", "hello", 'b', 'i', 't',100);参数实例化过程如下图:

这里写图片描述

详解:_INTSIZEOF(n)

这里写图片描述

详解:va_*系列宏

这里写图片描述

详解:print()函数

这里写图片描述

总结:

  • 函数的可变参数列表的实现是借助参数“命名参数部分”的最后一个命名参数的地址偏移进而找到“可变参数部分第一个参数的地址”进而往后访问其它可变参数部分。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值