Go part 3 指针,栈与堆
指针类型
要明白指针,需要知道几个概念:指针地址,指针类型 和 指针取值
取指针地址
每个变量在运行时都拥有一个地址,这个地址代表变量在内存中的位置,使用 & 放在变量前面进行“取指针地址”操作
var int a = 10
fmt.Println("address:", &a) // address: 0xc000098010
获取指针类型
package main import (
"fmt"
) func main(){
var a int = 100
addrA := &a
fmt.Printf("pointer type: %T\n",addrA)
} 运行结果:
pointer type: *int
从指针获取指针指向的值
使用 * 方便指针地址前面进行“指针取值”操作
package main import (
"fmt"
) func main(){
var a int = 100
addrA := &a
fmt.Println("address:", addrA) valueA := *addrA
fmt.Println("value:", valueA)
} 结果:
address: 0xc000098010
value: 100
通过指针修改指针指向的值
package main import (
"fmt"
) func main(){
var a int = 100
addrA := &a
fmt.Println("address:", addrA) valueA := *addrA
fmt.Println("value:", valueA) // modify
*addrA = 1
fmt.Println("modify value:", a)
} 运行结果:
address: 0xc000098010
value: 100
modify value: 1
练习1:写一个函数,使用指针交换两个整数的值
package main import (
"fmt"
) func swap(a *int, b *int){
*a, *b = *b, *a
} func main(){
var (
a int = 100
b int = 200
) swap(&a, &b)
fmt.Println(a, b)
} 运行结果:
200 100
练习2:使用指针变量获取命令行参数,经过 flag 包解析后,以指针类型返回,可定义变量接收命令行的数据
package main import (
"flag"
"fmt"
) func main(){
// 接收命令行参数,key,默认值,帮助
var mode = flag.String("mode", "", "process mode") flag.Parse()
fmt.Println(*mode)
} 调用:
go run pointer_03.go --mode "hello, world" 运行结果:
hello, world
创建指针的另一种方法
new() 函数可以创建一个对应类型的指针,创建过程会分配内存,被创建的指针指向的值为默认值
package main import (
"fmt"
) func main(){
var str *string = new(string)
fmt.Println(*str)
*str = "hello, world~"
fmt.Println(*str)
} 运行结果:
// 空字符串
hello, world~
栈与堆
什么是栈
栈(Stack)是一种拥有特殊规则的线性表数据结构
只允许往线性表的一端放入数据,之后在这一端取出数据,按照后进先出(LIFO,Last InFirst Out)的顺序,如下图:

往栈中放入元素的过程叫做入栈,入栈会增加栈的元素数量,最后放入的元素总是位于栈的顶部,最先放入的元素总是位于栈的底部
从栈中取出元素时,只能从栈顶部取出,不允许从栈底获取数据,也不允许对栈成员进行任何查看和修改操作
什么是堆
堆内存分配类似于往一个房间里摆放各种家具,家具的尺寸有大有小,分配内存时,需要找一块足够大小的空间来摆放家具,经过反复摆放和腾空家具后,房间里会变得乱七八糟,此时再往空间里摆放家具会存在虽然有足够的空间,但各空间分布在不同的区域,无法有一段连续的空间来摆放家具的问题,此时,内存分配器就需要对这些空间进行调整优化,如下图:

堆分配内存和栈分配内存相比,堆适合不可预知大小的内存分配。但是为此付出的代价是分配速度较慢,而且会形成内存碎片
堆和栈各有优缺点,该怎么在编程中处理这个问题呢?在 C/C++ 语言中,需要开发者自己学习如何进行内存分配,选用怎样的内存分配方式来适应不同的算法需求。比如,函数局部变量尽量使用栈;全局变量、结构体成员使用堆分配等。程序员不得不花费很多年的时间在不同的项目中学习、记忆这些概念并加以实践和使用。
Go 语言将这个过程整合到编译器中,命名为“变量逃逸分析”。这个技术由编译器分析代码的特征和代码生命期,决定应该如何堆还是栈进行内存分配,即使程序员使用 Go 语言完成了整个工程后也不会感受到这个过程
栈内存中通常分配值类型,包括 int, float, bool, string 以及数组和 struct(结构体)
堆内存中通常分配引用类型,通过 GC 回收,包括 pointer, select, map, chan 等
Go part 3 指针,栈与堆的更多相关文章
- Android For JNI(四)——C的数组,指针长度,堆内存和栈内存,malloc,学生管理系统
Android For JNI(四)--C的数组,指针长度,堆内存和栈内存,malloc,学生管理系统 好几天每写JNI了,现在任务也越来越重了,工作的强度有点高,还有好几个系列的博客要等着更新,几本 ...
- 栈 堆 stack heap 堆内存 栈内存 内存分配中的堆和栈 掌握堆内存的权柄就是返回的指针 栈是面向线程的而堆是面向进程的。 new/delete and malloc/ free 指针与内存模型
小结: 1.栈内存 为什么快? Due to this nature, the process of storing and retrieving data from the stack is ver ...
- 【译】.NET中六个重要的概念:栈、堆、值类型、引用类型、装箱和拆箱
为何要翻译 一来是为了感受国外优秀技术社区知名博主的高质量文章,二来是为了复习对.NET技术的基础拾遗达到温故知新的效果,最后也是为了锻炼一下自己的英文读写能力.因为是首次翻译英文文章(哎,原谅我这个 ...
- .NET中六个重要的概念:栈、堆、值类型、引用类型、装箱和拆箱 (转)
作者: Edison Chou 来源: 博客园 发布时间: 2014-09-03 15:59 阅读: 318 次 推荐: 2 原文链接 [收藏] 原文作者:Shivprasad k ...
- .NET中的六个重要概念:栈、堆、值类型、引用类型、装箱和拆箱
为何要翻译 一来是为了感受国外优秀技术社区知名博主的高质量文章,二来是为了复习对.NET技术的基础拾遗达到温故知新的效果,最后也是为了锻炼一下自己的英文读写能力.因为是首次翻译英文文章(哎,原谅我这个 ...
- 值类型,引用类型,栈,堆,ref,out
在网上收集... C#的值类型,引用类型,栈,堆,ref,out C# 的类型系统可分为两种类型,一是值类型,一是引用类型,这个每个C#程序员都了解.还有托管堆,栈,ref,out等等概念也是每个C# ...
- .NET六大剑客:栈、堆、值类型、引用类型、装箱和拆箱
.NET六大剑客:栈.堆.值类型.引用类型.装箱和拆箱 一.“堆”,“栈”专区 这两个字我相信大家太熟悉了,甚至于米饭是什么?不知道...“堆”,“栈”是什么?哦,这个知道... 之前我也写过一篇堆栈 ...
- .NET中栈和堆的比较 #1
原文出处:http://www.c-sharpcorner.com/UploadFile/rmcochran/csharp_memory01122006130034PM/csharp_memory.a ...
- jvm栈和堆详解
Java把内存分成两种,一种叫做栈内存,一种叫做堆内存 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配.当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间 ...
随机推荐
- python脚本实现-excel二级统计
pandas和SQL数据分析实战视频教程 https://study.163.com/course/courseMain.htm?courseId=1006383008&share=2& ...
- sklearn里计算roc_auc_score,报错ValueError: bad input shape
用sklearn的DecisionTreeClassifer训练模型,然后用roc_auc_score计算模型的auc.代码如下 clf = DecisionTreeClassifier(criter ...
- Android高频单词
Display 显示 Camera 照相机 Bluetooth 蓝牙 Flash Memory 闪存 Audio 音频 Management 管理 SurFace 界面 Media 多媒体 Frame ...
- python定义接口继承类
zxq547 python定义接口继承类invalid syntax解决办法 1 2 3 4 5 6 7 class s_all(metaclass=abc.ABCMeta): #python ...
- 阶段5 3.微服务项目【学成在线】_day18 用户授权_13-细粒度授权-细粒度授权介绍
3 细粒度授权 3.1 需求分析 什么是细粒度授权? 细粒度授权也叫数据范围授权,即不同的用户所拥有的操作权限相同,但是能够操作的数据范围是不一样的.一个 例子:用户A和用户B都是教学机构,他们都拥有 ...
- 编译安装python3事出错:
configure: error: no acceptable C compiler found in $PATH 问题解决 解决方法: yum intall gcc -y
- using kafkacat reset kafka offset
1. install kafkacat Ubuntu apt-get install kafkacat CentOS install deepenency yum install librdkafka ...
- Day6作业:计算器
嗯,稀里糊涂就居然写完了...... readme: 程序说明: 此计算器比较简单,只支持普通的加减乘除和小括号,不支持[],{},求幂之类的均不支持! 测试过的字符串: -1/2*((60-30+( ...
- maven:手动上传jar私服
转:https://www.jianshu.com/p/b8ec688c388e 打包时提示私服中找不到以下jar包 在私服中搜索确实找不到,后来知道这些是老系统的jar包没有deploy到私服 经分 ...
- 【VS开发】【数据库开发】libevent windows下基于VS2010的编译
libevent是一个常用的网络库,下面就看看在windows下面编译测试的过程吧. 一 环境 系统:win8.1编译器:VS2013官方下载地址:http://libevent.org/版本:2.0 ...