c语言中的# ## 可变参数宏 ...和_ _VA_ARGS_ _
1.#
假如希望在字符串中包含宏参数,ANSI C允许这样作,在类函数宏的替换部分,#符号用作一个预处理运算符,它可以把语言符号转化程字符串。例如,如果x是一个宏参量,那么#x可以把参数名转化成相应的字符串。该过程称为字符串化(stringizing).
#incldue <stdio.h>
#define PSQR(x) printf("the square of" #x "is %d.\n",(x)*(x))
int main(void)
{
int y =4;
PSQR(y);
PSQR(2+4);
return 0;
}
输出结果:
the square of y is 16.
the square of 2+4 is 36.
第一次调用宏时使用“y”代替#x;第二次调用时用“2+4"代#x。
2.##
##运算符可以用于类函数宏的替换部分。另外,##还可以用于类对象宏的替换部分。这个运算符把两个语言符号组合成单个语言符号。例如:
#define XNAME(n) x##n
这样宏调用:
XNAME(4)
展开后:
x4
程序:
#include <stdio.h>
#define XNAME(n) x##n
#define PXN(n) printf("x"#n" = %d\n",x##n)
int main(void)
{
int XNAME(1)=12;//int x1=12;
PXN(1);//printf("x1 = %d\n", x1);
return 0;
}
输出结果:
x1=12
3.可变参数宏 ...和_ _VA_ARGS_ _
__VA_ARGS__ 是一个可变参数的宏,很少人知道这个宏,这个可变参数的宏是新的C99规范中新增的,目前似乎只有gcc支持(VC6.0的编译器不支持)。
实现思想就是宏定义中参数列表的最后一个参数为省略号(也就是三个点)。这样预定义宏_ _VA_ARGS_ _就可以被用在替换部分中,替换省略号所代表的字符串。比如:
#define PR(...) printf(__VA_ARGS__)
int main()
{
int wt=1,sp=2;
PR("hello\n");
PR("weight = %d, shipping = %d",wt,sp);
return 0;
}
输出结果:
hello
weight = 1, shipping = 2
省略号只能代替最后面的宏参数。
#define W(x,...,y)错误!
c语言中的# ## 可变参数宏 ...和_ _VA_ARGS_ _的更多相关文章
- C语言中的可变参数-printf的实现原理
C语言中的可变参数-printf的实现原理 在C/C++中,对函数参数的扫描是从后向前的.C/C++的函数参数是通过压入堆栈的方式来给函数传参数的(堆栈是一种先进后出的数据结构),最先压入的参数最后出 ...
- GNU C和C99标准中的可变参数宏(variadic macros)
用可变参数宏(variadic macros)传递可变参数表你可能很熟悉在函数中使用可变参数表,如: void printf(const char* format, …); 直到最近,可变参数表还是只 ...
- C语言中函数可变参数解析
大多数时候,函数中形式参数的数目通常是确定的,在调用时要依次给出与形式参数对应的所有实际参数.但在某些情况下希望函数的参数个数可以根据需要确定.典型的例子有 大家熟悉的函数printf().scanf ...
- C语言中的可变参数函数的浅析(以Arm 程序中的printf()函数实现为例) .
我们在C语言编程中会遇到一些参数个数可变的函数,一般人对它的实现不理解.例如Printf(): Printf()函数是C语言中非常常用的一个典型的变参数函数,它 的原型为: int printf( c ...
- C语言中的可变参数函数
C语言编程中有时会遇到一些参数个数可变的函数,例如printf()函数,其函数原型为: int printf( const char* format, ...); 它除了有一个参数format固定以外 ...
- 各种语言中的可变参数(java、python、c++、javascript)
索引: java python c++ js 1.Java public class Animal { // 接受可变参数的方法 void eat(String... Objects) { for ( ...
- 嵌入式C语言自我修养 12:有一种宏,叫可变参数宏
12.1 什么是可变参数宏 在上面的教程中,我们学会了变参函数的定义和使用,基本套路就是使用 va_list.va_start.va_end 等宏,去解析那些可变参数列表我们找到这些参数的存储地址后, ...
- C函数和宏中的可变参数
一:调用惯例 函数的调用方和被调用方对函数如何调用应该有统一的理解,否则函数就无法正确调用.比如foo(int n, int m),调用方如果认为压栈顺序是m,n,而foo认为压栈顺序是n, m,那么 ...
- Swift语言中为外部参数设置默认值可变参数常量参数变量参数输入输出参数
Swift语言中为外部参数设置默认值可变参数常量参数变量参数输入输出参数 7.4.4 为外部参数设置默认值 开发者也可以对外部参数设置默认值.这时,调用的时候,也可以省略参数传递本文选自Swift1 ...
随机推荐
- Linux高端内存
Linux高端内存是针对物理内存来说的,虚拟内存没有高端这个概念.Linux系统将虚拟内存分为两个部分,即用户地 址空间和内核地址空间,对于32位系统来说,虚拟地址空间为4GB,其中用户空间范围为0- ...
- 如何设置快捷键(File Search)
window->preferences->General->keys. 找到File Search(有搜索框的,可以搜索),然后在下方 Binding按下ctrl +h .
- 压力测试工具ab,wrk,locust简介
ab 无疑是目前最常见的压力测试工具.其典型用法如下: shell> ab -k -c 100 -t 10 http://domain/path 其中,参数「c」表示的是并发, 参数「t」表示的 ...
- commons io上传文件
习惯了是用框架后,上传功能MVC框架基本都提供了.如struts2,springmvc! 可是假设项目中没有使用框架.而是单纯的使用jsp或servlet作为action,这时我们就能够使用commo ...
- 九度OJ 1141:Financial Management (财务管理) (平均数)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:939 解决:489 题目描述: Larry graduated this year and finally has a job. He's ...
- Java类加载器(死磕3)
[正文]Java类加载器( CLassLoader ) 死磕3: 揭秘 ClassLoader抽象基类 本小节目录 3.1. 类的加载分类:隐式加载和显示加载 3.2. 加载一个类的五步工作 3. ...
- Hadoop实战-MapReduce之WordCount(五)
环境介绍: 主服务器ip:192.168.80.128(master) NameNode SecondaryNameNode ResourceManager 从服务器ip:192.168.80.1 ...
- mongodb学习之:mongo安装以及远程访问
在linux下通过apt-get install mongo的方式一键式安装mongo 安装后mongo的配置文件位于/etc/mongodb.conf. 里面有mongo的各项配置,文件内容如下:重 ...
- 项目中一个普通的Java类如何获取service接口(一)
在普通的Java类中获取service接口目的是调用接口中的方法,实现数据的持久化等操作: Java类中的获取service接口方法: IfaceDetectService faceDetectSer ...
- linux apache服务器
apache服务器 服务端功能是侦听和响应客户端的http请求.http协议的默认端口是80. 1996年以来,apache成为最流行的web服务器. IIS web服务器只能安装在windows上. ...