学过C语言的老司机都知道,指针就是一个变量,用于存储另一个变量的内存地址。

那么什么是变量呢?在现代计算机体系结构中所有的需要执行的信息代码都需要存储在内存中,为了管理存储在内存的数据,内存是划分为不同的区域的,不同区域都用内存地址来标识。一个典型的内存地址是个16进制的8位数(一个字节)比如0xAFFFF(这是一个内存地址的十六进制表示)。

要访问数据,我们需要知道它的存储地址。我们可以跟踪存储与我们的程序相关的数据的所有内存地址。但是要记住这些内存地址,非常费劲,怎么办呢?

于是我们引入了变量的概念。变量只是给存储数据的内存地址的好记得别名。指针也是一个变量。但它是一种特殊的变量,因为它存储的数据不仅仅是一个普通的值,如简单的整数或字符串,而是另一个变量的内存地址。

在上面的图中,指针p包含变量a的地址值0x0001。

package main

import "fmt"

func main() {

    var p *int

    fmt.Println("p = ", p)

}

# Output

p = <nil>

指针声明

T类型的指针使用以下语法声明:

//类型T的指针

var p *T

类型T是指针指向的变量的类型。比如整型指针:

//类型为整型指针

var p *int

p指针只能保存int变量的内存地址。

指针的零值,不是0,而是nil。任何未初始化的指针值都为nil。我们直接撸一个代码:

package main

import "fmt"

func main() {

var p *int

fmt.Println("chongchong p = ", p)

}

#Output

chongchong p = <nil>

初始化指针

初始化一个指针,只需给他赋予其他变量的内存地址接口。变量的地址可以使用使用&运算符获得:

var x = 100

var p *int = &x

上面我们通过对x做&运算符来获取其地址,然后将该地址分配给指针p。

就像Golang中的其他变量一样,编译器也会推断指针变量的类型。所以你可以在上面的例子中省略指针p中的类型声明,直接简写为:

var p = &x

撸代码之例2 :

package main

import "fmt"

func main() {

var a = 3.1415926

var p = &a

fmt.Println("chongchong value a = ", a)

fmt.Println("chongchong Address a = ", &a)

fmt.Println("chongchong value p = ", p)

}

输出结果

chongchong value a = 3.1415926

chongchong Address a = 0Xc82000a330

chongchong value p = 0Xc82000a330

指针解引用

要获得指针指向地址的值,我们可以使用*运算符。这叫解引用。

package main

import "fmt"

func main() {

var a = 

var p = &a

fmt.Println("chongchong a = ", a)

fmt.Println("chongchong p = ", p)

fmt.Println("chongchong *p = ", *p)

}

输出入下:

chongchong a = 

chongchong p = 0Xc82000a330

chongchong *p = 

通过*运算符不仅能取值,还可以对指向变量值做修改。以下示例通过指针p设置存储在变量a中的值:

package main

import "fmt"

func main() {

    var a = 

    var p = &a

    fmt.Println("chongchong a = ", a)

    *p +=

    fmt.Println("chongchong a(altered)= ", a)

}

结果如下:

chongchong a =
chongchong a(altered)=

多重指针

指针可以指向任何类型的变量。所以也可以指向另一个指针。以下示例显示如何创建指向另一个指针的指针:

package main

import "fmt"

func main() {

var a = 3.141596

var p = &a

var pp = &p

fmt.Println("a = ", a)

fmt.Println("chong address a = ", &a)

fmt.Println("p = ", p)

fmt.Println("chongchong p = ", &p)

fmt.Println("pp = ", pp)

fmt.Println("chongchong *pp = ", *pp)

fmt.Println("chongchong **pp = ", **pp)

}

结果输出为

a = 3.1415926
chong address a = 0Xc82000a330
p = 0Xc82000a330
chongchong p = 0Xc820030020
pp = 0Xc820030020
chongchong *pp=0Xc82000a330
chongchong **pp = 3.1415926

Go中没有指针算术

老司机,都知道,可以在C/C ++中队指针做计算,但是golang就不支持那样做了。

package main

func main() {

var x = 

var p = &x

var p1 = p +  // Compiler Error: invalid operation

}

但是,golang中可以使用==运算符来比较两个相同类型的指针是否相等。

包主要

package main

import "fmt"

func main() {

var a = 

var p1 = &a

var p2 = &a

if p1 == p2 {

fmt.Printf("chongchong p1(%x) = p2(%x) value(%d): \n",p1,p2,*p1)

}

}

结果为:

chongchong p1(c82000a330) = p2(c82000a330) value()

Golang指针的更多相关文章

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

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

  2. Golang指针与unsafe

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

  3. Golang - 指针与引用

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

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

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

  5. golang 指针在struct里的应用

    type aa struct { b *int c string } func main() { var data int = 0 var ip *int /* 声明指针变量 */ ip = & ...

  6. Golang 指针理解

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

  7. golang 指针类型学习

    对于指针类型不安全编程,通过指针值以及偏移量操作slice私有属性 // 通过指针值获取切片 func TestGetPrivate(t *testing.T) { s := []int{1, 2, ...

  8. golang指针接收者和值接收者方法调用笔记

    初学go时很多同学会把 值接收者 和 指针接收者 的方法相互调用搞混淆,好多同学都只记得指针类型可以调用值接收者方法和指针接收者方法,而值类型只能调用值接收者方法,其实不然,在某些情况下,值类型也是可 ...

  9. golang指针函数

    func main() { a := models.SmsVerify{} a.Id = 100 fmt.Println(a.Id) // 100 test111(a) fmt.Println(a.I ...

随机推荐

  1. ArrayList 源码分析(JDK1.8)

    ArrayList简介  ArrayList 是一个数组队列,相当于 动态数组.与Java中的数组相比,它的容量能动态增长.它继承于AbstractList,实现了List, RandomAccess ...

  2. mysql crash cource 书中实例

    样例表 CREATE TABLE customers(  cust_id      int       NOT NULL AUTO_INCREMENT,  cust_name    char(50)  ...

  3. Java中List集合排序的方法 比较器的使用 根据学生对象数学 语文 英语成绩总和进行sort排序

    package com.swift; import java.util.ArrayList; import java.util.Collections; import java.util.Compar ...

  4. HTTP无状态协议和session原理(access_token原理)

    无状态协议是指协议对务处理没有记忆能力.缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大.另一方面,在服务器不需要先前信息时它的应答就较快. Http协议不 ...

  5. C++ 学习笔记(三)string 类

    在C语言中如果想要使用字符串那么有两种方法: 1.定义char型数组:char[10]; 然后将每个字符填充到对应的位置. 优点:这种方式将字符串放在内存所以每个位置都可以修改. 缺点:赋值比较麻烦, ...

  6. Django2.0里urls.py里配置的改变

    从Django2.0开始,urls.py配置方法有很大改变. 1.把url函数换成path 2.不在使用^.$作为路由 3.其他地方以后再进一步研究 下面看一个列子: from django.cont ...

  7. 文件处理seek以及修改内容的两种方式

    f.seek(offset,whence)offset代表文件的指针的偏移量,单位是字节byteswhence代表参考物,有三个取值# 0:参照文件的开头# 1:参照当前文件指针所在位置# 2: 参照 ...

  8. 为什么要用 ORM? 和 JDBC 有何不一样?

    orm是一种思想,就是把object转变成数据库中的记录,或者把数据库中的记录转变objecdt,我们可以用jdbc来实现这种思想,其实,如果我们的项目是严格按照oop方式编写的话,我们的jdbc程序 ...

  9. 20181206(re,正则表达式,哈希)

    1.re&正则表达式 2.hashlib 一:re模块&正则表达式 正则:正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法.或者说:正则就是用来描 ...

  10. Python头脑风暴1

    发个致富脑洞:我就在想本人虽然单身,但本人恋爱经历很多,追女生技术十足,女朋友漂亮又贤惠.如果本人开个平台帮人诚心介绍女朋友,男女成男女朋友经男方同意我收2.5万(IT界平均月收入的1.5倍不到),双 ...