`
61party
  • 浏览: 1106726 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

C技巧:结构体参数转成不定参数

阅读更多

酷壳:http://coolshell.cn/articles/2801.html

下面这段程序是一个C语言的小技巧,其展示了如何把一个参数为结构体的函数转成一个可变参数的函数,其中用到了宏和内建宏“__VA_ARGS__”,下面这段程序可以在GCC下正常编译通过:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
#define func(...) myfunc((struct mystru){__VA_ARGS__})
struct mystru { const char *name; int number; };
void myfunc(struct mystru ms )
{
printf("%s: %d\n", ms.name ?: "untitled", ms.number);
}
int main(int argc, char **argv)
{
func("three", 3);
func("hello");
func(.name = "zero");
func(.number = argc, .name = "argc",);
func(.number = 42);
return 0;
}

从上面这段程序,我们可以看到一个叫 myfunc的函数,被func的宏改变了,本来myfunc需要的是一个叫mystru的结构,然而通过宏,我们把struct mystru的这个参数,变成了不定参数列表的一个函数。上面这段程序输出入下,

three: 3
hello: 0
zero: 0
argc: 1
untitled: 42

虽然,这样的用法并不好,但是你可以从另外一个方面了解一下这世上对C稀奇古怪的用法。 如果你把宏展开后,你就明的为什么了。下面是宏展开的样子:

1
2
3
4
5
myfunc((struct mystru){"three", 3});
myfunc((struct mystru){"hello"});
myfunc((struct mystru){.name = "zero"});
myfunc((struct mystru){.number = argc, .name = "argc",});
myfunc((struct mystru){.number = 42});

分享到:
评论

相关推荐

    书籍 Cprogramming language

    - **变长参数列表**:函数可以接受不定数量的参数。 - **格式化输入:scanf**:使用`scanf`函数输入格式化数据。 - **文件访问**:文件的打开、关闭、读写操作。 - **错误处理:stderr与exit**:错误信息输出与...

    嵌入式C精华.pdf

    结构体(struct)是C/C++语言中用于组织不同类型数据的有效工具,它允许开发者创建自定义的数据类型,将多个不同类型的变量组合成一个单元。在嵌入式系统和网络编程中,正确且巧妙地使用结构体可以显著提升代码的...

    go学习笔记

    - **变参**: 允许使用不定数量的参数。 - **返回值**: 函数可以返回一个或多个值。 - **匿名函数**: 匿名函数没有函数名,可以直接调用或者赋值给变量。 - **延迟调用**: 使用`defer`关键字在函数即将返回之前执行...

    Beej's guide to C programming

    有些函数允许用户传递不定数量的参数。这部分内容介绍了如何定义和使用接受可变参数列表的函数。 #### 输入输出库 C语言的标准输入输出库提供了一系列用于文件和控制台I/O操作的函数。这部分内容详细介绍了这些...

    宋劲杉--Linux C编程一站式学习2009.3.13版本——-免积分!!!

    - **可变参数**:函数可以接受不定数量的参数。 **25. C标准库** - **标准库函数**:C语言标准库提供的各种函数,如stdio.h中的输入输出函数等。 **26. 链表** - **链表的概念**:链表的基本概念和特点。 - **链表...

    C 总结-- C编程技巧

    ### C编程技巧总结 #### 指针与数组相关概念 - **指针与数组的基本概念**:在C语言中,指针与数组是极为重要的概念。数组是一种基本的数据结构,用于存储相同类型的数据集合。指针则是一种特殊的变量,其值为另一...

    嵌入式c语言精华

    - **定义**: 可变参数列表允许函数接受数量不定的参数。 - **实现**: - 使用`&lt;stdarg.h&gt;`头文件中的宏`va_list`、`va_start`、`va_end`和`va_arg`来处理可变参数列表。 - **示例**: 实现一个可以接受任意数量整数...

    免费下载:C语言难点分析整理.doc

    这些函数允许用户传递不定数量的参数。使用`&lt;stdarg.h&gt;`库可以实现这类函数。 ### 8. C程序内存中组成部分 - **代码段**:存放程序的机器指令。 - **数据段**:存放全局变量和静态变量。 - **堆**:动态分配内存。 ...

    嵌入式C_精华

    - **结构体的概念与用途:** 结构体是一种用户自定义的数据类型,它允许将不同类型的数据组合成单个实体。在嵌入式系统编程中,特别是在网络协议、通信控制等方面,结构体的应用尤为广泛。 - **结构体的设计原则:**...

    Linux C语言实现串口收发数据

    2. **配置串口参数**:使用 `struct termios` 结构体来设置波特率、数据位、停止位、校验位等。调用 `tcgetattr()` 获取当前设置,然后使用 `cfsetispeed()` 和 `cfsetospeed()` 设置输入和输出波特率,例如: ```c ...

    C语言 重载运算符和重载函数.pdf

    具体做法是通过使用`va_list`类型变量和宏`va_start`, `va_arg`, `va_end`来处理不定数量的参数。例如: ```c #include #include void print_int(int i, ...) { va_list args; va_start(args, i); printf(...

    C语言高级编程及实例部析[源代码]

    此外,学习如何使用`void`指针和`stdarg.h`库进行不定参数函数的编写也是高级主题。 5. **位运算**:C语言提供了丰富的位运算符,如按位与、或、非、异或和位移,它们在处理硬件接口、数据编码或优化算法时非常有用...

    优秀程序员之路——C开发经验及技巧大汇总.pdf

    在C语言中,某些函数允许传入不定数量的参数,例如 `printf()`。这种情况下,函数的原型会使用省略号(`...`)来表示可变参数列表。为了处理这些参数,C语言提供了 `&lt;stdarg.h&gt;` 头文件,其中定义了一系列宏和函数,...

    100个Swift必备Tips(第二版)1

    22. **可变参数**:允许函数接受不定数量的参数,这些参数会被收集到一个数组中。 23. **范围运算符**:`..表示左闭右开区间,`...`表示左闭右闭区间。 24. **AnyClass与.self**:`AnyClass`可以表示任何类类型,`...

    嵌入式C_C++语言精华.pdf

    C/C++ 支持可变参数函数,即函数可以接受数量不定的参数。这种特性在某些情况下非常有用,例如实现日志记录功能。 - **标准库函数**:`printf` 和 `va_list` 等函数和类型为处理可变参数提供了支持。 - **实现方法*...

Global site tag (gtag.js) - Google Analytics