#define中使用的参数#、##、__VA_ARGS__和##__VA_ARGS___#define __map(n,...) __map##n(__va_args__)-程序员宅基地

技术标签: c语言  

#在预编译时期将宏参数转换为字符串

#define PRINT_MACRO_HELPER(x) #x
#define PRINT_MACRO(x) PRINT_MACRO_HELPER(x)
#define PRINT_ANOTHER_MACRO(x) #x"="PRINT_MACRO_HELPER(x)
char *str=PRINT_MACRO_HELPER(1235982536);
char *str2=PRINT_MACRO(i);
char *str3=PRINT_ANOTHER_MACRO(i);
printf("the string of str is %s,the string of str2 is %s ,the string of str3 is %s\n",str,str2,str3);
输出:
the string of str is 1235982536,the string of str2 is i,the string of str3 is i=i

宏连接符##
用于将带参数的宏定义中将两个子串(token)联接起来,从而形成一个新的子串;但它不可以是第一个或者最后一个子串。所谓的子串(token)就是指编译器能够识别的最小语法单元。但是“##”不能随意粘合任意字符,必须是合法的C语言标示符。在单一的宏定义中,最多可以出现一次“#”或“##”预处理操作符。如果没有指定与“#”或“##”预处理操作符相关的计算次序,则会产生问题。为避免该问题,在单一的宏定义中只能使用其中一种操作符(即,一份“#”或一个“##”,或都不用)。除非非常有必要,否则尽量不要使用“#”和“##”。

举个例子:宏定义为#define XNAME(n) x##n,代码为:XNAME(4),则在预编译时,宏发现XNAME(4)与XNAME(n)匹配,则令 n 为 4,然后将右边的n的内容也变为4,然后将整个XNAME(4)替换为 x##n,亦即 x4,故最终结果为 XNAME(4) 变为 x4。如下例所示:

#include <stdio.h>
#define XNAME(n) x##n
#define PRINT_XN(n) printf("x" #n " = %d\n", x##n);
int main(void)
{
    
    int XNAME(1) = 14; // becomes int x1 = 14;
    int XNAME(2) = 20; // becomes int x2 = 20;
    PRINT_XN(1);       // becomes printf("x1 = %d\n", x1);
    PRINT_XN(2);       // becomes printf("x2 = %d\n", x2);
    return 0;
}

可变参数宏

在GNU C中,从C99开始,宏可以接受可变数目的参数,就象可变参数函数一样。和函数一样,宏也用三个点…来表示可变参数

VA_ARGS
VA_ARGS 宏用来表示可变参数的内容,简单来说就是将左边宏中 … 的内容原样抄写在右边__VA_ARGS__ 所在的位置。如下例代码:

#include <stdio.h>
#define debug(...) printf(__VA_ARGS__)
int main(void)
{
    
    int year = 2018debug("this year is %d\n", year); //效果同printf("this year is %d\n", year);
}

可变参数别称
另外,通过一些语法,你可以给可变参数起一个名字,而不是使用__VA_ARGS__ ,如下例中的args:

#include <stdio.h>
#define debug(format, args...) printf(format, args)
int main(void)
{
    
    int year = 2018debug("this year is %d\n", year);  //效果同printf("this year is %d\n", year);
}

无参传入情况
与可变参数函数不同的是,可变参数宏中的可变参数必须至少有一个参数传入,不然会报错,为了解决这个问题,需要一个特殊的“##”操作,如果可变参数被忽略或为空,“##”操作将使预处理器(preprocessor)去除掉它前面的那个逗号。如下例所示

#include <stdio.h>
#define debug(format, args...) printf(format, ##args)
int main(void)
{
    
    int year = 2018debug("hello, world");  //只有format参数,没有args可变参数
}
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_22267967/article/details/120083937

智能推荐

qt 实现雷达扫描效果(附完整源码)_雷达控件 qt-程序员宅基地

文章浏览阅读93次。qt 实现雷达扫描效果(附完整源码)_雷达控件 qt

【Python常用函数】一文让你彻底掌握Python中的pivot_table函数_python pivot table-程序员宅基地

文章浏览阅读2.5k次。python中的pivot_table函数详解_python pivot table

OpenProcess调用失败,GetLastError返回5_openprocess 返回5-程序员宅基地

文章浏览阅读7.1k次。转自https://social.msdn.microsoft.com/Forums/zh-CN/20e3fc99-1d21-43b5-9bc2-03a52a721dc5/openprocess现象:服务方式程序时,程序的创建者为SYSTEM用户;非SYSTEM用户调用OpenProcess访问该服务程序时,调用失败,GetLastError返回5,可以通过调用如下EnableDebugP_openprocess 返回5

C语言,要求找出满足下列条件的 3 位数:它是完全平方数,又有两位数字相同。如:144、676。_c++求三位数的所有完全平方数-程序员宅基地

这篇文章介绍了关于系统操作、系统监控和文件权限设置的一些命令和操作方法,包括关机命令、后台执行命令、创建快捷方式、定时任务查看、网络流量监控、端口使用情况查看等。

DP转HDMI音视频数据转换器普瑞PS176方案设计_谱瑞ps176hdm方案设计-程序员宅基地

文章浏览阅读1.2k次。一、PS176概述PS176是一个显示端口 (DP)至HDMI 2.0视频接口转换器适用于需要视频协议转换的电缆适配器、电视接收器、监视器和其他应用。它将接受任何显示端口输入格式,包括DP 1.1a、dp1.2a、dp1.3或dp1.4。它可以输出传统的HDMI和DVI视频模式以及HDMI2.0格式。HDMI 2被支持到允许的最大TMDS日期速率为6Gb/s,使得4K 超高画质的视频以每秒24位的4:4:4视频模式每秒60帧的速度播放。PS176可提供实现由一个使用内部SPI ROM进行自动配置和微_谱瑞ps176hdm方案设计

pip install pycocotools 安装报错_pip install mmpycocotools报错-程序员宅基地

文章浏览阅读1.9k次,点赞2次,收藏6次。在Anaconda中执行pip install pycocotools后报错如下提示Microsoft Visual C++ 14.0 or greater is required.可以按照提示去官网下载,下载完后我又进入另一个坑,在安装过程中总是提示安装包丢失或已损坏,所以采用离线下载的方式,来离线搜索安装包实现离线安装离线包我这里给大家一个百度网盘的连接,大家自行下载即可链接:https://pan.baidu.com/s/1n5eVgV3iaR3Zyhzf30qZCA提取码:3jt._pip install mmpycocotools报错

随便推点

Kafka(二)实战篇(集群搭建、客户端命令、日志查看、Kafka原生API、Spring Boot Kafka)_kafka查看所有客户端-程序员宅基地

文章浏览阅读2.0k次。1. Kafka 集群搭建在生产环境中为了防止单点问题,Kafka 都是以集群方式出现的。下面要搭建一个 Kafka集群,包含三个 Kafka 主机,即三个 Broker。1.1 Kafka 的下载http://kafka.apache.org/downloads1.2 安装并配置第一台主机(1) 上传并解压将下载好的 Kafka 压缩包上传至 CentOS 虚拟机,并解压。[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hqgOu9TY-160023879115_kafka查看所有客户端

window下使用python import cx_Oracle时报错_windows import cx_oracle-程序员宅基地

文章浏览阅读9.1k次。python Oracle cx_Oracle_windows import cx_oracle

java-php-python-ssm学生校内兼职管理平台计算机毕业设计-程序员宅基地

文章浏览阅读100次。springboot基于Springboot的滑雪场学具租赁管理系统。springboot基于springboot的健身俱乐部综合管理系统。JSP基于Web的在线文献查阅系统的设计与实现sqlserver。springboot基于Bootstrap的家具商城系统设计。ssm基于SSM框架的菲特尼斯健身管理系统的设计与实现。jsp基于个性化推荐的扬州农业文化旅游管理平台。ssm基于javaweb的扶贫产品物资管理平台。ssm基于SpringMvC的流浪狗领养系统。ssm基于JavaEE的校园临时用工网站。

kindle安卓更新固件(已经装过安卓系统)_kindle enter updating mode-程序员宅基地

文章浏览阅读4.7w次,点赞2次,收藏14次。(http://182.254.232.41/download/update/update.170822/doc/3.%E5%9B%BA%E4%BB%B6%E6%9B%B4%E6%96%B0.html)1根据机型下载安卓固件,在电脑上解压缩固件,《kindle.xxxxxx.zip》入门版499《kpw2.xxxxxx.zip》Paperwhite二代《kpw3.xxxx_kindle enter updating mode

idea与vue+ElementUI搭建前后端分离的CRUD_elementplus vue idea-程序员宅基地

文章浏览阅读3.1k次,点赞2次,收藏15次。idea与vue+ElementUI搭建前后端分离的CRUD_elementplus vue idea

html+css+js图片加载失败设置默认图片_js图片加载失败事件-程序员宅基地

文章浏览阅读468次。【代码】html+css+js图片加载失败设置默认图片。_js图片加载失败事件

推荐文章

热门文章

相关标签