`

可变参数宏, Variadic Macros

阅读更多

可变参数宏, 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语言可变参数及printf函数的实现

    在C语言编程中,虽然可变参数(variadic functions)在自定义接口中较少应用,但作为核心功能之一,它在标准库函数如`printf`中扮演着关键角色。本文将深入探讨C语言中可变参数的工作原理及其在`printf`函数中的实现...

    variyak:宏以使用容器中的数据来调用可变参数函数

    瓦里亚克 此板条箱提供了一个宏call_variadic ,可用于构造样板代码,以使用容器(例如Vec)中的数据来调用可变参数函数。 例子: #![feature(c_variadic)]use variyak :: call_variadic;fn main () { let data = ...

    iphone开发实例 04-Variadic Arguments

    在iOS开发中,Variadic Arguments(可变参数)是一种允许函数接受不同数量参数的技术。它在C、C++和Objective-C等语言中被广泛使用,包括iPhone应用开发。本实例将深入探讨如何在Objective-C中使用Variadic ...

    CC++变长参数用法

    在C/C++编程语言中,变长参数列表(variadic function)是指函数能够接受可变数量的参数。这种灵活性使得开发人员能够在不确定参数个数的情况下定义函数,这对于创建诸如日志记录、错误报告等功能非常有用。 #### ...

    不定参数函数2.pdf

    C++中的可变参数模板(Variadic Templates)提供了另一种表达不定参数的方式,它更加类型安全,并且可以进行复杂的类型操作。 C++11标准中引入的可变参数模板是处理不定数量参数的新方式,它允许我们定义接受任意...

    PHP5.6新增加的可变函数参数用法分析

    在PHP的版本迭代中,PHP5.6引入了一个重要的特性,即可变函数参数(Variable-length argument lists),也称为 variadic functions。这个功能允许开发者在定义函数时不确定参数的数量,使得函数可以接受任意数量的...

    GCC核心扩展.doc

    4. **可变参数宏(Variable Argument Macros)** 在GCC中,宏不仅可以有固定数量的参数,还可以接受可变数量的参数,就像函数的varargs特性。例如,pr_debug宏使用了 variadic macro,可以接收任意数量的参数。宏...

    C++可变参数的函数与模板实例分析

    C++中的可变参数函数和模板是编程中非常灵活且强大的特性,允许我们编写能够处理任意数量和类型参数的函数。这些技术使得代码更具通用性和可扩展性。 首先,我们来了解一下`initializer_list`。`initializer_list`...

    VariadicExtension::beer_mug:扩展为Behat步骤定义添加了可变参数支持

    可变参数扩展 为Behat步骤定义增加了可变参数支持。 用法 安装它: $ composer require friends-of-behat/variadic-extension --dev 在您的Behat配置中启用它: # behat.yml default : # ... extensions : ...

    c语言宏使用

    在C99标准中引入了变参宏,允许宏接收可变数量的参数。例如,下面定义了一个名为`myprintf`的宏,它可以接受任意数量的参数: ```c #define myprintf(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__) ``` 这里`__VA_...

    Access-variable-argument-lists-demo.rar_ARGUMENT!

    3. **va_arg**: 这个宏用来从可变参数列表中获取参数。每次调用`va_arg`时,它会返回列表中的下一个参数,并假设它是指定的类型。例如,如果你期望下一个参数是`int`类型,你可以这样写: ```c int param = va_arg...

    C程序PPT课件2谭浩强

    5. 可变参数宏:介绍如何使用 variadic macros(如printf函数)处理可变数量的参数。 这套课件通过丰富的实例和详细的讲解,帮助学生深入理解C语言中的数组、函数、循环和预处理等重要概念,为编程实践打下坚实基础...

    va_arg_c_

    在C语言中,`va_arg`是一个非常重要的函数宏,它是可变参数列表(Variable Argument List,也称为 variadic function)处理的关键组成部分。标题“va_arg_c_”可能指的是一个文档,专门探讨了如何在C语言中使用`va_...

    C++编程惯用法——高级程序员常用方法和技巧

    13. **C++11/14/17/20新特性**:包括类型推断(auto)、变长参数模板(Variadic Templates)、并发编程支持(std::thread)、可变参数宏(Variadic Macros)等,这些都是C++不断演进和增强的表现。 14. **内存管理*...

    C/C++ 宏详细解析

    变参宏(Variadic Macros)允许接收可变数量的参数,如`#define LOG(format, ...) printf(format, __VA_ARGS__)`,`__VA_ARGS__`会自动替换为传递给宏的实际参数列表。这样,`LOG("%s %d", str, count)`就能按需打印...

    Swift心得笔记之函数

    可变参数(Variadic Parameters)允许函数接收任意数量的参数。它们通常用三个点 `...` 表示。例如,实现一个计算整数之和的函数: ```swift func sum(numbers: Int...) -&gt; Int { var total = 0 for number in ...

    va_args_count:使用AC宏在C99 __VA_ARGS__宏中查找参数的数量

    当在其他可变参数宏中使用VA_ARGS_COUNT()宏时,它确实发光。 您可能有一个函数,需要使用可变数量的参数,如下所示: void print_strings(int count, const char *s1, ...); 其中第一个参数count指定传递给该...

    cpp代码-C和C++奇怪内容 ## # __VA_ARGS__和... (可变参数) 宽字符

    在C和C++编程语言中,`##`、`#`和`__VA_ARGS__`是预处理器宏的重要组成部分,而`...`则涉及到可变参数模板或函数。这些特性在编写灵活、高效的代码时非常有用,特别是处理元编程、日志记录、配置文件解析等场景。...

    C++中可以接受任意多个参数的函数定义方法(详解)

    这可以通过函数模板和参数展开实现,通常称为可变参数模板(Variadic Templates)。下面将详细讲解如何在C++中定义这样的函数。 首先,让我们理解可变参数模板的概念。可变参数模板是一种特殊的模板,它允许函数或...

    GCC的51项扩充(编译器扩展语法标准)

    14. **Variadic Macros**:可变参数宏,允许宏接收数量可变的参数。 15. **Escaped Newlines**:宽松的换行规则,允许在某些情况下跨行书写表达式。 16. **Subscripting**:任何数组都可以被下标,即使它不是一个...

Global site tag (gtag.js) - Google Analytics