美文网首页C语言程序员
C语言的可变参数宏实现默认参数

C语言的可变参数宏实现默认参数

作者: 黑熊小李 | 来源:发表于2022-10-27 00:12 被阅读0次

起因

最近,在回顾C语言知识的时候,突发奇想——C语言怎么实现可选参数呢?在一些面向对象语言中,我们在设置函数时使用函数的默认参数,帮助我们完成一些非必要参数的初始化。那么,在C语言中怎么实现这一方便的特性呢?


查找

在图书馆查阅专业书籍时,我发现了《C程序设计新思维》这边本书,在本书中的第十章 更好的结构中提到了ISO C99 标准中引入的3种语法:复合文字、可变参数宏、指定初始化值。之后,我在书中例 10-11 找出了我问题的最终答案。


分析

代码:

#include<stdio.h>

typedef struct{
    double pressure, moles, temp;
} ideal_struct;

#define ideal_pressure(...) ideal_pressure_base((ideal_struct){.pressure=1,         \
                                                .moles=1, .temp=273.15, __VA_ARGS__})

double ideal_pressure_base(ideal_struct in){
    return (8.314*in.moles*in.temp)/in.pressure;
}

int main(){
    double x;
    scanf("%lf",&x);
    printf("volume given defaults: %g\n", ideal_pressure());
    printf("volume given boiling temp: %g\n", ideal_pressure(.temp=373.15));
    printf("volume given two moles: %g\n", ideal_pressure(.moles=x));
    printf("volume given two boiling moles: %g\n", ideal_pressure(.moles=2, .temp=373.15));
}

解读:

因为一个函数的输入是参数固定的,而用户输入是可变的,显然C语言不允许我们直接使用可变参数。

  1. 我们可以先定义一个输入参数的结构体,把输入参数包装起来。
  2. 定义以这个结构体为输入参数的 func_base 函数接口,再通过可变参数宏来定义创建真正调用的 func 函数接口。
  3. 像使用可变参数函数一样,使用 func 函数,而 func_base 为普通C语言函数。两者都可以在代码中正常使用。

这个例子使用了ISO C99的以下两个特性:

  1. 可变参数宏:
    实际效果类似于简单替换,把 func(...) 中省略号部分中的部分与后面 VA_ARGS 位置会发生原封不动地替换,在省略号中书写的部分就等于在 VA_ARGS 书写。
  2. 复合文字:
    用 (){} 来对一个变量进行初始化。
    ()中书写变量类型。例:name_struct(结构体)、double[](浮点型数组)、 ...
    {}中书写对应类型的值。例:.temp=273.15, .moles=2, ... 、1.5, 5.6, 7.9874, ... 、...

因为在宏内部已经通过复合文字这一C99语法给输入参数结构体所有成员赋值过一次,所需参数已经齐全,可以通过用户输入2次赋值参数,对参数进行调整,后续调用赋值相当于对结构体某一变量的二次赋值编译器并不会报错(见结果图)。

结果:

Variable parameter macro.png

注意:

文章为本人在简书平台原创,盗用必究!

相关文章

  • C语言的可变参数宏实现默认参数

    起因 最近,在回顾C语言知识的时候,突发奇想——C语言怎么实现可选参数呢?在一些面向对象语言中,我们在设置函数时使...

  • 可变参数

    C语言的可变参数的实现非常巧妙:大师只用了 3 个宏就解决了这个难题。 一、可变参数的应用 这里实现一个简单的可变...

  • 可变参数

    参考C语言中可变参数的用法 如何实现像printf()一样的可变参数函数一般用到以下几个宏 va这里指variav...

  • C语言 函数的可变参数

    在C语言中想在函数中输入不定量的参数 可变参数列表使用过宏来使实现的,这些宏定于stdarg.h头文件。这个头文件...

  • 精解C语言预处理命令(三)之“宏”的用法二

    关于C语言带参数的宏定义中的参数 C语言允许宏带有参数。在宏定义中的参数称为“形式参数”,在宏调用中的参数称为“实...

  • C语言可变参数实现

    一.如果我自己来实现printf printf是可变参数的典型列子,他接受一个格式化字符串和不定数量的输出参数,函...

  • 软件安全-格式化字符串攻击

    探索C语言的可变长参数 C语言标准库中头文件stdarg.h索引的接口包含了一组能够遍历变长参数列表的宏。 主要包...

  • Lua可变参数

    Lua 函数可以接受可变数目的参数,和 C 语言类似,在函数参数列表中使用...表示函数有可变的参数。 把可变参数...

  • 函数的参数

    函数的参数顺序是 必选参数、默认参数、可变参数、关键字参数、命名关键字参数 必选参数 默认参数 可变参数 关键...

  • iOS开发:Debug与Release版本NSLog屏蔽方法

    简单介绍以下几个宏: 1) __VA_ARGS__ 是一个可变参数的宏,这个可变参数的宏是新的C99规范中新增的,...

网友评论

    本文标题:C语言的可变参数宏实现默认参数

    本文链接:https://www.haomeiwen.com/subject/uapttdtx.html