指针:

  • 指针是一个特殊的变量,因为存储的数据不仅仅是一个普通的数据,而是一个变量的内存地址,指针本身也是有内存地址的
  • 指针的数据类型有int、float、bool、string、数组、结构体
  • 指针的作用就是可以通过变量/对象的内存地址去操作变量/对象
  • 并非所有对象都能进行取地址操作,但变量总是能正确返回(addressable)。指针运算符为左值时,我们可更新目标对象状态,而为右值时则是为了获取目标状态。

注意:

  • 空指针:未初始化的指针 使用*p获取
  • 野指针:被无效地址空间初始化
  • 取址运算符&用于获取对象地址
  • 指针运算符*用于间接引用目标对象
  • 二级指针(一个指针指向另一个指针)**T,或包含包名*package.T

指针定义:

定义格式:

var 指针名 *类型

获取内存地址格式:

&变量/指针

通过指针修改变量的值:

// *指针变量是获取到内存地址指向的变量值,拿到后可以再修改,或者其它操作
*指针变量 = 值

演示:

func pointerDemo01() {a := 10// 定义一个指针变量p,并把a的内存地址赋值给pvar p *int// &可以获取内存地址p = &a// 对比a的内存地址和p变量存的数据是一样的fmt.Println("变量a的内存地址:", &a)fmt.Println("指针p的数据:", p)fmt.Println("指针p存的数据:", *p)fmt.Println("指针p的内存地址:", &p)// 通过指针修改数据,a的数据也同步修改*p = 222fmt.Println(a)
}

指针类型支持相等运算符,但不能做加减法运算和直接类型转换。如果两个指针指向同一地址,或都为nil,那么它们相等

func main() {x := 10p := &xp++                 // 无效运算:p++ (non-numeric type *int)var p2 *int = p + 1 // 无效运算: p + 1 (mismatched types *int and int)p2 = &xprintln(p == p2)
}

零长度(zero-size)对象的地址是否相等和具体的实现版本有关,不过肯定不等于nil

即便长度为0,可该对象依然是合法存在的,也拥有内存地址,这与nil语义完全不同。
在runtime/malloc.go里有个zerobase全局变量,所有通过mallocgc分配的零长度对象都使用该地址。不过下例中,对象a、b在栈上分配,并未调用mallocgc函数

func main() {var a, b struct{}println(&a, &b)println(&a == &b, &a == nil)
}

打印结果:

0x14000096f68 0x14000096f68
false false

操作指针的3个注意事项:

  1. 空指针
 var p *intfmt.Println(p) // <nil>
  1. 不要操作没有合法指向的内存
 var p *int*p = 111fmt.Println(p) //  invalid memory address or nil pointer dereference// 这里虽然定义了指针并赋值,但是并没有将指针指向任何有效的变量
  1. new函数使用
 // 创建了一个int类型的内存空间,然后让p指向内存空间,然后把222保存到了内存空间中p = new(int)*p = 222fmt.Println(*p)

指针作为函数参数:

在函数中修改变量值,是不影响原来的变量的,可以通过指针去修改
不通过指针的时候,修改原来的变量,虽然变量都是a,但是内存地址是不一样的,所以在函数中修改完以后会发现原来的变量并没有被修改,但是通过指针去修改的时候是因为指向的是内存地址,所以对函数中的a进行操作,其实就是对原来的a进行操作,所以可以将原来的变量值修改掉

演示:

func main() {a := 10pointerDemo03(&a)fmt.Println(a)
}// 注意,指针作为函数的时候,参数也要加上*
func pointerDemo03(a *int) {*a = 20
}

数组指针:

要分清指针数组和数组指针的区别。指针数组是指元素为指针类型的数组,数组指针是获取数组变量的地址

var 数组指针变量 *[索引] 类型

演示:

func pointerDemo05() {arr := [10]int{1, 2, 3, 3, 4, 5}var p *[10]intp = &arrfmt.Println(*p)      // 获取数组中的全部数据fmt.Println((*p)[0]) // 获取指定数组中索引的数据,因为*p是先运算,所以要先加括号,否则编译保存fmt.Println(p[0])    // 获取指定数组中索引的数据,这个格式和加括号一样,但是简化的写法for i := 0; i < len(p); i++ {fmt.Print(p[i], ",")}
}

数组作为函数参数:

func main() {arr := [10]int{1, 2, 3, 3, 4, 5}var p *[10]intp = &arrpointerDemo06(p)
}func pointerDemo06(p *[10]int) {p[0] = 111fmt.Println(p)
}

指针数组:

指针数组指的是元素为指针类型的数组(一个数组中存储的都是指针),它就是一个存储了地址的数组。

定义格式:

var 数组名 [索引] *类型

演示:

func pointerDemo07() {var p [2]*inta := 10b := 20// 变量a的内存地址保存在指针数组p的0索引,b保存在1索引p[0] = &ap[1] = &bfmt.Println(p)            // 获取p数组中的内存地址fmt.Println(*p[0], *p[1]) // 获取p数组中的指定索引数据for i := 0; i < len(p); i++ {fmt.Println(*p[i]) // 获取p数组中的所有的数据}for key, value := range p {fmt.Println(key, *value)}
}

指针与切片:

其实就是定义指针,指向切片

演示:

func pointerDemo08() {s := []int{1, 2, 3, 4, 5}var p *[]intp = &sfmt.Println(*p)fmt.Println((*p)[0]) // 指针切片中没有简化的写法,只能加括号先运算指针,再运算切片for i := 0; i < len(*p); i++ {fmt.Print("fori方式:", (*p)[i], ",")}for key, value := range *p {fmt.Println("range方式:", key, value)}
}

指针与结构体:

其实就是定义指针,指向结构体

演示:

type Student struct {// 成员名称不加var关键字id   intname stringage  intaddr string
}func pointerDemo09() {stu := Student{001, "itzhuzhu", 23, "广州"}var p *Studentp = &stufmt.Println(*p)        // 获取全部fmt.Println((*p).name) // 获取指定的数据fmt.Println(p.name)    // 结构体指针中也是有简化写法的p.addr = "深圳"fmt.Println(*p)
}

将结构体指针作为函数参数:

func main() {stu := Student{001, "itzhuzhu", 23, "广州"}var p *Studentp = &stupointerDemo10(p)fmt.Println(stu)
}```go
func pointerDemo10(p *Student) {p.addr = "深圳"
}

多级指针:

多级指针指的是,存放的都是上一级指针的内存地址,二级指针存的是一级指针的内存地址,以此类推,多级指针的概念和二维数组的概念类似。多级指针可以无限定义级别,几级指针定义的时候就要写几个*

定义格式:

var 指针变量名 *类型
// 几级指针就写几个*   一个* 就是一级指针

演示:

func pointerDemo11() {a := 10var p *intp = &a// 定义二级指针,var p2 **int//var p3 ***int//var p4 ****intp2 = &pfmt.Println(**p2) // 10
}

Golang——指针的使用、数组指针和指针数组、指针与切片、指针与结构体、多级指针相关推荐

  1. C语言程序设计 数组,结构体和指针练习题

    涉及知识点:数组,结构体和指针 分析以下程序的运行结果: #include "stdio.h" struct  sp {     int a;     int *b; } *p ; ...

  2. python中的记录指针_使用Python向C语言的链接库传递数组、结构体、指针类型的数据...

    使用python向C语言的链接库传递数组.结构体.指针类型的数据 由于最近的项目频繁使用python调用同事的C语言代码,在调用过程中踩了很多坑,一点一点写出来供大家参考,我们仍然是使用ctypes来 ...

  3. python结构体数组传出接收c动态库_使用Python向C语言的链接库传递数组、结构体、指针类型的数据...

    使用python向C语言的链接库传递数组.结构体.指针类型的数据 由于最近的项目频繁使用python调用同事的C语言代码,在调用过程中踩了很多坑,一点一点写出来供大家参考,我们仍然是使用ctypes来 ...

  4. C语言项目实战:24点游戏计算器(基于结构体、指针、函数、数组、循环等知识点)

    文章目录 C语言项目实战:24点游戏计算器(基于结构体.指针.函数.数组.循环等知识点) 前言:24点游戏计算器的规则如下 一.项目的创建标 1.选择项目 2.输入项目名称和路径 3.创建头文件Mai ...

  5. 数组、结构体、指针的应用

    一.目的: 在课堂教学的基础之上,进一步了解构造数据类型,掌握一维数组.二维数组.字符数组.结构体.指针的应用及程序设计技巧.数组有利于我们对数据类型相同的许多数据进行分类与管理. 二.要求: 复习程 ...

  6. C语言结构体的定义与使用、结构体数组、指向结构体的指针(有代码详解)

    1.结构体的定义与使用 结构体是一种构造数据类型 把不同类型的数据组合成一个整体 结构体的定义形式: struct 结构体名{结构体所包含的变量或数组 }; 结构体是一种集合,它里面包含了多个变量或数 ...

  7. C++:将char*指针强制转换成一个指向结构体的指针

    在使用Socket与雷达进行通信采集数据时,会遇到"打包与解包"的问题,在打包和解包过程中,会涉及到结构体指针与字符指针间的强制转换.如下: 打包就是将包头与信息封装成一定大小的包 ...

  8. c语言中较常见的由内存分配引起的错误_内存越界_内存未初始化_内存太小_结构体隐含指针...

    1.指针没有指向一块合法的内存 定义了指针变量,但是没有为指针分配内存,即指针没有指向一块合法的内浅显的例子就不举了,这里举几个比较隐蔽的例子. 1.1结构体成员指针未初始化 1 2 3 4 5 6 ...

  9. 指向结构体的指针和指向结构体指针的指针

    例如,struct T *ptr;是指向一个结构体的指针,也可以当做一个结构体数组来用. 可以把结构体当做 int 来看,int* 类型即可以指向一个整数,也可以指向数组. struct T ** p ...

  10. c语言定义指向结构体的指针,C语言入门教程-指向结构体的指针

    指向结构体的指针 在C语言中几乎可以创建指向任何类型的指针,包括用户自定义的类型.创建结构体指针是极常见的.下面是一个例子: typedef struct {char name[21];char ci ...

最新文章

  1. Java学习总结:23
  2. bnu 34986 Football on Table(数学+暴力)
  3. 2021“MINIEYE杯”中国大学生算法设计超级联赛(1)zoto(二维数颜色)
  4. nodejs常用组件
  5. 2-2:套接字(Socket)编程之深入了解套接字
  6. 我被C++开发欺辱的岁月
  7. 通信upf是什么意思_管理UPF的方法、装置及系统与流程
  8. 深度学习----GAN(生成对抗神经网络)原理解析
  9. XSS Filter Evasion Cheat Sheet 中文版
  10. Java基础之二维数组
  11. oracle数据库迁移-TTS迁移操作案例01
  12. 求解函数最值的几种算法,梯度下降法python实现
  13. 关于在袁教授blog中的”呛袁教授“的争论
  14. “新基建”背景下,智慧灯杆产业面临的问题及思考
  15. DIY M328晶体管测试仪 挖坑 填坑
  16. 对于学习率与梯度下降的通俗总结:
  17. dxp中发光二极管在哪找_如何设计发光二极管的元件符号?
  18. ES 全文搜索与数据分析引擎
  19. Cerc2014 Outer space invaders
  20. 高校,微软未来的主战场--有感于DreamSpark的试用

热门文章

  1. linux图形界面为英文,Linux下“英文控制台 中文图形界面”的实现
  2. 指数函数中x的取值范围_谨记!高考数学中容易出错的几个地方
  3. android 页面整体滑动,ScrollView 实现页面整体滑动
  4. 获取数据库内容放入下拉框中
  5. android studio viewo,Android Studio 之 ViewModel
  6. SystemC 代码添加和测试方法
  7. python连接服务器sql server_python – 无法通过pymssql连接到SQL Server
  8. 教师进修学校计算机教学反思,优秀教学反思
  9. 【Python】random模块生成多种类型随机数
  10. Java 泛型(1):基本原理