C+中的#define指令的目的是什么+;? 代码< >代码>指令> < p> 定义> 用于在C和C++中创建宏。你可以在网站上阅读更多关于它的信息。快速的答案是它可以做一些事情:
简单的宏-基本上只是文本替换。编译时常量就是一个很好的例子:C+中的#define指令的目的是什么+;? 代码< >代码>指令> < p> 定义> 用于在C和C++中创建宏。你可以在网站上阅读更多关于它的信息。快速的答案是它可以做一些事情:,c++,c-preprocessor,C++,C Preprocessor,简单的宏-基本上只是文本替换。编译时常量就是一个很好的例子: #define SOME_CONSTANT 12 只要将出现在代码中的文本SOME_CONSTANT替换为12。这类宏通常用于提供代码块的条件编译。例如,项目中的每个源文件可能包含一个标题,其中包含项目的选项列表: #define OPTION_1 #define OPTION_2 #undef OPTION_3 然后,项目中的代码块将使用匹配的#ifdef/#endif块进行包装,以在完成的项目中启用和禁用这些选项。使用-Dg
#define SOME_CONSTANT 12
只要将出现在代码中的文本SOME_CONSTANT
替换为12
。这类宏通常用于提供代码块的条件编译。例如,项目中的每个源文件可能包含一个标题,其中包含项目的选项列表:
#define OPTION_1
#define OPTION_2
#undef OPTION_3
然后,项目中的代码块将使用匹配的#ifdef
/#endif
块进行包装,以在完成的项目中启用和禁用这些选项。使用-D
gcc标志将提供类似的行为。然而,对于这种方法是否真的是为应用程序提供配置的好方法,存在着强烈的意见
#define SQUARE(x) ((x) * (x))
将返回参数的平方作为其结果;注意潜在的操作顺序或副作用问题!下面是一个例子:
int x = SQUARE(3); // becomes int x = ((3) * (3));
威尔工作正常,但有点像:
int y = SQUARE(f()); // becomes int y = ((f()) * (f()));
将调用f()
两次,甚至更糟:
int z = SQUARE(x++); // becomes int z = ((x++) * (x++));
导致未定义的行为
使用某些工具,还可以使用带有参数的宏,这很方便#define DEBUG
#ifdef DEBUG
//perform debug code
#endif
< C或C++ > <强>定义> <强>允许您创建预处理器宏。
在正常的C或C++构建过程中,首先发生的是预处理器运行,预处理器看起来是预处理器指令的源文件,比如“强> >定义< <强> >或<强>包含< /强>,然后执行简单操作。< /P> 对于#define指令,预处理器执行简单的基于文本的替换
例如,如果你有代码#define PI 3.14159f
float circum = diameter*PI;
预处理器会将其转换为:
float circum = diameter* 3.14159;
通过简单地用相应的文本替换PI的实例。这只是#define语句的最简单形式,用于更高级的用途请从MSDN中查看此语句
{
#define的作用是让继承您代码的人措手不及,比如:
foreverandever
因为:
#define foreverandever for(;;)
}
请支持常数而不是定义
它还用于设置编译器指令…define指令有两种常见用途
第一个是控制编译器将如何操作。要做到这一点,我们还需要#undef、#ifdef和#ifndef。(和#endif too…)
您可以用这种方式创建“编译器逻辑”。常见的用法是激活或不激活代码的调试部分,如下所示:
#ifdef DEBUG
//debug code here
#endif
例如,您可以通过编写#define debug来编译调试代码
这种逻辑的另一个用途是避免双重包含
例如,文件A#包括文件B和C。但文件B也包括C。这可能会导致编译错误,因为“C”存在两次
解决方案是:
#ifndef C_FILE_INCLUDED
#define C_FILE_INCLUDED
//the contents of header "c" go here.
#endif
#define的另一个用法是make宏
最简单的是由简单的替换组成,如:
#define PI 3.14159265
float perimeter(float radius) {
return radius*2*PI;
}
或
然后还可以生成接受参数的宏,printf本身通常是一个宏,在头文件中使用#define创建
但这不应该这样做,因为有两个原因:
首先,速度OS宏与内联相同,第二,我们有C++模板,允许对变量类型的函数进行更多的控制。因此,使用带有参数的宏的唯一原因是生成奇怪的构造,这以后很难理解,比如元编程的东西…到目前为止,\define
最常用的用法是用于包含保护:
// header.hh
#ifndef HEADER_HH_
#define HEADER_HH_
namespace pony {
// ...
}
#endif
#define
的另一个常见用法是创建一个配置文件,通常是一个config.h文件,我们在其中根据各种状态和条件定义宏。然后,在我们的代码中,我们使用#ifdef
、#elif defined()
等测试这些宏,以支持不同情况下的不同编译。这不像include-guard习惯用法那样可靠,在这里您需要小心,因为如果分支错误,那么您可能会得到非常模糊的编译器错误,或者更糟糕的是,运行时行为
一般来说,除了include-guard,您需要仔细考虑(最好两次)这个问题,看看是否可以使用编译器而不是预处理器来解决它。编译器比预处理器更聪明。不仅如此,编译器也不可能混淆预处理器,而预处理器最能迷惑和误导编译器。 < P>大多数关于“X”定义的事情已经被告知,但不清楚C++对它们的大多数使用有更好的替代:
// header.hh
#ifndef HEADER_HH_
#define HEADER_HH_
namespace pony {
// ...
}
#endif
const int max_array_size=50;
int an_array[max_array_size];
#define MAX(a,b) ((a)<(b)?(b):(a))
template<typename T> T & max(T & a, T & b)
{
return a<b?b:a;
}