将代码放到.c
文件中,以C语言的方式编译,运行结果为99
。再将代码放到.cpp
文件中,以C++的方式编译,运行结果就变成了10
。这种差异正是由于C和C++对 const 的处理方式不同造成的。
在C语言中,使用 printf 输出 n 时会到内存中获取 n 的值,这个时候 n 所在内存中的数据已经被修改成了 99,所以输出结果也是 99。而在C++中,printf("%d\n", n);
语句在编译时就将 n 的值替换成了 10,效果和printf("%d\n", 10);
一样,不管 n 所在的内存如何变化,都不会影响输出结果。
当然,这种修改常量的变态代码在实际开发中基本不会出现,本例只是为了说明C和C++对 const 的处理方式的差异:C语言对 const 的处理和普通变量一样,会到内存中读取数据;C++ 对 const 的处理更像是编译时期的#define
,是一个值替换的过程。
C++中全局 const 变量的可见范围是当前文件
我们知道,普通全局变量的作用域是当前文件,但是在其他文件中也是可见的,使用extern
声明后就可以使用,这在《C语言头文件的编写》一章中进行了深入讲解。下面是多文件编程的演示代码:
代码段1(源文件1):
#include <stdio.h>
int n = 10;
void func();
int main(){
func();
printf(“main: %d\n”, n);
return 0;
}
代码段2(源文件2):
#include <stdio.h>
extern int n;
void func(){
printf(“module: %d\n”, n);
}
不管是以C还是C++的方式编译,运行结果都是:
module: 10
main: 10
在C语言中,const 变量和普通变量一样,在其他源文件中也是可见的。修改代码段1,在 n 的定义前面加 const 限制,如下所示:
const int n = 10;
修改后的代码仍然能够正确编译,运行结果和上面也是一样的。这说明C语言中的 const 变量在多文件编程时的表现和普通变量一样,除了不能修改,没有其他区别。
但是如果按照C++的方式编译(将源文件后缀设置为.cpp
),修改后的代码就是错误的。这是因为 C++ 对 const 的特性做了调整,C++ 规定,全局 const 变量的作用域仍然是当前文件,但是它在其他文件中是不可见的,这和添加了static
关键字的效果类似。虽然代码段2中使用 extern 声明了变量 n,但是在链接时却找不到代码段1中的 n。
由于 C++ 中全局 const 变量的可见范围仅限于当前源文件,所以可以将它放在头文件中,这样即使头文件被包含多次也不会出错,请看下面的例子。
module.h 代码:
const int n = 10;
void func();
module.cpp 代码:
#include <stdio.h>
#include “module.h”
void func(){
printf(“module: %d\n”, n);
}
main.cpp 代码:
#include <stdio.h>
#include “module.h”
int main(){
func();
printf(“main: %d\n”, n);
return 0;
}
运行结果:
module: 10
main: 10
C和C++中全局 const 变量的作用域相同,都是当前文件,不同的是它们的可见范围:C语言中 const 全局变量的可见范围是整个程序,在其他文件中使用 extern 声明后就可以使用;而C++中 const 全局变量的可见范围仅限于当前文件,在其他文件中不可见,所以它可以定义在头文件中,多次引入后也不会出错。
如果你使用的是 GCC,那么可以通过添加 extern 关键字来增大 C++ 全局 const 变量的可见范围,如下所示:
extern const int n = 10;
这样 n 的可见范围就变成了整个程序,在其他文件中使用 extern 声明后就可以使用了。不过这种方式只适用于 GCC,不适用于 VS/VC。
总结
C++ 中的 const 变量虽然也会占用内存,也能使用&
获取得它的地址,但是在使用时却更像编译时期的#define
;#define
也是值替换,可见范围也仅限于当前文件。
很多C++教程在对比 const 和 #define 的优缺点时提到,#define 定义的常量仅仅是字符串的替换,不会进行类型检查,而 const 定义的常量是有类型的,编译器会进行类型检查,相对来说比 #define 更安全,所以鼓励大家使用 const 代替 #define。
这种说法虽然没错,但是我没有发现不进行类型检查有什么隐患,我在使用 #define 的过程中也没有发现什么缺点,所以我对上面的观点持保留态度,也请大家多多指点。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Go语言工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Go语言全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Golang知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Go)
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
Go)**
[外链图片转存中…(img-9Y1eDTUp-1712861584856)]
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!