在C / C ++中,使用#define
[和#ifndef
#endif
]创建值时有什么区别,当您可以使用int
或std::string
[C ++]呢?
#ifndef MYVAL
#define MYVAL(500)
#endif
//C++
cout << MYVAL << endl;
//C
printf(MYVAL);
//C++
int MYVAL = 500;
cout << MYVAL << endl;
//C
int MYVAL = 500;
printf(MYVAL);
答案 0 :(得分:12)
你的假设是错误的。 #define
不会创建“值”,它会在源代码中创建替换文本。它基本上与C或C ++无关。
答案 1 :(得分:6)
在我进入历史之前,这里是对两者之间差异的简要理解。
变量是变量。它们占用编译程序中的空间,除非用const
标记它们(这是一个比宏更晚的开发),它们是可变的。
另一方面,宏是预处理。编译器永远不会看到宏。而是在编译之前处理宏。预编译器遍历代码,查找每个宏,并将其与宏文本逐字替换。这可能非常强大,有点用,而且相当危险(因为它修改代码并且在执行此操作时从不进行任何检查)。
此外,可以在命令行上设置宏。您可以在编译时根据需要定义任意数量的内容,如果您的代码检查该宏,则它的行为可能会有所不同。
宏在C ++之前很久就存在了。它们对很多东西很有用:
const
说明符之前,因此它们是维护常量“变量”的简单方法“ - 预编译器会将所有MYVAR实例替换为500。在有限的情况下,你只是使用一个宏来表示一个常量表达式,你是对的 - 它们不再需要它们了。
答案 2 :(得分:5)
不同之处在于,使用宏(#),预处理器会对该符号进行搜索和替换。替换没有类型检查。
当你创建一个变量时,它会被输入,编译器会在你使用它的地方进行类型检查。
C / C ++编译器通常被认为是2遍编译器。第一遍是预处理器,它在宏上进行搜索和替换。第二遍是实际编译,其中创建了声明的变量。
宏通常用于创建更复杂的表达式,因此代码不必重复多次,因此语法更紧凑。它们很有用,但由于它们“盲目”搜索和替换性质而更加危险。此外,您无法使用调试器进入宏,因此可能难以进行故障排除。
此外,宏不遵守任何范围规则。 #define MYVAL(500)
将MYVAL
替换为500
,即使它出现在函数,全局范围,类声明等中,因此您必须更加小心。
答案 3 :(得分:2)
当你#define
时,只要在你的代码中找到它就会被盲目替换:
#define the_answer 42
/// ...
int the_answer = /* oops! */
答案 4 :(得分:2)
您不应该使用#defines的重要原因很少。特别是对于你的问题,我会说,#define是纯文本替换,你不能限制宏的范围。即,您不能指定访问说明符或将其绑定到命名空间,因此一旦定义了宏,就可以在包含define的文件中的任何位置使用它们。
使用'const'变量,您可以将它们绑定在范围
中这些可以提供帮助:http://www.parashift.com/c++-faq/const-vs-define.html
答案 5 :(得分:1)
存在巨大差异:
a)#define MYVAL 500
这将创建一个宏。源代码中的每个出现都将由预处理器替换为其原始值。它完全忽略了范围,您无法更改其值
b)int MYVAL = 500;
这是遵守范围规则的常规变量,i。即当在函数内部声明时,它不能在它外面看到,它可以在另一个函数中被遮蔽等等......
另一方面,变量不能用于预处理器条件(#if
,#endif
块)
最后一个例子:
#define MYVAL 500
int main() {
int MYVAL = 10; // illegal, gets preprocessed as int 500 = 10;
}
与变量相同:
int MYVAL = 500
int main() {
int MYVAL = 10; // legal, MYVAL now references local variable, ::MYVAL is the global variable
}