酷壳: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});
|
分享到:
相关推荐
- **变长参数列表**:函数可以接受不定数量的参数。 - **格式化输入:scanf**:使用`scanf`函数输入格式化数据。 - **文件访问**:文件的打开、关闭、读写操作。 - **错误处理:stderr与exit**:错误信息输出与...
- **变参**: 允许使用不定数量的参数。 - **返回值**: 函数可以返回一个或多个值。 - **匿名函数**: 匿名函数没有函数名,可以直接调用或者赋值给变量。 - **延迟调用**: 使用`defer`关键字在函数即将返回之前执行...
有些函数允许用户传递不定数量的参数。这部分内容介绍了如何定义和使用接受可变参数列表的函数。 #### 输入输出库 C语言的标准输入输出库提供了一系列用于文件和控制台I/O操作的函数。这部分内容详细介绍了这些...
- **可变参数**:函数可以接受不定数量的参数。 **25. C标准库** - **标准库函数**:C语言标准库提供的各种函数,如stdio.h中的输入输出函数等。 **26. 链表** - **链表的概念**:链表的基本概念和特点。 - **链表...
### C编程技巧总结 #### 指针与数组相关概念 - **指针与数组的基本概念**:在C语言中,指针与数组是极为重要的概念。数组是一种基本的数据结构,用于存储相同类型的数据集合。指针则是一种特殊的变量,其值为另一...
- **定义**: 可变参数列表允许函数接受数量不定的参数。 - **实现**: - 使用`<stdarg.h>`头文件中的宏`va_list`、`va_start`、`va_end`和`va_arg`来处理可变参数列表。 - **示例**: 实现一个可以接受任意数量整数...
这些函数允许用户传递不定数量的参数。使用`<stdarg.h>`库可以实现这类函数。 ### 8. C程序内存中组成部分 - **代码段**:存放程序的机器指令。 - **数据段**:存放全局变量和静态变量。 - **堆**:动态分配内存。 ...
- **结构体的概念与用途:** 结构体是一种用户自定义的数据类型,它允许将不同类型的数据组合成单个实体。在嵌入式系统编程中,特别是在网络协议、通信控制等方面,结构体的应用尤为广泛。 - **结构体的设计原则:**...
2. **配置串口参数**:使用 `struct termios` 结构体来设置波特率、数据位、停止位、校验位等。调用 `tcgetattr()` 获取当前设置,然后使用 `cfsetispeed()` 和 `cfsetospeed()` 设置输入和输出波特率,例如: ```c ...
具体做法是通过使用`va_list`类型变量和宏`va_start`, `va_arg`, `va_end`来处理不定数量的参数。例如: ```c #include #include void print_int(int i, ...) { va_list args; va_start(args, i); printf(...
此外,学习如何使用`void`指针和`stdarg.h`库进行不定参数函数的编写也是高级主题。 5. **位运算**:C语言提供了丰富的位运算符,如按位与、或、非、异或和位移,它们在处理硬件接口、数据编码或优化算法时非常有用...
在C语言中,某些函数允许传入不定数量的参数,例如 `printf()`。这种情况下,函数的原型会使用省略号(`...`)来表示可变参数列表。为了处理这些参数,C语言提供了 `<stdarg.h>` 头文件,其中定义了一系列宏和函数,...
22. **可变参数**:允许函数接受不定数量的参数,这些参数会被收集到一个数组中。 23. **范围运算符**:`..表示左闭右开区间,`...`表示左闭右闭区间。 24. **AnyClass与.self**:`AnyClass`可以表示任何类类型,`...
C/C++ 支持可变参数函数,即函数可以接受数量不定的参数。这种特性在某些情况下非常有用,例如实现日志记录功能。 - **标准库函数**:`printf` 和 `va_list` 等函数和类型为处理可变参数提供了支持。 - **实现方法*...