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 //使用 ...
随机推荐
- -exec和|xargs
注意xargs会被空格割裂,所以遇到带有空格的文件名就不好办了,解决方法是使用-print0 例如:删除.目录下30天之前的.png文件 -type f -name rm 或者使用-exec:删除.目 ...
- Linq 查询 与方法调用
通常,使用linq查询时需要一个实现IQueryable<T> 的查询对象 public class DataA<T> : IQueryable<T> {....} ...
- 简单jquery 鼠标悬停提示效果
记得自己引入jq插件哦~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset= ...
- android体系架构
android体系架构总结: android体系架构分为四层 第一层:应用层:applications 第二层:开发层 第三层:
- ASP.net后台弹出消息对话框的方法!【转】
在winform后台,我们通过MessageBox.show(“消息")的方式来返回后台信息,在webform后台,我们通过Response.write(”消息")来返 ...
- angular中的orderBy过滤器使用
一 orderBy过滤器 AngularJS中orderBy进行排序,第一个参数可以有三种类型,分别为:function,string,array: 第一种:function,如果是func ...
- Linux下的ntp时钟同步问题
前段时间,项目中有个需求,需要将linux和windows的时间进行同步,网上也有很多类似时钟同步的帖子,大致类似:不过本次的linux的机器有点特殊,没有service命令,而且要求在另一台suse ...
- Date、String、Calendar类型之间的转化
原文出处:http://fjfj910.iteye.com/blog/1202219 1.Calendar 转化 String //获取当前时间的具体情况,如年,月,日,week,date,分,秒等 ...
- mysql基本知识
最大连接数show variables max_connections; select VARIABLE_VALUE from information_schema.GLOBAL_VARIABLES ...
- 前端内容缓存技术:CSI,SSI,ESI
一.CSI (Client Side Includes) 含义:通过iframe.javascript.ajax 等方式将另外一个页面的内容动态包含进来. 原理:整个页面依然可以静态化为html ...