tags: C/C++

写在前面

简单总结一下C语言中x-macros(宏)的几种主要用法, 虽然主流的C语言程序中一般是不推荐使用宏的, 但是作为一种不错的C语言语法糖, 了解一下也不错,至少能看懂点大佬的代码. 主要参考了C语言程序设计:现代方法第十四章预处理器.

基本语法

直接展开

其实就是简单的展开而已.

#include <stdio.h>#define n1 100
#define M (n1*n1+3*n1)int main() {int sum;sum = 3 * M + 4 * M + 5 * M;printf("sum=%d\n", sum);return 0;
}

这段程序中就是一个预处理器(宏)的简单用法, 直接进行简单的(无脑)替换操作.

带参数的宏

#include <stdio.h>
#define printn(n) printf("n=%d\n", n)int main() {int sum = 20 + 12;printn(sum);return 0;
}

井号的用途

单个井号表示变量替换, 后面跟上要替换的变量; 两个井号挨着表示连接.

#include <stdio.h>
#include <stdlib.h>
void t1() {// #表示变量替换
#define AREA(x,y) printf("长为"#x",宽为"#y"的长方形面积为%d.\n",(x)*(y));int i = 55, j = 3;AREA(i, j);AREA(3, 2);/*长为i,宽为j的长方形面积为165.长为3,宽为2的长方形面积为6.*/
}//##表示连接
#define VAR(n)v##nint v1(int a, int b) {return a + b;
}
int v2(int a, int b) {return a - b;
}
void t2() {printf("%d\n", VAR(1)(2, 3));printf("%d\n", VAR(2)(2, 3));/*5-1*/
}int main(int argc, char const *argv[]) {// t1();t2();return 0;
}

预定义的宏

C语言中预定义了一些宏, 可以用于调试代码.

名称 描述
__LINE__ 被编译的文件中的行号
__FILE__ 被编译的文件名称
__DATE__ 编译日期(mm dd yyyy)
__TIME__ 编译时间((hh:mm:ss))
__STDC__ 编译器符合C标准(89or99),值为1
__func__ 存储当前正在执行的函数的名字的字符串变量

这里直接用之前写好的C++代码了,C也一样,改成printf即可.

#include <iostream>
using namespace std;#define LOG(x) (cout<<__FILE__<<" "<<__LINE__<<": "<<__PRETTY_FUNCTION__<<(x)<<endl)void t1() {LOG("hello");
}template<typename T>
void t2(T s) {LOG(s);cout << __TIME__ << endl;cout << __DATE__ << endl;cout << __func__ << endl;/*gcc_pre_define.cc 13: void t2(T) [with T = char]100:17:03Aug 24 2022t2*/
}int main(int argc, char const *argv[]) {// t1();t2('1');return 0;
}

任意个数的参数的宏(C99)

#include <stdio.h>
#include <stdarg.h>
// 测试函数的用法是: 满足参数条件的话, 执行打印"通过测试", 否则执行自定语句
#define TEST(cond, ...) \
((cond) ? printf("Passed test: %s\n", #cond) : \
printf(__VA_ARGS__))void t1() {int v = 10, maxV = 20;TEST(v <= maxV, "v %d exceeds %d\n", v, maxV);v = 100, maxV = 20;TEST(v <= maxV, "v %d exceeds %d\n", v, maxV);/*Passed test: v <= maxVv 100 exceeds 20*/
}int main(int argc, char const *argv[]) {t1();return 0;
}

…记号(省略号)出现在宏参数列表的最后,前面是普通参数。__VA_ARGS__是一个专用的标识符,只能出现在具有可变参数个数的宏的替换列表中,代表所有与省略号相对应的参数。

(至少有一个与省略号相对应的参数,但该参数可以为空。)宏TEST至少要有两个参数,第一个参数匹配condition,剩下的参数匹配省略号。

注意事项

  1. 在每一个宏替换的变量两边都要加爱上圆括号, 这样可以防止宏替换之后的代码意义改变.
  2. 多行的宏定义, 在断行位置需要加上反斜杠(转义);
  3. 单一的井号后接变量名, 这种用法放在printf中, 隐含了C语言字符串字面量可以直接合并.

更多细节请看上面提到的书, 对一些比较特殊的例子也有解释.

C语言宏的几种常用语法与示例相关推荐

  1. jsp 4种常用语法3个编译指令7个动作指令

    4种常用语法: 注释:<%--注释--%> 声明:<%!声明部分%> 输出:<%=%> 脚本:可以包含任何java可执行代码.例 <% for(int i=0 ...

  2. 语言语法糖_【c#】几种常用语法糖

    语法糖(syntactic sugar)是由英国计算机科学家Peter J. Landin发明的术语,指计算机语言中添加的某种语法.这种语法不影响语言的功能,但更方便使用. 在开发中使用语法糖能够让程 ...

  3. java几种常用设计模式简单示例

    1.单例设计模式 所谓单例设计模式简单说就是无论程序如何运行,采用单例设计模式的类(Singleton类)永远只会有一个实例化对象产生.具体实现步骤如下: (1) 将采用单例设计模式的类的构造方法私有 ...

  4. 宏定义 指针 c语言,C语言宏定义讲解(C和指针 笔记)

    关于C语言宏定义#define 最常用的莫过于通过宏定义定义常数了,例如 #define MAX 1000      通过宏定义程序中需要的常量,方便维护被多次引用的变量,并且宏替换在预处理阶段完成, ...

  5. linux命令:awk常用语法

    awk 的工作原理是将文件内容逐行读入,然后以每一行中的空格为分隔符将每行数据切分成几列,再对每列的元素进行各种分析处理.  下面结合实例简单介绍 awk 命令常用的几种格式: 假设文件 form.t ...

  6. C语言宏定义、宏函数、内置宏与常用宏

    前言: 在C语言中,变量类型.循环控制.基础语法等与其他高级语言基本无异:而C语言(C++)特有的两把双刃剑指针和宏定义/宏函数使得C语言在底层开发中披荆斩棘.无所不能.这两个概念涉及范围比较广,其分 ...

  7. 根据文法画出语法树_几种常用的英语教学法误导了语法教学

    多年来,我国的英语教学一直采用语法翻译法,教法比较单一.上世纪八十年代初,随着国际交流的日益加强和教学改革的进一步深入,各种英语教学法,尤其是从国外推介的教学法都相继进入英语教学领域.尽管有一些教学法 ...

  8. python语言的语法_PYTHON语言常用语法摘要

    Python 语言常用语法 在 Python 中有 4 种类型的数--整数.长整数.浮点数和复数. 使用变量时只需要给它们赋一个值.不需要声明或定义数据类型. 不要 混合使用制表符和空格来缩进, 因为 ...

  9. web前端框架开发的几种常用语言?

    做Web开发,Web框架一定要熟悉,框架是Web架构开发中必不可少的工具,不仅可以提高开发效率,还能让开发项目更成熟,并且可以提升代码的可再用性,Web框架开发离不开相应的开发语言,以下是常用的Web ...

最新文章

  1. “三板斧”式文化价值体系互助协作,打通企业全流程管理模式
  2. 项目管理利器taiga快速安装
  3. android Adapter
  4. c/c++中typedef与函数指针
  5. .NET 6 全新指标 System.Diagnostics.Metrics 介绍
  6. linux关闭4750 端口,【ubuntu分享帖】acer 4750G ubuntu安装后的一些设置
  7. django-orm框架了解
  8. js判断字符串中某个字母出现次数最多
  9. Java笔记9:构造方法,内部类
  10. DataX Hdfs HA(高可用)配置支持
  11. java 线程 condition_Java编程中实现Condition控制线程通信
  12. 中点画线算法画直线----计算机图形学
  13. java程序设计实用教程 实验6答案_java程序设计实用教程习题解答与实验指导.doc...
  14. 中国各路神仙!!!!
  15. c语言两个字符串比较,将两个字符串s1和s2比较,如果s1s2,作业 - 编一个程序,将两个字符串s1和s2比较,如果.doc...
  16. Java 删除文件/文件夹
  17. 数睿数据的四域模型(软件=数据+形式)源何引发强烈关注?
  18. gitbash执行linux二进制文件,Git大文件存储将帮助Git处理大型二进制文件
  19. 任正非的胸怀和美国的狭隘
  20. 可乐学习NVMe之二:三只熊SQ/CQ/DB

热门文章

  1. XSS 平台搭建与优化(基于 xsser.me 源码)
  2. 充电桩、换电站、移动充电机器人,谁是补能最优解?
  3. 奇迹服务器端文件说明,奇迹云服务器
  4. LTE网络的RSRQ、RSRP、SNR
  5. css背景的设置及属性
  6. 11.4 OSPF在帧中继网络中的配置
  7. Python 实现简单的单机版 21 点游戏
  8. 系统架构设计笔记(16)——局域网与广域网
  9. ios作为pc摄像头,pc作为ios/另一pc摄像头
  10. Markdown 文本换行