在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 };
当前回答
在c#中定义更为流行。你可以使用这些值来声明数组大小,例如:
#define MAXLEN 5
void foo(void) {
int bar[MAXLEN];
}
据我所知,ANSI C不允许你在这种情况下使用静态常量。在c++中,在这些情况下应该避免使用宏。你可以写
const int maxlen = 5;
void foo() {
int bar[maxlen];
}
甚至不用static,因为内部链接已经由const隐含[仅在c++中]。
其他回答
在c#中定义更为流行。你可以使用这些值来声明数组大小,例如:
#define MAXLEN 5
void foo(void) {
int bar[MAXLEN];
}
据我所知,ANSI C不允许你在这种情况下使用静态常量。在c++中,在这些情况下应该避免使用宏。你可以写
const int maxlen = 5;
void foo() {
int bar[maxlen];
}
甚至不用static,因为内部链接已经由const隐含[仅在c++中]。
如果你有mystruct.var这样的东西,#define var 5会给你带来麻烦。
例如,
struct mystruct {
int var;
};
#define var 5
int main() {
struct mystruct foo;
foo.var = 1;
return 0;
}
预处理器将取代它,代码将无法编译。因此,传统的编码风格建议所有常量#定义都使用大写字母以避免冲突。
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,否则…
顺便说一句,#define的另一个选择是“enum”,它提供了适当的作用域,但表现得像一个“真正的”常量。例如:
enum {number_ten = 10;}
在许多情况下,定义枚举类型并创建这些类型的变量是有用的;如果这样做了,调试器可能能够根据变量的枚举名称显示变量。
然而,这样做有一个重要的警告:在c++中,枚举类型与整数的兼容性有限。例如,默认情况下,不能对它们进行算术运算。我发现这是枚举的一个奇怪的默认行为;虽然有一个“严格的enum”类型会很好,但考虑到c++通常与C兼容,我认为“enum”类型的默认行为应该与整数互换。
一个简单的区别:
在预处理时,常量被替换为它的值。 因此,不能将解引用操作符应用于定义,但可以将解引用操作符应用于变量。
如您所料,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分配在程序的文本段中。
上面,我想讲的是引用操作符,所以用引用替换解引用。