这是我参与2022首次更文挑战的第27天,活动详情查看:2022首次更文挑战
在 c/c++ 语言中,提到常量用途,可以是定义数组的长度、阈值或者最大值等。这些常量通常在程序中是不变,在 c++ 中,提供多种定义常量方式,今天我们来聊一聊其中两种常用的方式,分别是 const 和 define 方式,他们之间共同之处以及不同之处,以及他们更适合什么样的场合。
由于对 visual studio 的快捷键不太熟悉,所以解释一下注释快捷键 ctrl + K + C
#include <stdio.h>
#define ARRAY_LENGTH 12
//const int ARRAY_LENGTH =12;
int main()
{
printf("%d\n", ARRAY_LENGTH);
return 0;
}
通常我们定义常量会用 #define ARRAY_LENGTH 12 和 const int ARRAY_LENGTH =12; 这两种方式来定义一个常量,那么这两种方式又有什么不同呢?只有了解他们之间区别才能更好使用他们,在不同场景和需求选择正确方式来定义一个常量
#define ARRAY_LENGTH 12是在预处理也就是编译之前,将 ARRAY_LENGTH 替换为 12 ,那么对于 const int ARRAY_LENGTH =12; 则是我们定义了变量来储存 12 这是一个变量,所以对于变量赋值发生在编译阶段,同时通过 const 告诉编译器不可以修改这个变量的值,这是一个静态的变量。
那么时候使用 const ,首先这样定义静态变量是可以指定类型,而且我们可以将静态变量生命周期限定到一个作用域范围的。
int main()
{
const int ARRAY_LENGTH =12;
printf("%d\n", ARRAY_LENGTH);
return 0;
}
这样好处是可以避免命名冲突。既然 const 定义静态变量这么好,我们为什么还需要 define 这种方式,define 也有自己有点优点,就是我们通过 gcc 和 clang 这样命令在不通过修改 source 情况下,在编译命令时对这个变量进行赋值
#include <stdio.h>
#define ARRAY_LENGTH 12
int main(){
printf("%d\n",ARRAY_LENGTH)
}
#include <stdio.h>
//#define ARRAY_LENGTH 12
int main(){
printf("%d\n",ARRAY_LENGTH);
}
现在我们就去看看如何在编译过程通过命令语句来更改常量,而无需修改源码就可以更改常量,从而得到通过常量得到不同版本。
all: test
test: test.c
$(CC) $(CFLAGS) -DARRAY_LENGTH=12 $< -o $@
$(CC) $(CFLAGS) -DARRAY_LENGTH=120 $< -o $@.big
clean:
$(RM) test
$(RM) -r *.dSYM
我们现在将 Makefile 文件进行适当的修改,将其恢复原有的模样。
all: test
test: test.c
$(CC) $(CFLAGS) $< -o $@
clean:
$(RM) test
$(RM) -r *.dSYM
通过 const 定义常量是,首先我们明确地告诉这个变量是常量,而且明确其类型。而且这样常量是对应于一个作用域,往往不是全局的,这样也就是避免了命名冲突。
int main(){
const int ARRAY_LENGTH = 12;
printf("%d\n",ARRAY_LENGTH);
}
ARRAY_LENGTH = 120;
当然我们可以一些方法来实现对常量的修改,例如如下方式,不过既然我们将其定义为常量,就不要随意将其修改,不然也就是失去其常量含义。
int main(){
const int ARRAY_LENGTH = 12;
int *p = &ARRAY_LENGTH;
*p = 120;
printf("%d\n",ARRAY_LENGTH);
}
test.c:11:14: warning: initialization discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
int *p = &ARRAY_LENGTH;