从一道题目入手浅谈常量

从一道题目入手浅谈常量

我们先来看一段代码:

const cl = 100

var bl = 123

func main() {

fmt.Println(&bl, bl)

fmt.Println(&cl, cl)

}

问:这段代码有什么问题?

答:invalid operation: cannot take address of cl (untyped int constant 100)

常量不同于变量的在运行期分配内存,常量通常会被编译器在预处理阶段直接展开,作为指令数据使用。

接下来我们要先了解一下内存四区的概念:

A.数据类型本质

固定内存大小的别名。

B.数据类型的作用

编译器预算对象(变量)分配的内存空间大小。

C.内存四区

流程说明:

操作系统把物理硬盘代码load到内存操作系统把C语言代码分成四个区操作系统找到main函数入口执行

栈区(Stack):

​ 空间较小,要求数据读写性能高,数据存放时间较短暂。由编译器自动分配和释放,存放函数的参数值、函数的调用流程方法地址、局部变量等(局部变量如果产生逃逸现象,可能会挂在在堆区)

堆区(heap):

​ 空间充裕,数据存放时间较久。一般由开发者分配及释放(但是Golang中会根据变量的逃逸现象来选择是否分配到栈上或堆上),启动Golang的GC由GC清除机制自动回收。

全局区 - 静态全局变量区:

​ 全局变量的开辟是在程序在main之前就已经放在内存中。而且对外完全可见。即作用域在全部代码中,任何同包代码均可随时使用,在变量会搞混淆,而且在局部函数中如果同名称变量使用:=赋值会出现编译错误。

​ 全局变量最终在进程退出时,由操作系统回收。我们在开发的时候,尽量减少使用全局变量的设计

全局区 - 常量区:

​ 常量区也归属于全局区,常量为存放数值字面值单位,即不可修改。或者说的有的常量是直接挂钩字面值的。

概念都介绍完了,接下来我们来说明为什么常量不可以取地址。

为什么常量不可以取地址?

原因其实很简单:

常量没有地址

因为严格意义上的常量是一种“等效承诺”,只要结果一致,一个常量表达式可以翻译成任何东西,它和内存没有映射关系,所以正常来说在内存里是没有对应地址的。

而表达式则是一种还没有完成的逻辑,取决于表达式的返回值,如果返回值是变量,那么其实是可以取地址的,如果是常量,则取地址是无法完成的。

地址的本质作用是为了方便代码的执行,而常量定义在常量区,在main函数执行之前就已经放在内存中了,代表一种映射关系,与代码的执行没有关系,那么它还要地址的概念干嘛呢?对吧!

相关阅读

幸运彩票APP下载365 《龙腾世纪:审判》当选教皇方法介绍

《龙腾世纪:审判》当选教皇方法介绍

幸运彩票APP下载365 500首粤语歌曲经典老歌:免费收听

500首粤语歌曲经典老歌:免费收听

365bet体育在线比分 《醉玲珑》凤卿尘为什么会有凤家女儿的刺青 凤卿尘是凤家的女儿吗

《醉玲珑》凤卿尘为什么会有凤家女儿的刺青 凤卿尘是凤家的女儿吗

365bet体育在线比分 兄弟战争攻略秘籍

兄弟战争攻略秘籍

365商城怎么下载 “纳滤之父”蓝伟光:真净水背后的故事

“纳滤之父”蓝伟光:真净水背后的故事

幸运彩票APP下载365 广州图书馆·问题与帮助·找不到书该怎么办?

广州图书馆·问题与帮助·找不到书该怎么办?

365bet体育在线比分 收费直播软件有哪些

收费直播软件有哪些

365商城怎么下载 魔兽世界破碎海滩造什么建筑好 不建法师塔的话小心被人打哦

魔兽世界破碎海滩造什么建筑好 不建法师塔的话小心被人打哦

365bet体育在线比分 苹果手机怎么下载迅雷旧版本?

苹果手机怎么下载迅雷旧版本?