在C语言中,下列语句中使用哪个更好?
static const int var = 5;
or
#define var 5
or
enum { var = 5 };
在C语言中,下列语句中使用哪个更好?
static const int var = 5;
or
#define var 5
or
enum { var = 5 };
当前回答
一般来说:
static const
因为它尊重作用域并且是类型安全的。
我能看到的唯一警告是:如果您希望变量可能在命令行上定义。还有另一种选择:
#ifdef VAR // Very bad name, not long enough, too general, etc..
static int const var = VAR;
#else
static int const var = 5; // default value
#endif
尽可能使用类型安全的替代方法,而不是宏/省略号。
如果你真的需要使用宏(例如,你想要__FILE__或__LINE__),那么你最好非常小心地命名你的宏:在它的命名约定中,Boost推荐所有大写字母,以项目的名称(这里是BOOST_)开头,而仔细阅读库,你会注意到这(通常)后面是特定区域(库)的名称,然后是一个有意义的名称。
它通常会产生很长的名字:)
其他回答
的定义
const int const_value = 5;
并不总是定义一个常数值。一些编译器(例如tcc 0.9.26)只分配名称为“const_value”的内存。使用标识符“const_value”你不能修改这个内存。但是你仍然可以使用另一个标识符来修改内存:
const int const_value = 5;
int *mutable_value = (int*) &const_value;
*mutable_value = 3;
printf("%i", const_value); // The output may be 5 or 3, depending on the compiler.
这意味着定义
#define CONST_VALUE 5
是定义一个不能用任何方法修改的常数值的唯一方法。
一个简单的区别:
在预处理时,常量被替换为它的值。 因此,不能将解引用操作符应用于定义,但可以将解引用操作符应用于变量。
如您所料,define比static const更快。
例如,有:
#define mymax 100
你不能做printf("address of constant is %p",&mymax);
但是有
const int mymax_var=100
你可以做printf("address of constant is %p",&mymax_var);
更清楚地说,define在预处理阶段被它的值替换,因此程序中没有存储任何变量。我们只有使用define的程序文本段的代码。
然而,对于static const,我们有一个被分配到某处的变量。对于gcc,静态const分配在程序的文本段中。
上面,我想讲的是引用操作符,所以用引用替换解引用。
如果你可以使用它,静态const有很多优点。它遵循正常的作用域原则,在调试器中可见,并且通常遵守变量所遵循的规则。
然而,至少在最初的C标准中,它实际上不是一个常数。如果你使用#define var 5,你可以写int foo[var];作为一个声明,但你不能这样做(除非作为一个编译器扩展“与静态const int var = 5;;在c++中不是这样,静态const版本可以在#define版本可以使用的任何地方使用,我相信C99也是如此。
但是,永远不要用小写名称命名#define常量。它将覆盖该名称的任何可能使用,直到翻译单元结束。宏常量应该在实际上属于它们自己的名称空间中,传统上都是大写字母,可能还有一个前缀。
顺便说一句,#define的另一个选择是“enum”,它提供了适当的作用域,但表现得像一个“真正的”常量。例如:
enum {number_ten = 10;}
在许多情况下,定义枚举类型并创建这些类型的变量是有用的;如果这样做了,调试器可能能够根据变量的枚举名称显示变量。
然而,这样做有一个重要的警告:在c++中,枚举类型与整数的兼容性有限。例如,默认情况下,不能对它们进行算术运算。我发现这是枚举的一个奇怪的默认行为;虽然有一个“严格的enum”类型会很好,但考虑到c++通常与C兼容,我认为“enum”类型的默认行为应该与整数互换。
C中const的另一个缺点是不能在初始化另一个const时使用该值。
static int const NUMBER_OF_FINGERS_PER_HAND = 5;
static int const NUMBER_OF_HANDS = 2;
// initializer element is not constant, this does not work.
static int const NUMBER_OF_FINGERS = NUMBER_OF_FINGERS_PER_HAND
* NUMBER_OF_HANDS;
即使这对const也不起作用,因为编译器不会将其视为常量:
static uint8_t const ARRAY_SIZE = 16;
static int8_t const lookup_table[ARRAY_SIZE] = {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; // ARRAY_SIZE not a constant!
我很乐意在这些情况下使用类型化的const,否则…