在C中的以下陈述中哪一个更好用?
static const int var = 5;
Run Code Online (Sandbox Code Playgroud)
要么
#define var 5
Run Code Online (Sandbox Code Playgroud)
要么
enum { var = 5 };
Run Code Online (Sandbox Code Playgroud)
Jon*_*ler 660
这取决于你需要的价值.你(和其他人到目前为止)省略了第三种选择:
static const int var = 5;
#define var 5
enum { var = 5 };
忽略有关名称选择的问题,然后:
因此,在大多数情况下,更喜欢"枚举"而非替代品.否则,第一个和最后一个要点可能是控制因素 - 如果你需要同时满足这两个要点,你必须更加努力.
如果你问的是C++,那么你每次都会使用选项(1) - 静态const.
Mat*_* M. 273
一般来说:
static const
Run Code Online (Sandbox Code Playgroud)
因为它尊重范围并且是类型安全的.
我能看到的唯一警告:如果你想在命令行上定义变量.还有一个选择:
#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
Run Code Online (Sandbox Code Playgroud)
尽可能使用类型安全的替代方法而不是宏/省略号.
如果你真的需要使用宏(例如,你想要__FILE__
或者__LINE__
),那么你最好非常仔细地命名你的宏:在其命名约定中, Boost推荐所有大写字母,从项目名称开始(这里是BOOST_ ),在阅读库时,您会注意到(通常)后面跟着特定区域(库)的名称,然后是一个有意义的名称.
它通常会使冗长的名字:)
AnT*_*AnT 106
在C中,特别是?在C中,正确答案是:使用#define
(或者,如果适用enum
)
虽然具有对象的作用域和键入属性是有益的,但const
实际上const
C 中的对象(与C++相反)不是真正的常量,因此在大多数实际情况下通常是无用的.
因此,在C中,选择应取决于您计划如何使用常量.例如,您不能将const int
对象用作case
标签(宏将起作用).您不能将const int
对象用作位字段宽度(而宏将起作用).在C89/90中,您不能使用const
对象来指定数组大小(宏将起作用).即使在C99中,const
当您需要非VLA阵列时,也无法使用对象指定数组大小.
如果这对您很重要,那么它将决定您的选择.大多数时候,你别无选择,只能#define
在C中使用.不要忘记另一种选择,它会在C中产生真正的常量enum
.
在C++中,const
对象是真正的常量,所以在C++中,最好更喜欢const
变体(static
尽管不需要在C++中显式).
wra*_*erm 32
static const
和之间的区别在于#define
前者使用内存而后者不使用内存进行存储.其次,你不能传递一个地址,#define
而你可以传递一个地址static const
.实际上,这取决于我们所处的环境,我们需要从这两者中选择一个.在不同情况下,两者都处于最佳状态.请不要认为一个比另一个好...... :-)
如果情况确实如此,丹尼斯·里奇 本来会保持最好的一个......哈哈哈...... :-)
sel*_*tze 19
在C #define
中更受欢迎.您可以使用这些值来声明数组大小,例如:
#define MAXLEN 5
void foo(void) {
int bar[MAXLEN];
}
Run Code Online (Sandbox Code Playgroud)
static const
据我所知,ANSI C不允许您在此上下文中使用s.在C++中,您应该避免在这些情况下使用宏.你可以写
const int maxlen = 5;
void foo() {
int bar[maxlen];
}
Run Code Online (Sandbox Code Playgroud)
static
因为内部链接已经暗示const
[仅限C++] ,所以甚至会遗漏.
Gau*_*ier 14
const
C中的另一个缺点是你不能在初始化另一个时使用该值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;
Run Code Online (Sandbox Code Playgroud)
即使这不适用于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!
Run Code Online (Sandbox Code Playgroud)
我很乐意const
在这些情况下使用打字,否则......
Dav*_*ley 11
如果你能逃脱它,static const
有很多优点.它遵循正常的范围原则,在调试器中可见,并且通常遵循变量服从的规则.
但是,至少在最初的C标准中,它实际上并不是一个常数.如果你使用#define var 5
,你可以写int foo[var];
一个声明,但你不能这样做(除了作为编译器扩展"with static const int var = 5;
.在C++中不是这种情况,static const
版本可以在版本可以使用的任何地方使用#define
,我相信这C99也是如此.
但是,永远不要#define
用小写名称命名常量.在翻译单元结束之前,它将覆盖对该名称的任何可能使用.宏常量应该在它们自己的命名空间中,它通常都是大写字母,可能带有前缀.
始终最好使用const而不是#define.这是因为const由编译器处理,而#define由预处理器处理.就像#define本身不是代码的一部分(粗略地说).
例:
#define PI 3.1416
Run Code Online (Sandbox Code Playgroud)
编译器可能永远不会看到符号名称PI; 在源代码甚至到达编译器之前,它可能被预处理器删除.因此,名称PI可能无法输入到符号表中.如果在编译期间出现涉及使用常量的错误,则可能会造成混淆,因为错误消息可能指的是3.1416,而不是PI.如果在你没有写的头文件中定义PI,你就不知道3.1416来自哪里.
此问题也可能出现在符号调试器中,因为您编程的名称可能不在符号表中.
解:
const double PI = 3.1416; //or static const...
Run Code Online (Sandbox Code Playgroud)
#define var 5
如果你有类似的东西,会给你带来麻烦mystruct.var
.
例如,
struct mystruct {
int var;
};
#define var 5
int main() {
struct mystruct foo;
foo.var = 1;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
预处理器将替换它,代码将无法编译.出于这个原因,传统的编码风格表明所有常量都#define
使用大写字母来避免冲突.
我写了快速测试程序来证明一个区别:
#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);
}
Run Code Online (Sandbox Code Playgroud)
这会编译这些错误和警告:
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
^
Run Code Online (Sandbox Code Playgroud)
请注意,当define给出警告时,枚举会给出错误.
定义
const int const_value = 5;
Run Code Online (Sandbox Code Playgroud)
并不总是定义一个常数值。一些编译器(例如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.
Run Code Online (Sandbox Code Playgroud)
这意味着定义
#define CONST_VALUE 5
Run Code Online (Sandbox Code Playgroud)
是定义无法以任何方式修改的常量值的唯一方法。
尽管问题是关于整数,但值得注意的是,如果您需要常量结构或字符串,#define 和枚举是无用的。它们通常都作为指针传递给函数。(对于字符串,这是必需的;对于结构,它的效率要高得多。)
至于整数,如果您处于内存非常有限的嵌入式环境中,您可能需要担心常量的存储位置以及对它的访问如何编译。编译器可能在运行时添加两个 const,但在编译时添加两个 #define。#define 常量可以转换为一条或多条 MOV [立即] 指令,这意味着该常量有效地存储在程序存储器中。const 常量通常存储在数据存储器中的单独部分中,例如 .const 或 .rodata。在具有哈佛架构的系统中,性能和内存使用可能存在差异,尽管差异可能很小。它们可能对于内部循环的核心优化很重要。
归档时间: |
|
查看次数: |
334151 次 |
最近记录: |