#define的使用方法体会
#define 创建一个宏,该宏是标识符或參数化标识符与标记字符串的关联。
在定义宏之后。编译器可用标记字符串替换源文件里标识符的每一个匹配项。
双击以所有折叠。">语法
#define identifier token-string
#define identifier ( identifier 1 , ... , identifier n ) token-string
">备注
1 #define 指令促使编译器用 token-string 替换源文件里 identifier 的每一个匹配项。 仅当 identifier 构成标记时才替换它。 也就是说,假设 identifier 出如今凝视、字符串或较长的标识符中。则不会替换它。
2 另外一种形式类似于函数,比如
#define mul(a,b) (a*b) 形參名称将出如今 token-string 中以标记实际值的替换位置。
token-string 中前面未带stringizing (#)、charizing(#@)
或 token-pasting (##) 运算符或后面未跟 ## 运算符的每一个形參将由相应的实參替换。
注意:
1 宏就是简单的字符替换,注意替换后的运算符优先级可能会影响宏定义所要表达的。所以要善于使用小括号。比如:
#define Add(a,b) a+b 假设使用的时候:2*Add(1,2) 原本想让它等于6,但替换后变成2*1+2=4。
所以要注意。
2 #define中的换行符是反斜杠\。
假设一行没写完。直接加一个\,下一行继续写就能够了。
3 注意这里仅仅是字符替换。宏定义中不应含有return等语句。想一想替换后。会变成什么样子。
宏的返回值的两种形式:
1 操作符。
#define Max(a,b) (((a)>(b))(a):(b))
#define add(a,b) ((a)+(b))
2 将返回值赋值给一个额外的形參。这个形參就是返回值。
#define cal(a,b,c) {c=a+b;}
一个很有意思的样例:
定义一个求最大值的宏。
可能会这么写:#define Max(a,b) ((a)>(b) ?
a):(b))
这么做可能对于大多数情况是没有错误的,可是事实上这么做是不严谨的。比如:
#define Max(a,b) ((a)>(b)? (a):(b))
int fun(int *a)
{
*a=*a+1;
return *a;
}
main()
{
int a=1,b=2,c;
c=Max(a,fun(&b));
}//我们想得到的c的值应该是3,但实际会发现c的值是4.
由于首先我们替换:c=((a)>(fun(&b))?
(a):(fun(&b)));
能够发现fun运行了两次。b的值加了两次变成了4.所以结果是4.
这里给出一个严谨的做法:
使得參数仅仅被运行一次。
#define Max(a,b) ({\
typeof(a) _a=(a);\
typeof(b) _b=(b);\
(_a>_b)? _x : _y; })
这样就不会有上述的问题了。
注意:({...})的作用是将内部的几条语句中最后一条的值返回,它也同意在内部声明变量(由于它通过大括号组成了一个局部Scope)。用此能够达到return的目的。
!!
注:这里使用了typeof。它是c的一个新扩展。而在vs2005,2010,2013中都无法使用。
仅仅能在在线编译器下运行。结果是对的。
观察发现:vs中不识别keywordtypeof了。在C++中可用decltype实现相似功能,求某个变量的类型。并且vs中也不能够有这种({...})的东西了。
要么#define..
() 要么#define .. {}。
所以上面的做法能够改成:
#define MIN(X,Y,M) {\
decltype(X)x_ = (X);\
decltype(Y)y_ = (Y);\
M=(x_ < y_) ? x_ : y_; }
使用时:int a=1,b=2,c; Max(a,b,c);c为返回值。不參与运算。
#与##与#@在#define中的使用方法:
#的意思是不展开參数
假设在token-string 中出现以#开头。意思是:不展开參数。直接替换。
假设在token-string 中出现不以#开头,意思是:展开參数。直接替换。
比如:
#define f(a) a+1
#define T(a) #a
#define H(a) a
T(f(a))->f(a)->a+1
H(f(a))->H(a+1)->a+1
尽管结果一样,可是过程不一样。
##的意思是字符串连接符
比如:
#define f(a,b) a##b##lobe
结果就是ablobe
注意:##不能出如今开头,也不能出如今结尾。仅仅能出如今中间。
#@字符化运算符
Microsoft 专用
charizing 运算符仅仅能与宏的參数一起使用。 假设宏的定义中的形參前有 #@。则会在扩展宏时用单引號括起实參并将其视为一个字符。
#define makechar(x) #@x
==
char a= makechar(x);
比如:
#define H(x) #@x
cout<<H(a)<<endl;
输出结果:a
cout<<H(ab)<<endl;
输出结果:24930
注解:就是相当于把#@后面的实參变成一个字符型的字符。
#define的使用方法体会的更多相关文章
- tornado 的 define 和options方法解读
一.源码解读 tornado是facebook开源的非阻塞web容器,类似java的netty,tornado.options是负责解析tornado容器的全局参数的,同时也能够解析命令行传递的参数和 ...
- Unable to execute dex: Multiple dex files define 的解决方法
我们在引入library时可能会出现这个错误 比如: [2013-11-05 14:22:15 - Dex Loader] Unable to execute dex: Multiple dex fi ...
- FXC Define的使用方法
https://docs.microsoft.com/en-us/windows/desktop/direct3dtools/dx-graphics-tools-fxc-syntax https:// ...
- #define使用方法
1.简单的define定义 #define MAXTIME 1000 一个简单的MAXTIME就定义好了,它代表1000,假设在程序里面写 if(i<MAXTIME){.........} 编译 ...
- define 的全部使用方法
typedef的总结,以下是引用的内容(红色部分是我自己写的内容). 用途一: 定义一种类型的别名,而不只是简单的宏替换.可以用作同时声明指针型的多个对象.比如: char* pa, pb; // 这 ...
- iOS常用系统信息获取方法
一.手机电量获取,方法二需要导入头文件#import<objc/runtime.h> 方法一.获取电池电量(一般用百分数表示,大家自行处理就好) -(CGFloat)getBatteryQ ...
- php中const与define的使用区别 详解
1.const用于类成员变量定义,一旦定义且不能改变其值.define定义全局常量,在任何地方都可以访问. 2.define不能在类中定义而const可以. 3.const不能在条件语句中定义常量 i ...
- PHP 中const 与define 区别
1.const用于类成员变量定义,一旦定义且不能改变其值.define定义全局常量,在任何地方都可以访问. 2.define不能在类中定义而const可以. 3.const不能在条件语句中定义常量 i ...
- const与define的使用区别
1.const用于类成员变量定义,一旦定义且不能改变其值.define定义全局常量,在任何地方都可以访问. 2.define不能在类中定义而const可以. 3.const不能在条件语句中定义常量 i ...
随机推荐
- Android Developer -- Bluetooth篇 开发实例之三 管理连接
Managing a Connection When you have successfully connected two (or more) devices, each one will have ...
- win7 下注册dll文件失败
1.win7 下注册dll文件失败,提示模块“xx.dll”已加载,但找不到入口点DllRegisterServer 原因:该dll文件非可注册组件,没有包含DllRegisterServer函数,可 ...
- sql server 性能调优 资源等待之网络I/O
原文:sql server 性能调优 资源等待之网络I/O 一.概述 与网络I/O相关的等待的主要是ASYNC_NETWORK_IO,是指当sql server返回数据结果集给客户端的时候,会先将结果 ...
- linux内存查看方法
cat /proc/meminfo 查看RAM使用情况,最简单的方法是通过/proc/meminfo.这个动态更新的虚拟文件实际上是许多其他内存相关工具(如:free / ps / top)等的组合显 ...
- django模型manager学习记录
Managers 在语句Book.objects.all()中,objects是一个特殊的属性,需要通过它查询数据库. 在第5章,我们只是简要地说这是模块的manager .现在是时候深入了解mana ...
- tez参数
https://tez.apache.org/releases/0.8.4/tez-api-javadocs/configs/TezConfiguration.html
- FormData上传文件同时附带其他参数
前端js代码: function fileSubmit() { var formData = new FormData(); formData.append(].files[]); var type ...
- 让Mac支持lrzsz
http://blog.csdn.net/citywolf4/article/details/49071679 https://github.com/mmastrac/iterm2-zmodem
- [ElasticSearch]Java API 之 词条查询(Term Level Query)
1. 词条查询(Term Query) 词条查询是ElasticSearch的一个简单查询.它仅匹配在给定字段中含有该词条的文档,而且是确切的.未经分析的词条.term 查询 会查找我们设定的准确值 ...
- AngularJS, Ember.js, Backbone这类新框架与 jQuery的重要区别在哪里?
jQuery主要是用来操作DOM的,如果单单说jQuery的话就是这样一个功能,它的插件也比较多,大家也都各自专注一个功能,可以说jQuery体系是跟着前端页面从静态到动态崛起的一个产物,他的作用就是 ...