指针的定义

指针是一个代表着某个内存地址的值。这个内存地址往往是在内存中存储的另一个变量的值的起始位置。

go指针是提供操作数据的基本桥梁。因为go很多调用,往往复制一份对象,例如函数的参数,如果没有指针,有些情况不得不存在很多副本。

Go语言保留了指针,但与C语言指针有所不同。主要体现在:

  • 默认值 nil
  • 操作符 "&" 取变量地址, "*" 通过指针访问目标对象
  • 不支持指针运算,不支持 "->" 运算符,直接⽤ "." 访问目标成员

概念: linux 程序内存管理

data section (.data)*: 用来存放已经被初始化为非零的全局变量。

bss section (.bbs):用来存放 没有被初始化 和 已经被初始化为0 的全局变量。

rodata section(.rodata): 用来存放常量数据。 ro: read only

text section(.text):存放代码(如:函数)和部分整数常量(应该指的是一些立即数),这个段是可执行的。

heap (堆):动态分配内存,由程序自身决定开辟和释放。

stack(栈): 存放函数的局部变量和函数参数

栈帧:用来给函数运行提供内存空间,取内存于stack上,当函数调用的时候,产生栈帧.函数调用结束的时候,释放栈帧。栈帧存储: 1.局部变量. 2形参(形参与局部变量存储地位相同) 3.内存字段描述值

如何使用指针

  • * 取值操作符
  • & 取指(指针)操作符

使用 var p *int 声明一个指针类型的变量,当一个指针被定义后没有分配到任何变量时,它的值为 nil。

func main()  {
var a int = 100 // 声明 int 变量 a
fmt.Printf("&a = %p\n", &a) // "&" 取 a 地址 var p *int // 声明变量p
p = &a // p指向a
fmt.Printf("p = %p\n", p)
fmt.Printf("a = %d, *p = %d\n", a, *p)
*p = 324 //*p操作指针所指向的内存,即为a
fmt.Printf("a = %d, *p = %d\n", a, *p)
}

变量存储

左值(Lvalue)和右值(Rvalue)

左值(Lvalue):Location-value,表示可寻址。是保存在内存中,具有确切地址,并能取地址,进行访问,修改等操作的表达式。

右值(Rvalue):Read-value,表示可读不可寻址。是保存在内存中,或者寄存器中,不知道也无法获得其确切地址,在得到计算表达式结果后就销毁的临时表达式。

var a = 1 //a是左值
var b = 2 //b是左值
var c = a + b //这里a和b从左值转换为右值,然后将和(右值)赋值给左值c。

左值引用一般不能用右值初始化,因为如果用右值初始化,相当于将左值绑定在了右值上,那右值就不会被销毁,也就不是右值了

空指针和野指针

  • 空指针:没有存储任何内存地址的指针就称为空指针 go 为 nil
  • 野指针:不可用内存的指针

指针变量的零值不是空子串,而是nil。p的值是指针类型,由于尚未该指针尚未指向另外一个地址。因此初始化为nil。

var p *int
*p = 1 //错误,1是右值,p是左值引用,无法直接初始化

*p = 1 的含义可以理解为,将nil的指针地址的值赋予1。可是p的值是nil,但还没有赋值成地址,因此不能把一个子串赋值给一个nil值。此外,即使不是赋值,对nil的指针通过*读取也会报错,毕竟读取不到任何地址。无效的赋值即野指针

函数new

表达式new(type)将创建一个type类型的匿名变量,所做的是为type类型的新值分配并清零一块内存空间,然后将这块内存空间的地址作为结果返回,而这个结果就是指向这个新的type类型值的指针值,返回的指针类型为*type。此时会在堆空间开辟一个内存地址。随应用程序使用始终存在。

package main

import "fmt"

func main() {

   var p *int

   p = new(int)  // 为p开辟一个int的地址, 初始为nil的地址

   *p = 100 // 此时可以正常赋值
fmt.Println(p)
fmt.Println(*p)
}

指针做函数参数

golang允许向函数传递指针,志需要在函数定义的参数上设置为指针类型即可。

值传递,将实参拷贝一份给形参

传地址(引用),将形参的地址值作为函数参数、返回值后传递

 func swap01(a, b int) {
    a, b = b, a
    fmt.Printf("swap01 a = %d, b = %d\n", a, b)
} func swap02(x, y *int) {
    *x, *y = *y, *x
} func main() {
    a := 10
    b := 20     //swap01(a, b) //值传递(传值)
    swap02(&a, &b) //地址传递(传引用)
    fmt.Printf("a = %d, b = %d\n", a, b)
}

多级指针

一级指针:指向变量的地址
二级指针:指向一级指针的地址
....

package main

import "fmt"

func main() {
var a = 10 var b *int
var c **int b = &a
c = &b
**c = 200 fmt.Println(a, &a)
fmt.Println(b, &b)
fmt.Println(c, &c)
}

golang:指针理解总结的更多相关文章

  1. Golang 指针理解

    目录 0x00 指针地址和指针类型 0x01 从指针获取指针指向的值 0x02 使用指针修改值 0x03 返回函数中局部变量 0x04 使用 new() 创建指针 0x05 flag包的指针技术 0x ...

  2. Golang指针与unsafe

    前言 我们知道在golang中是存在指针这个概念的.对于指针很多人有点忌惮(可能是因为之前学习过C语言),因为它会导致很多异常的问题.但是很多人学习之后发现,golang中的指针很简单,没有C那么复杂 ...

  3. TODO:Golang指针使用注意事项

    TODO:Golang指针使用注意事项 先来看简单的例子1: 输出: 1 1 例子2: 输出: 1 3 例子1是使用值传递,Add方法不会做任何改变:例子2是使用指针传递,会改变地址,从而改变地址. ...

  4. [c++]this指针理解

    #include <iostream> using namespace std; /** * this 指针理解 */ class A{ int i; public: void hello ...

  5. Golang - 指针与引用

    ​ Golang有指针 , 那么一切数据都是值传递吗 ? 都需要用户进行指针传递吗, 其实不然, 对于Go语言, 虽然有指针, 但是其也有引用传递. 是不是很绕, 因为引用传递就是指针传递哇 . 我们 ...

  6. 关于this指针理解

    1. this指针的用处: 一个对象的this指针并不是对象本身的一部分,不会影响sizeof(对象)的结果.this作用域是在类内部,当在类的非静态成员函数中访问类的非静态成员的时候,编译器会自动将 ...

  7. Golang指针基本介绍及使用案例

    一.指针的相关概念说明 变量:是基本类型,变量存的就是值,也叫值类型 地址:用于引用计算机的内存地址,可理解为内存地址的标签,通俗一点讲就是一间房在小区里的门牌号.如下图① 指针:指针变量存的是一个地 ...

  8. C++指针理解

    指针是C/C++编程中的重要概念之一,也是最容易产生困惑并导致程序出错的问题之一.利用指针编程可以表示各种数据结构,通过指针可使用主调函数和被调函数之间共享变量或数据结构,便于实现双向数据通讯:指针能 ...

  9. 浅谈 .NET 中的对象引用、非托管指针和托管指针 理解C#中的闭包

    浅谈 .NET 中的对象引用.非托管指针和托管指针   目录 前言 一.对象引用 二.值传递和引用传递 三.初识托管指针和非托管指针 四.非托管指针 1.非托管指针不能指向对象引用 2.类成员指针 五 ...

随机推荐

  1. PAT (Advanced Level) Practice 1002 A+B for Polynomials (25 分) 凌宸1642

    PAT (Advanced Level) Practice 1002 A+B for Polynomials (25 分) 凌宸1642 题目描述: This time, you are suppos ...

  2. Dubbo 编解码那些事

    一.背景 笔者在一次维护基础公共组件的过程中,不小心修改了类的包路径.糟糕的是,这个类被各业务在facade中进行了引用.传递.幸运的是,同一个类,在提供者和消费者的包路径不一致,没有引起各业务报错. ...

  3. 201871030117-李亚楠 实验三 结对项目—《D{0-1}KP 实例数据集算法实验平台》项目报告

    项目 内容 课程班级博客链接 课程班级 这个作业要求链接 作业要求 我的课程学习目标 1.体验软件项目开发中的两个人合作.练习结对编程:2.掌握Github协作开发程序的操作方法:3.熟悉编程语言的综 ...

  4. java面试一日一题:mysql中常用的存储引擎有哪些?

    问题:请讲下mysql中常用的引擎有哪些? 分析:该问题主要考察对mysql存储引擎的理解,及区别是什么? 回答要点: 主要从以下几点去考虑, 1.mysql的存储引擎的基本概念? 2.mysql中常 ...

  5. 深入学习spring cloud gateway 限流熔断

    前言 Spring Cloud Gateway 目前,Spring Cloud Gateway是仅次于Spring Cloud Netflix的第二个最受欢迎的Spring Cloud项目(就GitH ...

  6. 解决IDEA Gradle构建报错"Cause: zip END header not found"

    1 问题描述 某天使用Gradle构建项目时,IDEA报错如下: 2 原因 原因是下载的Gradle,也就是zip压缩包不完整,导致无法使用Gradle构建. 3 解决方法 3.1 删除本地缓存重新下 ...

  7. Nest 中处理 XML 类型的请求与响应

    公众号及小程序的微信接口是通过 xml 格式进行数据交换的. 比如接收普通消息的接口: 当普通微信用户向公众账号发消息时,微信服务器将 POST 消息的 XML 数据包到开发者填写的 URL 上. - ...

  8. FusionInsight MRS:你的大数据“管家”

    摘要:4月24日-26日,HDC.Cloud2021在深圳大学城成功举办,华为云FusionInsight MRS云原生数据湖带来最懂行的大数据解决方案,为政企客户提供湖仓一体.云原生的大数据解决方案 ...

  9. Java封装接口统一返回数据模板

    现在大多数都使用前后端分离开发模式,前端通过Ajax请求访问后台服务器,后台返回JSON数据供前端操作,这里编写一个统一返回数据模板类,方便日后操作 public class R extends Ha ...

  10. 模拟退火算法Python编程(2)约束条件的处理

    1.最优化与线性规划 最优化问题的三要素是决策变量.目标函数和约束条件. 线性规划(Linear programming),是研究线性约束条件下线性目标函数的极值问题的优化方法,常用于解决利用现有的资 ...