Go语言高级数据类型之指针篇

目录
  • 一.指针
    • 1.指针概述
    • 2.指针地址和指针类型
    • 3.定义指针变量
    • 4.指针细节
      • 4.1 可以通过改变指向值
      • 4.2 指针变量接收的一定是地址值
      • 4.3 指针的地址不可以不匹配
      • 4.4 基础数据类型又称为值类型
    • 5.指针传值
      • 5.1 案例一
      • 5.2 案例二(注意,数组也是值类型哟~)
  • 二.new和make
    • 1.new
      • 1.1 new概述
      • 1.2 new案例
    • 2.make
      • 2.1 make概述
      • 2.2 make案例
    • 3.new和make的区别

一.指针

1.指针概述

任何程序数据载入内存后,在内存都有他们的地址,这就是指针。而为了保存一个数据在内存中的地址,我们就需要指针变量。Go语言中的指针不能进行偏移和运算,因此我们说Go语言的指针是只读的。Go语言中的指针操作非常简单,我们只需要记住两个符号:- &:用于取地址。- *:根据地址取值。取地址操作符&和取值操作符*是一对互补操作符,&取出地址,*根据地址取出地址指向的值。要搞明白Go语言中的指针需要先知道三个概念:- 指针地址: &a- 指针取值: *&a- 指针类型: 比如: "*int"变量、指针地址、指针变量、取地址、取值的相互关系和特性如下:- 对变量进行取地址(&)操作,可以获得这个变量的指针变量。- 指针变量的值是指针地址。- 对指针变量进行取值(*)操作,可以获得指针变量指向的原变量的值。

2.指针地址和指针类型

每个变量在运行时都拥有一个地址,这个地址代表变量在内存中的位置。Go语言中使用"&"字符放在变量前面对变量进行"取地址"操作。 Go语言中的值类型(int、float、bool、string、array、struct)都有对应的指针类型,如:*int、*int64、*string等。取变量指针的语法如下:ptr := &v    // v的类型为T其中:- v:代表被取地址的变量,类型为T。- ptr:用于接收地址的变量,ptr的类型就为"*T",称做T的"指针类型"。"*"代表指针。

3.定义指针变量

package mainimport ("fmt"
)func main() {var (a int = 10// 定义指针变量,*int可以理解为指向int类型的指针。指针本质上指向的是一个内存地址b *int = &a  // 取变量a的内存地址,将指针保存到b指针中)fmt.Printf("type of b:%T, value of b: %v\n", b, b)// 指针取值(根据指针去内存地址取值)c := *bfmt.Printf("type of c:%T,value of c: %v\n", c, c)
}

4.指针细节

4.1 可以通过改变指向值

package mainimport ("fmt"
)func main() {var (a int  = 100b *int = &a)fmt.Printf("a = %v\n", a)// 可以通过改变指向值*b = 200fmt.Printf("a = %v\n", a)}

4.2 指针变量接收的一定是地址值

package mainimport ("fmt"
)func main() {var (a int  = 100// 指针变量接收的一定是地址值// b *int = a  // 编译报错: "cannot use a (variable of type int) as *int value in variable declaration"b *int = &a)fmt.Printf("b = %v\n", b)}

4.3 指针的地址不可以不匹配

package mainimport ("fmt"
)func main() {var (a int  = 100// 指针的地址不可以不匹配// b *float64 = &a  // 编译报错: cannot use &a (value of type *int) as *float64 value in variable declarationb *int = &a)fmt.Printf("b = %v\n", b)}

4.4 基础数据类型又称为值类型

基础数据类型又称为值类型,都有对应的指针类型,形式为"*数据类型"。比如int的对应指针就是"*int",float64对应的指针类型就是"*float64",以此类推。

5.指针传值

5.1 案例一

package mainimport ("fmt"
)func modify1(x int) {x = 200
}func modify2(x *int) {*x = 300
}func main() {a := 100fmt.Printf("in main: %d\n", a)// 传递的是值modify1(a)fmt.Printf("after modify1: %d\n", a)// 传递的是指针变量modify2(&a)fmt.Printf("after modify2: %d\n", a)
}

5.2 案例二(注意,数组也是值类型哟~)

package mainimport ("fmt"
)func modifyArray1(x [3]int) {x[0] = 200
}func modifyArray2(x *[3]int) {x[0] = 200
}func main() {a := [3]int{1, 2, 3}fmt.Printf("in main:  %v\n", a)modifyArray1(a)fmt.Printf("modifyArray1: %v\n", a)modifyArray2(&a)fmt.Printf("modifyArray2: %v\n", a)
}

二.new和make

1.new

1.1 new概述

new是一个内置的函数,它的函数签名如下:func new(Type) *Type
其中:Type:表示类型,new函数只接受一个参数,这个参数是一个类型*Type:表示类型指针,new函数返回一个指向该类型内存地址的指针。new函数不太常用,使用new函数得到的是一个类型的指针,并且该指针对应的值为该类型的零值。指针作为引用类型需要初始化后才会拥有内存空间,才可以给它赋值。

1.2 new案例

package mainimport ("fmt"
)func main() {// a是一个int类型的指针,但并没有内存地址,但无法使用,写法错误!// var a *int// 正确的写法是,使用new得到一个int类型的指针,此时指针是有内存地址的。var a = new(int)fmt.Printf("内存地址: %v, 数据: %v, 类型: %T\n", a, *a, a)// 取出a的内存地址,并修改其值为100*a = 100// 对a指针类型进行初始化fmt.Printf("内存地址: %v, 数据: %v, 类型: %T\n", a, *a, a)// 声明一个"[3]int"数组类型指针并分配内存地址var b = new([3]int)fmt.Printf("内存地址: %v, 数据: %v, 类型: %T\n", b, *b, b)// 下面这种两种写法都是正确的,但Go编译器使用了语法糖,让我们可以有更简洁的写法。// (*b)[0] = 200b[0] = 200fmt.Printf("内存地址: %v, 数据: %v, 类型: %T\n", b, *b, b)
}

2.make

2.1 make概述

make也是用于内存分配的,区别于new,它只用于slice、map以及channel的内存创建,而且它返回的类型就是这三个类型本身,而不是他们的指针类型,因为这三种类型就是引用类型,所以就没有必要返回他们的指针了。make函数的函数签名如下:func make(t Type, size ...IntegerType) Typemake函数是无可替代的,我们在使用slice、map以及channel的时候,都需要使用make进行初始化,然后才可以对它们进行操作。这个我们在上一章中都有说明,关于channel我们会在后续的章节详细说明。

2.2 make案例

package mainimport ("fmt"
)func main() {var teacher map[string]int// 对引用类型的数据进行初始化操作,用于分配内存地址teacher = make(map[string]int, 10)teacher["尹正杰"] = 20fmt.Println(teacher)}

3.new和make的区别

- 二者都是用来做内存分配的。
- make只用于slice、map以及channel的初始化,返回的还是这三个引用类型本身:- make只能对内置数据类型进行申请内存;- 返回是数据值本身;
- 而new用于类型的内存分配,返回的是指向类型的指针。- new方法主要给struct等非内置数据类型申请空间- 返回的是一个指针类型

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

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

相关文章

[LeetCode] 380. Insert Delete GetRandom O(1)

竟然不需要import random,击败了5%的O(1)哈哈哈 class RandomizedSet:def __init__(self):self.data = []def insert(self, val: int) -> bool:if val in self.data:return Falseelse:self.data.append(val)return Truedef remove(self, val: int) -> bool:if val in …

springboot下的纯html页面乱码带问号?

springboot下的纯html页面乱码带问号? html访问后端接口 返回的Content-Type: text/html;charset=ISO-8859-1所以大概率是springboot编码影响到了html页面在springboot的application.yml加上以下配置server:servlet:encoding:#enabled: true #让系统的CharacterEncdoingFil…

运用inlinehook主动调用函数

这里拿arm32的环境下运行的来举例 首先我们先准备这两个函数可以清楚的看到,解锁英雄那里有个参数为id,可以猜到为英雄id(元气的英雄id为1,2,3...) 所以,我们在update进行hook.用他调用该函数 我们首先分配个内存页,方便我们编写hook段的代码编写如下的汇编将a地址的值0…

等保V2.0测评指标

等保V2.0测评指标列表清单:1、物理和环境安全:主要关注机房的物理环境,包括机房位置的选择、温湿度控制、防盗、防火、防潮、防水、防雷击、电力供应、电磁防护等方面的要求。确保服务器房间、设备存储区域等得到适当的物理保护。2、网络和通信安全:这一指标主要对网络安全…

jdk1.8安装到d盘

下载地址双击直接安装,安装过程中需要指定jdk和jre的安装目录安装完成后验证,打开cmdC:\Users\xxx>java -version java version "1.8.0_381" Java(TM) SE Runtime Environment (build 1.8.0_381-b09) Java HotSpot(TM) 64-Bit Server VM (build 25.381-b09, mix…

vscode设置背景图片

1.vscode应用商店搜索下载 background 2.更改settings.json3.搜索 "background.fullscreen"; 保存重启vscode

《操作系统》第三章的重难点内容_补充笔记

前言 王道408书上很多内容是没有的,但是这些内容是超级重要的考点,也能加深理解,所以我将其补充一下。 《25操作系统408王道》p184-185 混淆点 页框、页帧是指内存中。页框号同理。 页面、页是指页表中。页号、页内偏移量同理。 每个页表项占多少字节【经常考察】 一个页表项…

收集了几个Github文件代理下载的站点

收集了几个Github文件代理下载的站点 1、GitClone 2、ghproxy 3、moeyy 最后实在不行可以去Gitee 上边,新建仓库->从现有仓库导入,然后从gitee上下载

Power BI实用技巧——批量爬取网页数据

Power BI实用技巧——批量爬取网页数据假设我是个电商公司老板,我的公司最近要上架一款新产品,我需要你来帮我做一个竞品分析,同类型产品的评分、价格、销量、市场占有率最高的品牌详情,来帮助我进行前期宣发,这个时候最让你一筹莫展的环节是什么?我猜是数据从哪来?竞争…

Hello,NanXi~

今天是2024.07.05,注册博客已经4天了,零零散散的抽时间把博客园美化了一下(我有自定义美化的习惯,喜欢自定义性强的东西),毕竟这是我的新家啊!我准备丢掉之前自己搭建的博客了,改用博客园平台,这样会很方便,省下了自己维护网站的时间,而且平台的稳定性自然是比个人网…

HDLC报文简单分析

最近在学习HDLC协议,从刚开始的一窍不通到现在的懵懵懂懂,下面分享一段报文解析,给初学者一点点经验的分析。 报文:7E A0 57 03 02 B8 4B 5B E6 E7 00 C4 01 C1 00 01 01 02 08 09 0C 07 E8 04 05 05 0D 08 33 FF 80 00 02 06 00 00 00 02 06 00 00 00 05 06 00 00 00 07 0…

喜闻乐见的颓柿子

从洛谷搬来的高三时做的题,主要目的是测试既然一开始的时候把 dp 方程写了,第三问不如就尝试一下。 接下来我们考虑一下对 $ a_n=a_{n-1}+(n-1)a_{n-2} $ 找出通项。 首先有 $ a_1=1,,a_2=2, $ 化一下式子: \[a_n=a_{n-1}+(n-1)a_{n-2} \]即 \[\frac{a_n}{(n-1)!}=\frac{a_…

safe_shellcode

[HNCTF 2022 Week1]safe_shellcode 思路 下载附件,名称为shellcoder,很明显的shellcode提示。 判断题目解法可能是shellcode利用 常规流程查看保护发现存在NX保护,但是让我们以shellcode的思路去解题,则可能存在修改权限的函数mprotect ida打开分析分析代码,发现存在一个m…

环境变量的一些作用

环境变量的一些作用 接上篇:如果希望批量执行一组cmd指令,而不是像之前那样一次执行一个cmd指令,那么可以通过批处理来实现。将多条cmd指令存放在一个以.bat为扩展名的文件里,然后执行这个文件,这个文件就叫批处理文件。 在d:\aaa文件夹里新建demo.bat编辑,记得把文件扩展名…

Jitsi搭建流程

系统要求:Debian 11 (DD 脚本 非必需 DD,用原来的系统也 OK)。安装好宝塔(需要用到https证书)、Nninx前置: sudo -i # 切换到 root 用户apt update -y # 升级 packagesapt install wget curl sudo vim git -y # Debian 系统比较干净,安装常用的软件 1:安装 Docker 环…

代码随想录算法训练营第五十三天 | 739.每日温度 496.下一个更大的元素I 503.下一个更大的元素II

739.每日温度 题目链接 文章讲解 视频讲解 单调栈适合的场景:求当前元素左面或右面第一个比它大或小的元素单调栈里存什么元素 只要存下标就可以了,比较元素时可以通过下标取元素 单调栈是单调增还是单调减(从栈顶到栈底) 使用单调增的单调栈解题步骤:遍历数组,当栈空时直…

积分中值定理的证明1

积分中值定理的证明如下:

24年读书清单

最近整理的读书清单,今年的读书就从里面挑选了;

【Azure Blob】关闭Blob 匿名访问,iOS Objective-C SDK连接Storage Account报错

问题描述 iOS Objective-C 应用,连接Azure Storage Account, 根据官网Example代码,在没有关闭Storage Account的匿名访问时,程序正常运行。但是,只要关闭了匿名访问,上传blob到Container中,就会报错:Public access is not permitted on this storage account 问题解答…

模拟集成电路设计系列博客——9.4 ESD保护单元

模拟集成电路设计 9.4 ESD保护单元 ESD,即electrostatic discharge(静电放电)是集成电路设计中的一个经典问题。通常在电路的生产和使用过程中,很容易由于各种原因积累大量的静电电荷,一旦产生静电放电,极高的静电电压(可能\(>1000V\))会对电路产生不可逆的破坏。因…