可变参数宏, Variadic Macros
说起可变参数,立即想到的就是printf(),scanf()了.可变参数就是有一个固定的格式控制参数,后面再根据格式控制参数接若干参数.
这里先讨论可变参数宏.
我们一般在Debug需要打印调试信息的时候,需要可变参数的宏.
一, vc(C99)的复杂宏.
参考msdn(http://msdn2.microsoft.com/en-us/library/ms177415.aspx ).使用这种复杂宏时,省略号是格式控制参数,而标识符__VA_ARGS__用来插入另外的参数.__VA_ARGS__ 将"..." 传递给宏.
例如:
#include <stdio.h>
#define CHECK1(x, ...) if (!(x)) { printf(__VA_ARGS__); }
#define CHECK2(x, ...) if ((x)) { printf(__VA_ARGS__); }
#define CHECK3(...) { printf(__VA_ARGS__); }
int main( )
{
CHECK1(0, "here %s %s %s", "are", "some", "varargs1(1)\n");
CHECK1(1, "here %s %s %s", "are", "some", "varargs1(2)\n"); // won't print
CHECK2(0, "here %s %s %s", "are", "some", "varargs2(3)\n"); // won't print
CHECK2(1, "here %s %s %s", "are", "some", "varargs2(4)\n");
CHECK3("here %s %s %s", "are", "some", "varargs3(5)\n");
return 0;
}
输出为:
here are some varargs1(1)
here are some varargs2(4)
here are some varargs3(5)
二,GCC中的复杂宏
GCC支持C99中的复杂宏,但G++不支持.GCC使用一种不同的语法,给可变参数一个名字,如同其它参数一样.
#define CHECK1(x,format, args...) if(x) { printf (format, args); }
显然这样易于描述而且可读性更强.
三,CHECK("Some messges.")的情况
这时由于宏展开后有个多余的逗号,,将导致编译错误..为了解决这个问题,CPP使用一个特殊的“##”操作.
#define CHECK(format, ...) printf ( format, ## __VA_ARGS__)
这里,如果可变参数被忽略或为空,“##”操作将使预处理器去除掉它前面的那个逗号.如果在宏调用时,确实提供了一些可变参数,GNU CPP也会工作正常,它会把这些可变参数放到逗号的后面.
四,类似printf()的技巧
用一个被括弧括起来的 “参数”来定义和调用宏,参数在宏扩展的时候成为类似printf()函数中的格式控制字符串那样的参数列表.
#define CHECK(args) (printf("DEBUG: "), printf(args))
分享到:
相关推荐
在C语言编程中,虽然可变参数(variadic functions)在自定义接口中较少应用,但作为核心功能之一,它在标准库函数如`printf`中扮演着关键角色。本文将深入探讨C语言中可变参数的工作原理及其在`printf`函数中的实现...
瓦里亚克 此板条箱提供了一个宏call_variadic ,可用于构造样板代码,以使用容器(例如Vec)中的数据来调用可变参数函数。 例子: #![feature(c_variadic)]use variyak :: call_variadic;fn main () { let data = ...
在iOS开发中,Variadic Arguments(可变参数)是一种允许函数接受不同数量参数的技术。它在C、C++和Objective-C等语言中被广泛使用,包括iPhone应用开发。本实例将深入探讨如何在Objective-C中使用Variadic ...
在C/C++编程语言中,变长参数列表(variadic function)是指函数能够接受可变数量的参数。这种灵活性使得开发人员能够在不确定参数个数的情况下定义函数,这对于创建诸如日志记录、错误报告等功能非常有用。 #### ...
C++中的可变参数模板(Variadic Templates)提供了另一种表达不定参数的方式,它更加类型安全,并且可以进行复杂的类型操作。 C++11标准中引入的可变参数模板是处理不定数量参数的新方式,它允许我们定义接受任意...
在PHP的版本迭代中,PHP5.6引入了一个重要的特性,即可变函数参数(Variable-length argument lists),也称为 variadic functions。这个功能允许开发者在定义函数时不确定参数的数量,使得函数可以接受任意数量的...
4. **可变参数宏(Variable Argument Macros)** 在GCC中,宏不仅可以有固定数量的参数,还可以接受可变数量的参数,就像函数的varargs特性。例如,pr_debug宏使用了 variadic macro,可以接收任意数量的参数。宏...
C++中的可变参数函数和模板是编程中非常灵活且强大的特性,允许我们编写能够处理任意数量和类型参数的函数。这些技术使得代码更具通用性和可扩展性。 首先,我们来了解一下`initializer_list`。`initializer_list`...
可变参数扩展 为Behat步骤定义增加了可变参数支持。 用法 安装它: $ composer require friends-of-behat/variadic-extension --dev 在您的Behat配置中启用它: # behat.yml default : # ... extensions : ...
在C99标准中引入了变参宏,允许宏接收可变数量的参数。例如,下面定义了一个名为`myprintf`的宏,它可以接受任意数量的参数: ```c #define myprintf(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__) ``` 这里`__VA_...
3. **va_arg**: 这个宏用来从可变参数列表中获取参数。每次调用`va_arg`时,它会返回列表中的下一个参数,并假设它是指定的类型。例如,如果你期望下一个参数是`int`类型,你可以这样写: ```c int param = va_arg...
5. 可变参数宏:介绍如何使用 variadic macros(如printf函数)处理可变数量的参数。 这套课件通过丰富的实例和详细的讲解,帮助学生深入理解C语言中的数组、函数、循环和预处理等重要概念,为编程实践打下坚实基础...
在C语言中,`va_arg`是一个非常重要的函数宏,它是可变参数列表(Variable Argument List,也称为 variadic function)处理的关键组成部分。标题“va_arg_c_”可能指的是一个文档,专门探讨了如何在C语言中使用`va_...
13. **C++11/14/17/20新特性**:包括类型推断(auto)、变长参数模板(Variadic Templates)、并发编程支持(std::thread)、可变参数宏(Variadic Macros)等,这些都是C++不断演进和增强的表现。 14. **内存管理*...
变参宏(Variadic Macros)允许接收可变数量的参数,如`#define LOG(format, ...) printf(format, __VA_ARGS__)`,`__VA_ARGS__`会自动替换为传递给宏的实际参数列表。这样,`LOG("%s %d", str, count)`就能按需打印...
可变参数(Variadic Parameters)允许函数接收任意数量的参数。它们通常用三个点 `...` 表示。例如,实现一个计算整数之和的函数: ```swift func sum(numbers: Int...) -> Int { var total = 0 for number in ...
当在其他可变参数宏中使用VA_ARGS_COUNT()宏时,它确实发光。 您可能有一个函数,需要使用可变数量的参数,如下所示: void print_strings(int count, const char *s1, ...); 其中第一个参数count指定传递给该...
在C和C++编程语言中,`##`、`#`和`__VA_ARGS__`是预处理器宏的重要组成部分,而`...`则涉及到可变参数模板或函数。这些特性在编写灵活、高效的代码时非常有用,特别是处理元编程、日志记录、配置文件解析等场景。...
这可以通过函数模板和参数展开实现,通常称为可变参数模板(Variadic Templates)。下面将详细讲解如何在C++中定义这样的函数。 首先,让我们理解可变参数模板的概念。可变参数模板是一种特殊的模板,它允许函数或...
14. **Variadic Macros**:可变参数宏,允许宏接收数量可变的参数。 15. **Escaped Newlines**:宽松的换行规则,允许在某些情况下跨行书写表达式。 16. **Subscripting**:任何数组都可以被下标,即使它不是一个...