Go_指针的使用、数组指针和指针数组、指针与切片、指针与结构体、多级指针

指针:

  • 指针是一个特殊的变量,因为它存储的数据是另一个变量的内存地址,指针本身也是有内存地址的
  • 指针的数据类型有int、float、bool、string、数组、结构体
  • 指针的作用就是可以通过变量/对象的内存地址去操作变量/对象

在这里插入图片描述

注意:

  • 取址运算符&用于获取对象地址

  • 指针运算符*用于 间接引用目标对象

  • 二级指针(一个指针指向另一个指针)**T,或包含包名*package.T

指针定义:

定义格式:

var 指针名 *数据类型

获取内存地址格式:

&变量

获取指针存的数据

fmt.Println(指针名)

获取指针指向的数据

fmt.Println(*指针名)

通过指针修改变量的值:

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

演示:

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

输出:

变量a的内存地址: 0x1400001a090
指针p的数据: 0x1400001a090
获取指针指向的数据: 10
指针p的内存地址: 0x1400000e028
222

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

func main() {x := 10p := &xp++ // 无效运算:p++ (non-numeric type *int)p2 := &xprintln(p == p2) // truevar p3 *intvar p4 *intfmt.Println(p3 == p4) // true
}

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

  1. 空指针:定义了指针,但指针内并没保存其他变量的内存地址
func main() {var p *intfmt.Println(p) // <nil>
}
  1. 野指针:指针没有合法指向的内存
func main() {var p *int*p = 111fmt.Println(p) 	// 虽然定义了指针并赋值,但是并没有将指针指向任何有效的变量
}
  1. new函数使用
func main() {// 创建了一个int类型的内存空间,然后让p指向内存空间,然后把222保存到了内存空间中p := new(int) // int是4个字节,所以new(int)这个空间大小就是4byte*p = 222fmt.Println(*p)
}

指针作为函数参数:

在函数中修改变量值,是不影响原变量值的,可以通过指针完成修改。

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

演示:

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

数组指针作为函数参数

func main() {arr := [10]int{1, 2, 3, 3, 4, 5}var p *[10]intp = &arrfmt.Println("修改前p[0]=", p[0])test(p)fmt.Println("修改后p[0]=", p[0])
}func test(p *[10]int) {p[0] = 111
} 

数组指针:

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

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

演示:

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

指针数组:

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

定义格式:

var 数组名 [索引] *类型

演示:

func main() {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 main() {s := []int{1, 2, 3, 4, 5}var p *[]intp = &sfmt.Println(*p)fmt.Println("修改前:", (*p)[0]) // 指针切片中没有简化的写法,只能加括号先运算指针,再运算切片(*p)[0] = 111fmt.Println("修改后:", (*p)[0]) // 指针切片中没有简化的写法,只能加括号先运算指针,再运算切片for i := 0; i < len(*p); i++ {fmt.Print((*p)[i], " ")if i == len(*p)-1 {fmt.Println()}}for key, value := range *p {fmt.Println("key:", key, "value:", value)}
} 

指针结构体:

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

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

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

type Student struct {id   intname stringage  intaddr string
}func main() {stu := Student{001, "itzhuzhu", 23, "广州"}var p *Studentp = &stutest(p)fmt.Println(stu)
}func test(p *Student) {p.addr = "深圳"
}

多级指针:

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

定义格式:

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

演示:

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/572111.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Go_面向对象(抽象、封装、继承)

抽象 抽象是一种编程思维方式&#xff0c;是从多个事物中提取共性 例&#xff1a;产品经理和程序员都有工作的方法&#xff0c;但是工作内容不同&#xff0c;可以把工作抽象出来定义为一个方法&#xff0c;具体细节由调用者补充 银行存取款案例&#xff1a; 账号结构体取款方法…

Discrete Logging POJ - 2417(BSGS)

Discrete Logging POJ - 2417 题意&#xff1a;给P&#xff0c;B&#xff0c;N&#xff0c;求最小的L使得 BL≡N (mod P)&#xff0c;其中P是素数。 Baby Step Giant Step 1 #include <cstdio>2 #include <cstring>3 #include <iostream>4 #include <cma…

js 根据固定位置获取经纬度--腾讯地图

1.首先引入jq 和 腾讯地图js <script src"../js/jQuery.js"></script> <script charset"utf-8" src"http://map.qq.com/api/js?v2.exp"></script> 2.html代码部分 <body onload"init()"><button ty…

Golang——string字符串常用函数(Contains、join、Index、Repeat、Replace、Split、Trim、Fields)

更多的还是去官方文档里去看&#xff1a;https://studygolang.com/pkgdoc Contains&#xff1a; 判断字符串中是否包含指定字符串 演示&#xff1a; func main() {str1 : "itzhuzhu"result : strings.Contains(str1, "zhu")fmt.Println(result) }join&a…

[flask 优化] 由flask-bootstrap,flask-moment引起的访问速度慢的原因及解决办法

一周时间快速阅读了400页的《javascript基础教程》&#xff0c;理解了主要概念。解决了一个很久之前的疑问。 我的网站是使用flask框架搭建的&#xff0c;介绍flask web的一本著名的书&#xff08;之前提到过&#xff09;作者搭建个人博客时&#xff0c;向读者推荐了flask-boot…

Go_关键字、编译、转义字符

关键字&#xff1a; 关键字是指被go语言赋予了特殊含义的单词&#xff0c;共25个&#xff0c;关键字不能用于自定义名字&#xff0c;只能在特定语法结构中使用。 breakdefaultfuncinterfaceselectcasedefergomapstructchanelsegotopackageswitchconstfallthroughifrangetypec…

并发编程概念、程序线程进程、线程同步、互斥量、读写锁、协程并发

多线程&#xff1a; 多线程就是同时执行多个应用程序&#xff0c;需要硬件的支持同时执行&#xff1a;不是某个时间段同时&#xff0c;cpu切换的比较快&#xff0c;所有用户会感觉是在同时运行 并发与并行&#xff1a; 并行(parallel)&#xff1a;指在同一时刻&#xff0c;有多…

第4阶段——制作根文件系统之分析init_post()如何启动第1个程序(1)

本章学习如何启动第一个应用程序 1.在前面的分析中我们了解到&#xff0c;在init进程中内核挂接到根文件系统之后&#xff0c;会开始启动第一个应用程序: kernel_init函数代码如下: static int __init kernel_init(void * unused) //进入init进程 …

Golang并发——并发技术Goroutine和channel的使用、定时器、生产者消费者、条件变量、select

Goroutine: goroutine是Go并行设计的核心。goroutine说到底其实就是协程&#xff0c;它比线程更小&#xff0c;十几个goroutine可能体现在底层就是五六个线程&#xff0c;Go语言内部帮你实现了这些goroutine之间的内存共享。执行goroutine只需极少的栈内存(大概是4~5KB)&#x…

Oozie协作框架

Oozie协作框架 一&#xff1a;概述 1.大数据协作框架 2.Hadoop的任务调度 3.Oozie的三大功能 Oozie Workflow jobs Oozie Coordinator jobs Oozie Bundle 4.Oozie的架构 控制流节点 起始&#xff0c;分支&#xff0c;并发&#xff0c;汇合&#xff0c;结束 动作节点action 5.O…

11.4 专利法与反不正当竞争法解读

第六条是对于职务作品的一个定性.它这个职务作品、职务发明创造和我们前面著作法所讲到的职务作品的处理方式基本一致.就是如果认定某一个作品它是属于职务作品、职务发明创造,那么这一个作品它的专利权应该是属于单位而不是个人.只有认定这个创造为非职务发明创造的时候,申请的…

一文入门网络编程:常见协议、通信过程、Socket、CS/BS、TCP/UDP

网络编程三要素&#xff1a;ip地址、端口、协议&#xff0c;在网络通信协议下&#xff0c;不同计算机上运行的程序&#xff0c;可以进行数据传输 常见协议&#xff1a; 传输层 常见协议有TCP/UDP协议。应用层 常见的协议有HTTP协议&#xff0c;FTP协议。网络层 常见协议有IP协议…

【Linux笔记(000) 】-- 系统启动过程

索引&#xff1a; 目录索引 一. 启动流程 BIOS --> MBR(Boot Code) --> 引导程序(GRUB) --> 加载内核 --> 执行Init --> runlevel 二. 内容详解 BIOS: Basic Input Output System , 基本输入输出系统 ,负责检查硬件,查找启动设备, 可启动设备在BIOS中定义。…

Golang——TCP、UDP实现并发(服务端与客户端)

Server端常用函数、接口&#xff1a; Listen函数&#xff1a;func Listen(network, address string) (Listener, error)network&#xff1a;选用的协议&#xff1a;TCP、UDP&#xff0c; 如&#xff1a;“tcp”或 “udp”address&#xff1a;IP地址端口号, 如&#xff1a;…

java中 将字符串时间 '2015-9-8 17:05:06' 转化为格式 '2015-09-08 17:05:06'

/** * 将字符串时间2015-9-8 17:05:06转化为格式2015-09-08 17:05:06 */import java.text.SimpleDateFormat; public class TestDate{ public static void main(String[] args) throws Exception{ String time "2015-9-8 17:05:06";//注意&#xff1a;时分秒必须都…

详解TCP协议三次握手四次挥手

三次握手&#xff1a; 三次握手表示建立通信阶段&#xff0c;在TCP协议中&#xff0c;在发送数据的准备阶段&#xff0c;客户端与服务器之间的三次交互&#xff0c;以保证连接的可靠&#xff0c;由于这种面向连接的特性&#xff0c; TCP协议可以保证传输数据的安全&#xff0c;…

Golang——实现文件传输

借助TCP完成文件的传输&#xff0c;基本思路如下&#xff1a; 发送方&#xff08;客户端&#xff09;向服务端发送文件名&#xff0c;服务端保存该文件名。接收方&#xff08;服务端&#xff09;向客户端返回一个消息ok&#xff0c;确认文件名保存成功。发送方&#xff08;客户…

Golang——HTTP编程请求和响应实现

请求&#xff1a; HTTP 请求报文由请求行、请求头部、空行、请求包体4个部分组成&#xff0c;如下图所示&#xff1a; 请求行&#xff1a; 请求行由方法字段、URL 字段 和HTTP 协议版本字段 3个部分组成&#xff0c;他们之间使用空格隔开。常用的 HTTP 请求方法有 GET、POST。…

zabbix v3.0安装部署【转】

关于zabbix及相关服务软件版本&#xff1a; Linux&#xff1a;oracle linux 6.5 nginx&#xff1a;1.9.15 MySQL&#xff1a;5.5.49 PHP&#xff1a;5.5.35 一、安装nginx&#xff1a; 安装依赖包&#xff1a; yum -y install gcc gcc-c autoconf automake zlib zlib-devel ope…

WeChatTweak-微信小助手安装教程

github下载&#xff1a;https://github.com/Sunnyyoung/WeChatTweak-macOS CSDN下载&#xff1a;https://download.csdn.net/download/weixin_45477086/83895866 双击解压下载的WeChatTweak-macOS-***.zip在终端输入cd ,并敲一个空格&#xff0c;然后把解压的文件夹拖到终端 …