AnT*_*AnT 101
不,通常你不应该在C中使用const限定对象来创建名称常量.要在C中创建命名常量,您应该使用宏(#define)或枚举.事实上,C语言没有常数,从某种意义上说,你似乎暗示着.(在这方面,C与C++有很大不同)
在C语言中,常量和常量表达式的概念与C++的定义截然不同.在C 常量中表示字面值,如123.以下是C 中常量的一些示例
123
34.58
'x'
Run Code Online (Sandbox Code Playgroud)
C中的常量可用于构建常量表达式.但是,由于任何类型的const限定对象都不是C中的常量,因此它们不能用于常量表达式,因此,您不能使用需要常量表达式的const限定对象.
例如,以下不是常数
const int C = 123; /* C is not a constant!!! */
Run Code Online (Sandbox Code Playgroud)
由于以上C不是常量,因此不能用于在文件范围内声明数组类型
typedef int TArray[C]; /* ERROR: constant expression required */
Run Code Online (Sandbox Code Playgroud)
它不能用作案例标签
switch (i) {
case C: ; /* ERROR: constant expression required */
}
Run Code Online (Sandbox Code Playgroud)
它不能用作位域宽度
struct S {
int f : C; /* ERROR: constant expression required */
};
Run Code Online (Sandbox Code Playgroud)
它不能用作具有静态存储持续时间的对象的初始化程序
static int i = C; /* ERROR: constant expression required */
Run Code Online (Sandbox Code Playgroud)
它不能用作枚举初始值设定项
enum {
E = C /* ERROR: constant expression required */
};
Run Code Online (Sandbox Code Playgroud)
即它不能用于需要常数的任何地方.
这可能看似违反直觉,但这就是C语言的定义方式.
这就是您#define在使用的代码中看到这些众多-s的原因.同样,在C语言中,const-qualified对象的使用非常有限.它们基本上完全没用作"常量",这就是为什么在C语言中你基本上被迫使用#define或枚举来声明真正的常量.
当然,在const限定对象为您工作的情况下,即它完成您希望它做的事情,它确实在很多方面优于宏,因为它是作用域和键入的.在适用的情况下,您可能更喜欢这些对象,但在一般情况下,您必须考虑上述限制.
Leo*_*Hat 10
常数应优先于defines.有几个优点:
类型安全.虽然C是一种弱类型的语言,但是使用了define丢失所有类型的安全性,这将允许编译器为您挑选问题.
易于调试.您可以通过调试器更改常量的值,而defines由代码中的预处理器自动更改为实际值,这意味着如果要更改测试/调试的值,则需要重新编译.
小智 7
也许我一直在使用它们,但至少在gcc中,你不能在case语句中使用常量.
const int A=12;
switch (argc) {
case A:
break;
}
Run Code Online (Sandbox Code Playgroud)
虽然这个问题是针对C的,但我想知道这个很好:
#include<stdio.h>
int main() {
const int CON = 123;
int* A = &CON;
(*A)++;
printf("%d\n", CON); // 124 in C
}
Run Code Online (Sandbox Code Playgroud)
适用于C语言,但不适用于C++语言
使用的一个原因#define是避免这样的事情弄乱你的代码,特别是它是C和C++的混合.
很多人在这里给你提供"C++风格"的建议.有些人甚至说C++参数适用于C.这可能是一个公平的观点.(无论是否感觉有点主观.)const有时说意味着两种语言不同的人也是正确的.
但这些都是小问题而且个人而言,我认为事实上,无论采取哪种方式都会产生相对较小的后果.这是一个风格问题,我认为不同的人群会给你不同的答案.
在常见用法,历史用法和最常见的风格方面,在C中,它更常见#define.在C代码中使用C++主义对C编码器的某个狭窄部分来说可能很奇怪.(包括我,这就是我的偏见所在.)
但我很惊讶没有人提出一个中间解决方案,在两种语言中"感觉正确":如果它适合一组整数常量,请使用enum.