惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The Hacker News
The Hacker News
F
Full Disclosure
Cloudbric
Cloudbric
Blog — PlanetScale
Blog — PlanetScale
W
WeLiveSecurity
N
News and Events Feed by Topic
T
Troy Hunt's Blog
V2EX - 技术
V2EX - 技术
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
B
Blog
GbyAI
GbyAI
C
Check Point Blog
B
Blog RSS Feed
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Recorded Future
Recorded Future
The Last Watchdog
The Last Watchdog
N
News and Events Feed by Topic
T
The Blog of Author Tim Ferriss
O
OpenAI News
V
V2EX
人人都是产品经理
人人都是产品经理
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
IT之家
IT之家
WordPress大学
WordPress大学
www.infosecurity-magazine.com
www.infosecurity-magazine.com
S
Security @ Cisco Blogs
C
Cisco Blogs
Security Latest
Security Latest
S
Security Affairs
V
Visual Studio Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Hacker News - Newest:
Hacker News - Newest: "LLM"
博客园 - 司徒正美
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Microsoft Azure Blog
Microsoft Azure Blog
Last Week in AI
Last Week in AI
AWS News Blog
AWS News Blog
雷峰网
雷峰网
Apple Machine Learning Research
Apple Machine Learning Research
PCI Perspectives
PCI Perspectives
博客园_首页
U
Unit 42
Google DeepMind News
Google DeepMind News
Hugging Face - Blog
Hugging Face - Blog
Project Zero
Project Zero
Cisco Talos Blog
Cisco Talos Blog
The Register - Security
The Register - Security
N
Netflix TechBlog - Medium
L
LINUX DO - 热门话题
H
Hacker News: Front Page

博客园 - Evilbaniry

(转)浏览器的两种模式quirks mode 和strict mode Does a Nodelist contain circle? XML Dom所有的节点类型 ExtJS-2.2内存泄漏补丁 (转)VC中#pragma warning指令 自已为Ext添加的DateTimeField控件(附源码) VC里一些容易混淆的地方(转) (转)GetWindowLongPtr释义 (转)消息分流器 (转)std::map的用法总结 GetModuleFileName()得到程序路径 利用GetDriveType来得到驱动器信息 makeintresource:VC MAKEINTRESOURCE 析疑 (转)c/c++的预处理定义 Stringizing Operator (#) Charizing Operator (#@) Token-Pasting Operator (##) va_start() va_end()函数应用 #ifdef __cplusplus 倒底是什么意思? (转)typedef用法小结 (转)STDAPI释义 判断windows系统类型
#define总结 (网上资料汇集)
Evilbaniry · 2009-02-25 · via 博客园 - Evilbaniry

1. 定义简单的常数:定义常量,便于修改(切不可在后面加上分号!)

 #define N 1000

 等效于 const int N = 1000; 但略有不同,define只是简单替换,而不是作为一个量来使用.

2. 定义简单的函数:注意多使用括号

define可以像函数那样接受一些参数,如下:

#define max(x,y) (x)>(y)?(x):(y);

这个定义就将返回两个数中较大的那个,看到了吗?因为这个“函数”没有类型检查,就好像一个函数模板似的,当然,它绝对没有模板那么安全就是了。可以作为一个简单的模板来使用而已。但是这样做的话存在隐患,例子如下:

#define Add(a,b) a+b;

在一般使用的时候是没有问题的,但是如果遇到如:c * Add(a,b) * d的时候就会出现问题,代数式的本意是a+b然后去和c,d相乘,但是因为使用了define(它只是一个简单的替换),所以式子实际上变成了

c*a + b*d

另外举一个例子:

#define pin (int*);

pin a,b;

本意是a和b都是int型指针,但是实际上变成int* a,b;

a是int型指针,而b是int型变量。

这是应该使用typedef来代替define,这样a和b就都是int型指针了。

所以我们在定义的时候,养成一个良好的习惯,建议所有的层次都要加括号。

3. 定义单行宏:主要有以下三种用法.

   1) 前加##或后加##,将标记作为一个合法的标识符的一部分.注意,不是字符串.多用于多行的宏定义中.例如:

#define A(x)  T_##x

则 int A(1) = 10; //等效于int T_1 = 10;

#define A(x)  Tx##__

则 int A(1) = 10; //等效于int T1__ = 10;

   2) 前加#@,将标记转换为相应的字符,注意:仅对单一标记转换有效(理解有误?)

 #define B(x) #@x

 则B(a)即’a’,B(1)即’1’.但B(abc)却不甚有效.

   3) 前加#,将标记转换为字符串.

 #define C(x) #x

 则C(1+1) 即 ”1+1”.

4. 定义多行宏:注意斜杠的使用,最后一行不能用斜杠.

 #define DECLARE_RTTI(thisClass, superClass)\

  virtual const char* GetClassName() const\ 

  {return #thisClass;}\

  static int isTypeOf(const char* type)\

  {\

   if(!strcmp(#thisClass, type)\

    return 1;\

   return superClass::isTypeOf(type);\

   return 0;\

  }\

  virtual int isA(const char* type)\

  {\

   return thisClass::isTypeOf(type);\

  }\

  static thisClass* SafeDownCast(DitkObject* o)\

  {\

   if(o&&o->isA(#thisClass))\

    return static_cast<thisClass*>(o);\

   return NULL;\

  }

5. 用于条件编译:(常用形式)

 #ifndef _AAA_H

 #define _AAA_H

 //c/c++代码

 #endif

在大规模的开发过程中,特别是跨平台和系统的软件里,define最重要的功能是条件编译。就是:

#ifdef WINDOWS
......
......

#endif

#ifdef LINUX
......
......
#endif
可以在编译的时候通过#define设置编译环境

5.如何定义宏、取消宏

//定义宏
#define [MacroName] [MacroValue]

//取消宏
#undef [MacroName]

普通宏
#define PI (3.1415926)

带参数的宏
#define max(a,b) ((a)>(b)? (a),(b))

关键是十分容易产生错误,包括机器和人理解上的差异等等。

6.条件编译

#ifdef XXX…(#else) …#endif

例如 #ifdef DV22_AUX_INPUT

#define AUX_MODE 3 

#else

#define AUY_MODE 3

#endif

#ifndef XXX … (#else) … #endif

7.头文件(.h)可以被头文件或C文件包含;

重复包含(重复定义)

由于头文件包含可以嵌套,那么C文件就有可能包含多次同一个头文件,就可能出现重复定义的问题的。

通过条件编译开关来避免重复包含(重复定义)

例如

#ifndef __headerfileXXX__

#define __headerfileXXX__

文件内容

#endif 

8. 一些注意事项:

  1) 不能重复定义.除非定义完全相同.#define A(x) … 和#define A 是重复定义.

  2) 可以只定义符号,不定义值.如#define AAA