对于某些类型的程序,我需要使用常量高值来指示某些变量的某些属性。我的意思是,如果树中的color[i] = 1000000;
节点未被探测,则允许i
。但是我经常在最后错误地写出0的数量,所以我只是想知道这样做是否更好:
#define UNEXPLORED 1000000;
color[i] = UNEXPLORED;
我记得在某些地方我已经读到,避免使用#define要好得多。这样对吗?你会如何解决这个问题?
答案 0 :(得分:4)
对于简单常量,您可以使用const
或新constexpr
:
constexpr unsigned int UNEXPLORED = 1000000;
在这种情况下,使用const
和constexpr
之间没有区别。但是,标记为constexpr
的“变量”在编译时进行评估,而不是在运行时进行评估,并且可以在只接受文字的地方使用。
答案 1 :(得分:3)
例如使用常量。
const unsigned int UNEXPLORED = 1000000;
或枚举
enum { UNEXPLORED = 1000000 };
答案 2 :(得分:0)
在常量的使用中,上面的两个答案是正确的,但#define
并不仅限于使用。{1}}。另一个使用#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" );
该代码允许我确保每个人都记录引发异常的文件行。
模板通常是一个更好的选择而不是宏,但是我不能在这个例子中使用模板函数,因为我需要在throw的位置使用__LINE__
和__FILE__
函数,而不是模板功能的位置。
你应该在哪里使用宏?你可以在任何地方使用其他东西与任何#define
一样,宏都经过预处理,因此编译器根本看不到它们。这意味着永远不会为HELLO_MAC
或THROW_EXCEPT
创建任何符号,因此无法在调试器中看到它们。如果遇到编译错误,它们也会令人困惑,特别是如果它们是长宏。