指针类型

要明白指针,需要知道几个概念:指针地址指针类型指针取值

取指针地址

每个变量在运行时都拥有一个地址,这个地址代表变量在内存中的位置,使用 & 放在变量前面进行“取指针地址”操作

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 指针,栈与堆的更多相关文章

  1. Android For JNI(四)——C的数组,指针长度,堆内存和栈内存,malloc,学生管理系统

    Android For JNI(四)--C的数组,指针长度,堆内存和栈内存,malloc,学生管理系统 好几天每写JNI了,现在任务也越来越重了,工作的强度有点高,还有好几个系列的博客要等着更新,几本 ...

  2. 栈 堆 stack heap 堆内存 栈内存 内存分配中的堆和栈 掌握堆内存的权柄就是返回的指针 栈是面向线程的而堆是面向进程的。 new/delete and malloc/ free 指针与内存模型

    小结: 1.栈内存 为什么快? Due to this nature, the process of storing and retrieving data from the stack is ver ...

  3. 【译】.NET中六个重要的概念:栈、堆、值类型、引用类型、装箱和拆箱

    为何要翻译 一来是为了感受国外优秀技术社区知名博主的高质量文章,二来是为了复习对.NET技术的基础拾遗达到温故知新的效果,最后也是为了锻炼一下自己的英文读写能力.因为是首次翻译英文文章(哎,原谅我这个 ...

  4. .NET中六个重要的概念:栈、堆、值类型、引用类型、装箱和拆箱 (转)

    作者: Edison Chou  来源: 博客园  发布时间: 2014-09-03 15:59  阅读: 318 次  推荐: 2   原文链接   [收藏]   原文作者:Shivprasad k ...

  5. .NET中的六个重要概念:栈、堆、值类型、引用类型、装箱和拆箱

    为何要翻译 一来是为了感受国外优秀技术社区知名博主的高质量文章,二来是为了复习对.NET技术的基础拾遗达到温故知新的效果,最后也是为了锻炼一下自己的英文读写能力.因为是首次翻译英文文章(哎,原谅我这个 ...

  6. 值类型,引用类型,栈,堆,ref,out

    在网上收集... C#的值类型,引用类型,栈,堆,ref,out C# 的类型系统可分为两种类型,一是值类型,一是引用类型,这个每个C#程序员都了解.还有托管堆,栈,ref,out等等概念也是每个C# ...

  7. .NET六大剑客:栈、堆、值类型、引用类型、装箱和拆箱

    .NET六大剑客:栈.堆.值类型.引用类型.装箱和拆箱 一.“堆”,“栈”专区 这两个字我相信大家太熟悉了,甚至于米饭是什么?不知道...“堆”,“栈”是什么?哦,这个知道... 之前我也写过一篇堆栈 ...

  8. .NET中栈和堆的比较 #1

    原文出处:http://www.c-sharpcorner.com/UploadFile/rmcochran/csharp_memory01122006130034PM/csharp_memory.a ...

  9. jvm栈和堆详解

    Java把内存分成两种,一种叫做栈内存,一种叫做堆内存 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配.当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间 ...

随机推荐

  1. Tosca new project Repository as MS SQL Server

    # 然后对应的服务器就能自己给创建对应的数据库

  2. java 虚拟机类加载 及内存结构

    http://www.jb51.net/article/105920.htm https://www.cnblogs.com/Qian123/p/5707562.html Java类加载全过程 一个j ...

  3. 用python查看文件是否存在的三种方式

    目录 1.使用os模块 判断文件是否可做读写操作 2.使用Try语句 3. 使用pathlib模块 正文 通常在读写文件之前,需要判断文件或目录是否存在,不然某些处理方法可能会使程序出错.所以最好在做 ...

  4. 123457123457---com.threeObj03.MaJiangertong--- 记忆翻牌益智游戏

    com.threeObj03.MaJiangertong--- 记忆翻牌益智游戏

  5. Hive实现WordCount详解

    一.WordCount原理 初学MapReduce编程,WordCount作为入门经典,类似于初学编程时的Hello World.WordCount的逻辑就是给定一个/多个文本,统计出文本中每次单词/ ...

  6. ElasticSearch——路由(_routing)机制

    前言 一条数据是如何落地到对应的shard上的? 当索引一个文档的时候,文档会被存储到一个主分片中. Elasticsearch 如何知道一个文档应该存放到哪个分片中呢? 首先这肯定不会是随机的,否则 ...

  7. ADFS RelayState

    https://blogs.technet.microsoft.com/askds/2012/09/27/ad-fs-2-0-relaystate/ 什么是RelayState,我为什么要关心?有两种 ...

  8. Git操作记录、腾讯工蜂

    腾讯工蜂: http://git.code.tencent.com 登录-->>创建项目-->>获取仓库路径 https://git.code.tencent.com/dang ...

  9. [转载]DriverStore文件夹特别大,能删除吗?

    [转载]DriverStore文件夹特别大,能删除吗? 转自博客园https://www.cnblogs.com/lovebing/p/6951833.html 这篇文章,清理完C盘多了20G!不要太 ...

  10. Android Studio优化编译速度

    随着Android Studio的不断完善,其安卓开发者阵营也基本从Eclipse转移到了Android Studio,毕竟Android Studio是谷歌亲力亲为开发的官方开发软件.不过其最重要的 ...