2013-03-05 153 views
2

对于某些类型的程序,我需要使用一个恒定的高值来指示某些变量的某些属性。如果树中的i节点未被探索,我的意思是让color[i] = 1000000;。但我经常miswrite末0的个数,所以我只是想知道是否能够更好地做这种方式:我应该避免在C++中使用#define吗?为什么,我可以使用哪些替代方案?

#define UNEXPLORED 1000000; 
color[i] = UNEXPLORED; 

我记得在某个地方我已阅读,这是更好的避免使用的#define 。这样对吗?你将如何解决这个问题?

+3

浏览此主题。最佳答案从那里 - '#define's'不尊重范围 - http://stackoverflow.com/questions/1944041/advantage-and-disadvantages-of-defines-vs-constants – 2013-03-05 08:14:07

回答

3

对于简单的常量,您可以使用const或新constexpr

constexpr unsigned int UNEXPLORED = 1000000; 

在这样的情况下,它的使用const并没有什么区别constexpr。但是,标记为constexpr的“变量”是在编译时评估的,而不是在运行时评估的,并且可能用于其他地方,否则这些地方只接受文字。

+1

这里有没有什么特别的理由在这里使用'auto'我看到'auto'的主要用途是为了避免重复类型名称或者拼出复杂的嵌套类型,这两者都不是,并且明确地指出类型会提高清晰度(同样,为什么'constexpr',而不是传统的'const'?) – 2013-03-05 08:39:23

+1

@JamesKanze - 在这里使用'auto'会产生一个足够大的整数类型来保存实际值。 'unsigned int'不一定足够大以容纳'1000000',这是宏没有的问题。 – 2013-03-05 12:54:21

+0

@PeteBecker这是一个有趣的方面,我没有想到。根据具体情况,它可能被认为是缺点或优势。 (我假设如果'1000000'不符合'unsigned int',编译器至少会发出警告。) – 2013-03-05 13:47:19

2

例如使用常量。

const unsigned int UNEXPLORED = 1000000; 

或枚举

enum { UNEXPLORED = 1000000 }; 
+0

它越来越monre困惑我。 :(我想学习一个特定的部分,然后来成千上万的其他人:(ENUM和STRUCT之间的区别是什么? – gen 2013-03-05 08:21:58

+0

@gen对于这样的问题,我建议你抓住一个[good书籍](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list)来指导你的学习。 – Angew 2013-03-05 08:26:24

+0

@Angew非常感谢你的确很不错:) – gen 2013-03-05 08:30:19

0

在使用常量时,上面的两个答案是正确的,但#define不限于单独使用。使用#define的另一个示例是宏。

宏是代码的预处理,利用片,他们的工作完全一样在这方面其他#define声明。预处理器将用宏的代码从字面上替换已定义符号的出现。举个例子:

#define HELLO_MAC do{ std::cout << "Hello World" << std::endl; }while(false) 

int main(int argc, char** argv) 
{ 
    HELLO_MAC; 
} 

这将字面上我宣布码掉出HELLO_MAC符号。如果它是一个常数,它会做同样的事情。所以你可以把#define作为一个特殊的宏来考虑。

使用宏,你也可以传递参数,这对于通过代码实施日志/异常策略非常有用。 例如

#define THROW_EXCEPT(ex_type, ex_msg)/
    do{ throw ex_type(buildExString((ex_msg), __LINE__, __FILE__)); }while(false) 

... 
// somewhere else 
THROW_EXCEPT(std::runtime_error, "Unsupported operation in current state"); 

该代码可以让我以确保每个人都与抛出异常的文件的行日志。

模板往往是一个更好的选择,而不是宏,而是因为我需要使用__LINE____FILE__功能从废弃的地方,而不是从模板函数的位置,我不能使用模板函数的这个例子。

你应该在哪里不使用宏?任何地方你可以使用别的东西。与任何#define一样,宏也被预处理,所以编译器根本看不到它们。这意味着从来没有为HELLO_MACTHROW_EXCEPT创建任何符号,因此无法在调试器中看到它们。如果你得到编译错误,他们也会感到困惑,特别是如果它们是长宏的话。

相关问题