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 //使用 ...
随机推荐
- Java项目经验
Java项目经验 转自CSDN. Java就是用来做项目的!Java的主要应用领域就是企业级的项目开发!要想从事企业级的项目开发,你必须掌握如下要点:1.掌握项目开发的基本步骤2.具备极强的面向对象的 ...
- Markdown 生成目录
<link rel="stylesheet" href="http://yandex.st/highlightjs/6.2/styles/googlecode.mi ...
- Eclipse恢复初始界面&打开视图
恢复初始界面: 单击菜单栏的windows主菜单,在子菜单里选择 Reset Perspective 会弹出各对话框 ,点 ok就可以了 打开视图:Windows->Show View 其中Ot ...
- Linux下UDP收/发广播消息简单实现
发送广播消息 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<sys/typ ...
- A Case for Flash Memory SSD in Enterprise Database Applications
通过分析固态硬盘的特性对数据库中不同对象,如:表,索引,回滚段,重做日志等的应用进行具体研究,最后将数据库中不同的对象进行区别应用
- redis 常用操作命令
操作相关的命令连接 quit:关闭连接(connection)auth:简单密码认证 持久化 save:将数据同步保存到磁盘bgsave:将数据异步保存到磁盘lastsave:返回上次成功将数据保存到 ...
- 获取input标签的所有属性
1.用jquery$("input[name='btnAdd']").attr("value") 获取value属性值,其它属性换attr的参数就OK 例1: ...
- jQuery Mobile里xxx怎么用呀?(控件篇)
jQuery Mobile里都有什么控件? http://api.jquerymobile.com/category/widgets/ jQuery Mobile里slider控件的change事件怎 ...
- 使用内核定时器的second字符设备驱动及测试代码
驱动: #include <linux/kernel.h> #include <linux/module.h> #include <linux/fs.h> #inc ...
- Python中map,filter,reduce,zip的应用
事例1: l=[('main', 'router_115.236.xx.xx', [{'abc': 1}, {'dfg': 1}]), ('main', 'router_183.61.xx.xx', ...