在C语言中,下列语句中使用哪个更好?

static const int var = 5;

or

#define var 5

or

enum { var = 5 };

当前回答

在C语言中?在C语言中,正确的答案是:使用#define(或者,如果合适,使用enum)

虽然具有const对象的作用域和类型属性是有益的,但实际上C中的const对象(与c++相反)并不是真正的常量,因此在大多数实际情况下通常是无用的。

所以,在C语言中,选择应该取决于你计划如何使用常数。例如,你不能使用const int对象作为case标签(而宏可以)。你不能使用const int对象作为位域宽度(而宏可以)。在C89/90中,你不能使用const对象来指定数组大小(而宏可以)。即使在C99中,当你需要一个非vla数组时,你也不能使用const对象来指定数组大小。

如果这对你很重要,那么它将决定你的选择。大多数时候,你别无选择,只能在C中使用#define。不要忘记另一个选择,它在C - enum中产生真正的常量。

在c++中,const对象是真正的常量,所以在c++中,最好使用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++中]。

使用const而不是#define总是更好。这是因为const是由编译器处理的,而#define是由预处理器处理的。这就像#define本身不是代码的一部分(粗略地说)。

例子:

#define PI 3.1416

符号名称PI可能永远不会被编译器看到;它可能在源代码到达编译器之前被预处理器删除。因此,名称PI可能无法进入符号表。如果在编译过程中遇到涉及使用常量的错误,这可能会令人困惑,因为错误消息可能指向3.1416,而不是PI。如果圆周率定义在一个你没有写的头文件中,你就不知道3.1416是从哪里来的。

这个问题也可能在符号调试器中突然出现,因为您正在编程的名称可能不在符号表中。

解决方案:

const double PI = 3.1416; //or static const...

我不确定我是否正确,但在我看来,调用#defined value比调用任何其他正常声明的变量(或const value)快得多。 这是因为当程序运行时,它需要使用一些正常声明的变量,它需要跳转到内存中的确切位置来获得该变量。

相反,当它使用#defined value时,程序不需要跳转到任何已分配的内存,它只是接受该值。如果#define myValue 7和调用myValue的程序,它的行为与只调用7时完全相同。

一个简单的区别:

在预处理时,常量被替换为它的值。 因此,不能将解引用操作符应用于定义,但可以将解引用操作符应用于变量。

如您所料,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分配在程序的文本段中。

上面,我想讲的是引用操作符,所以用引用替换解引用。

我写了一个快速测试程序来证明其中的一个区别:

#include <stdio.h>

enum {ENUM_DEFINED=16};
enum {ENUM_DEFINED=32};

#define DEFINED_DEFINED 16
#define DEFINED_DEFINED 32

int main(int argc, char *argv[]) {

   printf("%d, %d\n", DEFINED_DEFINED, ENUM_DEFINED);

   return(0);
}

这个编译带有以下错误和警告:

main.c:6:7: error: redefinition of enumerator 'ENUM_DEFINED'
enum {ENUM_DEFINED=32};
      ^
main.c:5:7: note: previous definition is here
enum {ENUM_DEFINED=16};
      ^
main.c:9:9: warning: 'DEFINED_DEFINED' macro redefined [-Wmacro-redefined]
#define DEFINED_DEFINED 32
        ^
main.c:8:9: note: previous definition is here
#define DEFINED_DEFINED 16
        ^

注意,当define给出警告时,enum给出一个错误。