C语言中的宏总结
我的博客:www.shishangguan.net
宏定义分为两种:
1.变量式宏定义,如
#define abc def
#define str "string"
#define num 100
2.函数式宏定义,
#define device_init_wakeup(dev,val) \
do { \
device_can_wakeup(dev) = !!(val); \
device_set_wakeup_enable(dev,val); \
} while()
注意:多行的时候,需要用do{}while(0)包装起来,这样更像一个函数调用。同时注意带有字增自减运算符的情况。
在函数式宏定义中, # 运算符用于创建字符串, # 运算符后面应该跟一个形参(中间可以有空格
或Tab),例如:
#define STR(s) # s
STR(hello world) //展开后为"hello world",自动加双引号。
注意:实参中的多个空格会被替换成一个空格。如果游爽引号",会被自动添加转义符,
## 运算符把前后两个预处理Token连接成一个预处理Token,函数式宏定义和变量式宏定义都可以使用。
#define CONCAT(a, b) a##b
CONCAT(con, cat) //展开后是concat #define HASH_HASH # ## # //展开后是##
函数式宏定义也可使用可变参数,如
#define showlist(...) printf(#__VA_ARGS__)
#define report(test, ...) ((test)?printf(#test):\
printf(__VA_ARGS__))
showlist(The first, second, and third items.);
report(x>y, "x is %d but y is %d", x, y);
替换后变成
printf("The first, second, and third items.");
((x>y)?printf("x>y"): printf("x is %d but y is %d", x, y));
注意,__VA_ARGS__包含参数间的逗号。
还有一种gcc的扩展,如
#define DEBUGP(format, ...) printk(format, ## __VA_ARGS__)
,##放在这儿,如果可变参数部分为空的时候,展开的时候第一个参数后不会有逗号。如
DEBUGP("info") //printk("info")
宏展开规则:
1.在展开当前宏函数时,如果形参有#(字符串化操作)或##(记号连接操作)则不进行宏参数的展开,否则先展开宏参数,再展开当前宏(就像先计算函数中的参数,然后调用函数一样)。
2.宏展开不能递归展开。
我的博客:www.while0.com
C语言中的宏总结的更多相关文章
- C语言学习笔记--C语言中的宏定义
1. C 语言中的宏定义 (1)#define 是预处理器处理的单元实体之一(因此,预处理器只是简单的进行替换,并不(2)#define 定义的宏可以出现在程序的任意位置(包括函数体的内部)(3)#d ...
- C语言中的宏定义
目录(?)[-] 简单宏定义 带参数的宏 运算符 运算符 宏的通用属性 宏定义中圆括号 创建较长的宏 较长的宏中的逗号运算符 宏定义中的do-while循环do 空操作的定义 预定义宏 C语言中常用的 ...
- C语言中的宏
写好C语言,漂亮的宏定义很重要,使用宏定义可以防止出错,提高可移植性,可读性,方便性 等等.下面列举一些成熟软件中常用得宏定义...... 1,防止一个头文件被重复包含 #ifndef COMDEF_ ...
- 20个C语言中常用宏定义总结
01: 防止一个头文件被重复包含 #ifndef COMDEF_H#define COMDEF_H//头文件内容#endif 02: 重新定义一些类型防止由于各种平台和编译器的不同,而产生的类型字节数 ...
- C语言中的宏展开
#include<stdio.h> #define f(a,b) a##b #define g(a) #a #define h(a) g(a) int main() { printf(,) ...
- c语言中使用宏,需要注意的的几点
使用#define来定义一些宏,进行一些简洁的替换甚至一些带参数的宏,在linux c代码中很常见,说明它很好.很有用, 但是它也有一些复杂的规矩和陷阱需要注意,下面我记录一些,仅供参考. 1.当使用 ...
- C\C++语言中的宏多重展开和递归展开
宏定义中的#,## 1. 宏中的参数前面使用一个#,预处理器会把这个参数转换为一个字符数组 2.记号粘贴操作符(token paste operator): ## “## ...
- Visual Studio属性配置中使用宏
在学习C语言的时候,我们曾经遇到过一个宏的概念.宏的作用机理本质上是宏的展开,C语言中的宏的用法也有很多种(水其实很深...),不过从感觉上来讲,人们大致上会在以下的场景中,利用宏来解决一些窘境:一是 ...
- 哨兵查找法(明解c语言) + 函数式宏
//哨兵法,就是将待查找的元素加入待查找的数组的后面,这样可以提高性能(在数据量很庞大的时候体现出来) #include <stdio.h> #define FAILURE -1 //使用 ...
随机推荐
- 牵扯较多属性和方法的类题目,很简单的题目本来不想发的,如果有同学学到这个题目感觉太长不愿敲代码,copy走我的即可~不过还是建议自己打一打
/* 3.设计一个"学生"类 1> 属性 * 姓名 * 生日 * 年龄 * 身高(单位是m) * 体重(单位是kg) * 性别 * C语言成绩 * OC成绩 * iOS成绩 ...
- java集合_collection子接口 list的特有方法,ArrayList类体现
/* Collection |--List:元素是有序的,元素可以重复.因为该集合体系有索引. |--ArrayList:底层的数据结构使用的是数组结构.特点:查询速度很快.但是增删稍慢.线程不同步. ...
- Java线程练习
/*线程练习创建两个线程,与主线程交替运行 */ class Text extends Thread{ private String name; Text(String name) ...
- Eclipse恢复初始界面&打开视图
恢复初始界面: 单击菜单栏的windows主菜单,在子菜单里选择 Reset Perspective 会弹出各对话框 ,点 ok就可以了 打开视图:Windows->Show View 其中Ot ...
- mysql innodb 数据打捞(四)innodb 簇不连续页扫描提取(试验)
一,用winhex把正常页有意做成不连续的两部分,把后8K向后移动4K,中间隔开4K,启动第一次扫描; 扫描结果是,没有提取到有效页面,但在输出目录生成两个文件:upper.pages和upper.l ...
- [Effective Objective-C 读书笔记] 第1章 几条基本写法 (2~5条)
我的技术博客经常被流氓网站恶意爬取转载.请移步原文:http://www.cnblogs.com/hamhog/p/3575599.html,享受整齐的排版.有效的链接.正确的代码缩进.更好的阅读体验 ...
- 七牛云覆盖上传 php
使用七牛云过程中遇到了需要上传覆盖的情况,最终解决,分享给大家. 七牛云sdk上传示例中是这样写的 <?php require_once 'path_to_sdk/vendor/autoload ...
- 【仿携程JQuery日期价格表】
今天比较闲所以就花点时间又写了点东西. 相信这种价格表大家不会陌生 现在我就模仿它做一个简单版本的.效果如下 首先需要两个时间控件,我这里用的是HTML5里面的时间控件,这个没限制喜欢用什么就用什么 ...
- 今日吐槽20151208.net服务器控件
正文 今天有个小任务是给页面添加一个搜索条件,复选框多选.因为页面都是服务器控件,我也只能用服务器控件配合了.然后给页面加了一个 CheckBoxList 控件.后台通过数据表加载数据. fore ...
- IT书籍下载汇总--持续更新
本书单由北北分享,并持续更新,请将该地址加入收藏夹:北北的书单 .badge{float:right;}.list-group-item > .badge + .badge{margin-rig ...