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

static const int var = 5;

or

#define var 5

or

enum { var = 5 };

当前回答

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

#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给出一个错误。

其他回答

的定义

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

是定义一个不能用任何方法修改的常数值的唯一方法。

如果你有mystruct.var这样的东西,#define var 5会给你带来麻烦。

例如,

struct mystruct {
    int var;
};

#define var 5

int main() {
    struct mystruct foo;
    foo.var = 1;
    return 0;
}

预处理器将取代它,代码将无法编译。因此,传统的编码风格建议所有常量#定义都使用大写字母以避免冲突。

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

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

静态const和#define之间的区别在于前者使用内存,而后者不使用内存进行存储。其次,您不能传递#define对象的地址,而可以传递静态const对象的地址。实际上,这取决于我们所处的环境,我们需要在这两者中选择一个。两者在不同的情况下都处于最佳状态。请不要认为一个比另一个好。: -)

如果是这样的话,丹尼斯·里奇会把最好的留下来……哈哈哈……: -)

一般来说:

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_)开头,而仔细阅读库,你会注意到这(通常)后面是特定区域(库)的名称,然后是一个有意义的名称。

它通常会产生很长的名字:)