Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C &引用;“静态常数”;vs"#定义;vs";“枚举”;_C_Constants - Fatal编程技术网

C &引用;“静态常数”;vs"#定义;vs";“枚举”;

C &引用;“静态常数”;vs"#定义;vs";“枚举”;,c,constants,C,Constants,在C语言的下列语句中,哪一个更适合使用 static const int 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;

在C语言的下列语句中,哪一个更适合使用

static const int 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
尽可能使用类型安全选项,而不是宏/省略号

如果您真的需要使用宏(例如,您想要
\uuuuuu文件\uuuuuuu
\uuuuuuu行\uuuuuuuu
),那么您最好非常小心地命名宏:在它的建议中,以项目名称开头(此处为BOOST),在仔细阅读库时,您会注意到这是(通常)后跟特定区域(库)的名称,然后使用有意义的名称


它通常会产生冗长的名称:)

不要认为“哪一个总是最好的”是有答案的,但正如马修所说

静态常数

是类型安全的。不过,我对
#define
最恼火的地方是在中调试时无法查看变量。它给出了一个找不到符号的错误。

在C
中,define
更受欢迎。您可以使用这些值来声明数组大小,例如:

#define MAXLEN 5

void foo(void) {
   int bar[MAXLEN];
}
enum {number_ten = 10;}
据我所知,ANSI C不允许在此上下文中使用
static const
s。在C++中,在这些情况下应该避免宏。你可以写

const int maxlen = 5;

void foo() {
   int bar[maxlen];
}

甚至忽略了代码>静态< /代码>,因为内部链接由<代码> const <代码> > [C++中只有]。在C中,正确答案是:使用

#define
(或者,如果合适,使用
enum

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

因此,在C中,选择应该由您计划如何使用常量来决定。例如,不能将
const int
对象用作
大小写
标签(而宏可以工作)。不能将
const int
对象用作位字段宽度(而宏可以工作)。在C89/90中,不能使用
const
对象指定数组大小(而宏可以工作)。即使在C99中,当需要非数组时,也不能使用
const
对象来指定数组大小

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


<> > C++中的代码> const 对象是真的常量,所以在C++中,最好是选择< <代码> const 变体(不需要在C++中显式<代码>静态< /代码>)。

如果你能逃脱它,静态const <代码>有很多优点。它遵循正常的作用域原则,在调试器中可见,并且通常遵循变量所遵循的规则

然而,至少在最初的C标准中,它实际上不是一个常数。如果使用
#define var 5
,则可以编写
int foo[var]作为一个声明,但您不能这样做(除了编译器扩展名),代码<静态const int var=5;< />代码>,C++中没有这种情况,其中<代码>静态const <代码>版本可以在任何地方使用<代码>定义< /COD>版本CAN,并且我相信这也是C99 ./P>的情况。

但是,切勿使用小写名称命名
#定义
常量。在翻译单元结束之前,它将覆盖该名称的任何可能使用。宏常量应位于其自己的名称空间中,通常都是大写字母,可能带有前缀。

这取决于您需要的值f或者,您(以及目前为止的其他所有人)忽略了第三种选择:

#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
  • static const int var=5;
  • #定义变量5
  • enum{var=5};
  • 忽略有关名称选择的问题,然后:

    • 如果需要传递指针,则必须使用(1)
    • 因为(2)显然是一个选项,所以不需要到处传递指针
    • (1)和(3)在调试器的符号表中都有一个符号,这使得调试更容易。更可能的是(2)没有符号,让您想知道它是什么
    • (1) 不能用作全局范围内数组的维度;(2)和(3)都可以
    • (1) 不能用作函数作用域中静态数组的维度;(2)和(3)都可以
    • 在C99下,所有这些都可以用于本地数组。从技术上讲,使用(1)意味着使用VLA(可变长度数组),尽管“var”引用的维度当然会固定为大小5
    • (1) 不能在switch语句等位置使用;(2)和(3)都可以
    • (1) 无法用于初始化静态变量;(2)和(3)都可以
    • (2) 可以更改您不希望更改的代码,因为预处理器正在使用该代码;(1)和(3)都不会产生意外的副作用
    • 您可以检测是否在预处理器中设置了(2);(1)和(3)都不允许这样做
    因此,在大多数情况下,选择“枚举”而不是备选方案。否则,第一个和最后一个要点很可能是控制因素——如果需要同时满足这两个要点,你必须更加仔细地思考


    <>强>如果你问C++,那么你会使用选项(1)-静态常量-每次。

    静态常量和定义的区别在于前者使用内存,后者不使用内存存储。其次,您不能传递定义的地址,而可以传递静态的地址
    enum {number_ten = 10;}
    
    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;
    
    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!
    
    struct mystruct {
        int var;
    };
    
    #define var 5
    
    int main() {
        struct mystruct foo;
        foo.var = 1;
        return 0;
    }
    
    const int const_value = 5;
    
    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 mymax 100
    
    const int mymax_var=100
    
    #define PI 3.1416
    
    const double PI = 3.1416; //or static 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
            ^