3

对于某些类型的程序,我需要使用恒定的高值来指示某些变量的某些属性。我的意思是color[i] = 1000000;如果i树中的节点未被探索,则让。但是我经常在最后写错 0 的数量,所以我只是想知道这样做是否更好:

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

我记得在某处我读到过,最好避免使用#define。这样对吗?你将如何解决这个问题?

4

3 回答 3

5

对于简单的常量,您可以使用或者使用constnew constexpr

constexpr unsigned int UNEXPLORED = 1000000;

const在这种情况下,使用和没有区别constexpr。但是,标记的“变量”constexpr在编译时而不是在运行时进行评估,并且可以在仅接受文字的地方使用。

于 2013-03-05T08:13:51.940 回答
4

例如使用常量。

const unsigned int UNEXPLORED = 1000000;

或枚举

enum { UNEXPLORED = 1000000 };
于 2013-03-05T08:13:04.510 回答
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用于常量的 s 视为一种特殊的宏。

使用宏您还可以传递参数,我发现它对于在代码上执行日志记录/异常策略特别有用。例如

#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" );

该代码允许我确保每个人都使用引发异常的文件行记录。

模板通常是比宏更好的选择,但我不能在这个例子中使用模板函数,因为我需要从 throw 的位置使用__LINE__and__FILE__函数,而不是从模板函数的位置。

哪里不应该使用宏?你可以在任何地方使用其他东西。像任何宏一样,宏#define是经过预处理的,因此编译器根本看不到它们。这意味着永远不会为HELLO_MACor创建任何符号THROW_EXCEPT,因此在调试器中看不到它们。如果您遇到编译错误,它们也可能会令人困惑,尤其是当它们是长宏时。

于 2013-03-05T09:42:31.353 回答