go 指针类型
变量和内存地址
每个变量都有内存地址,可以说通过变量来操作对应大小的内存
var a int32
a =
fmt.Printf(“%d\n”, a)
fmt.Printf(“%p\n”, &a)
通过&符号可以获取变量的地址
普通变量存储的是对应类型的值,这些类型就叫值类型
var b int32
b =
fmt.Printf(“%d\n”, b)
fmt.Printf(“%p\n”, &b)

指针类型的变量存储的是一个地址,所以有叫指针类型或引用类型
var b int32
b =
var a *int32
a = &b

指针类型定义,var 变量名 *类型
package main
import (
"fmt"
)
func main() {
b :=
var a *int = &b
fmt.Printf("Type of a is %T\n", a)
fmt.Println("address of b is", a)
}
指针类型变量的默认值为nil,也就是空地址
package main
import (
"fmt"
)
func main() {
a :=
var b *int
if b == nil {
fmt.Println("b is", b)
b = &a
fmt.Println("b after initialization is", b)
}
}
如果操作指针变量指向的地址里面的值呢?
通过* 符号可以获取指针变量指向的变量
package main
import (
"fmt"
)
func main() {
b :=
a := &b
fmt.Println("address of b is", a)
fmt.Println("value of b is",*a)
}
通过指针修改变量的值
package main
import (
"fmt"
)
func main() {
b :=
a := &b
fmt.Println("address of b is", a)
fmt.Println("value of b is",*a)
*a++
fmt.Println("new value of b is", b)
}
举例
package main import "fmt" // 定义指针
func test1() {
var a int =
var b *int
fmt.Printf("a 的值为: %v a的内存地址是:%p a的类型是%t\n", a, &a, a)
fmt.Printf("b 的值为: %v b的内存地址是:%p b的类型是%t\n", b, &b, b) b = &a
fmt.Printf("b 的值为: %v b的内存地址是:%p b的类型是%t\n", b, &b, b)
} /*
a 的值为: 100 a的内存地址是:%!p(int=100) a的类型是%!t(int=100)
b 的值为: <nil> b的内存地址是:0x0 b的类型是%!t(*int=<nil>)
b 的值为: 0xc0000100a8 b的内存地址是:0xc0000100a8 b的类型是%!t(*int=0xc0000100a8)
*/ //控指针
func test2() {
var a int =
var b *int
fmt.Printf("b 的值为: %v b的内存地址是:%p b的类型是%t\n", b, &b, b)
if b == nil {
fmt.Println("b是一个空指针")
b = &a
}
fmt.Printf("b 的值为: %v b的内存地址是:%p b的类型是%t\n", b, &b, b)
} /*
b 的值为: <nil> b的内存地址是:0xc000080018 b的类型是%!t(*int=<nil>)
b是一个空指针
b 的值为: 0xc000058080 b的内存地址是:0xc000080018 b的类型是%!t(*int=0xc000058080)
*/ // 获取指针对应地址的值
func test3() {
var a int =
var b *int
b = &a
fmt.Printf("b 的值为: %v b的内存地址是:%p b的类型是%t\n", b, &b, b)
fmt.Printf("b 中存储的内存地址对应的值为%v\n", *b) } /*
b 的值为: 0xc0000100a8 b的内存地址是:0xc000006028 b的类型是%!t(*int=0xc0000100a8)
b 中存储的内存地址对应的值为100
*/ // 改变指针存储地址对应的值
func test4() {
var a int =
var b *int
b = &a
fmt.Printf("b 中存储的内存地址对应的值为%v\n", *b)
fmt.Printf("a的值为%v\n", a)
*b =
fmt.Printf("b 中存储的内存地址对应的值为%v\n", *b)
fmt.Printf("a的值为%v\n", a) } /*
b 中存储的内存地址对应的值为100
a的值为100
b 中存储的内存地址对应的值为500
a的值为500
*/ func main() {
// test1()
// test2()
test3()
// test4()
}
指针变量传参
package main
import (
"fmt"
)
func change(val *int) {
*val =
}
func main() {
a :=
fmt.Println("value of a before function call is",a)
b := &a
change(b)
fmt.Println("value of a after function call is", a)
}
package main
import (
"fmt"
)
func modify(arr *[]int) {
(*arr)[] =
}
func main() {
a := []int{, , }
modify(&a)
fmt.Println(a)
}
切片传参 切片是应用类型
package main
import (
"fmt"
)
func modify(sls []int) {
sls[] =
}
func main() {
a := []int{, , }
modify(a[:])
fmt.Println(a)
}
package main
import "fmt"
func test1() {
var a int =
var b *int
b = &a
fmt.Printf("a 的值为: %v a的内存地址是:%p a的类型是%t\n", a, a, a)
fmt.Printf("b 中存储的内存地址对应的值为%v\n", *b)
fmt.Printf("b 的值为: %v b的内存地址是:%p b的类型是%t\n", b, b, b)
a =
fmt.Printf("a 的值为: %v a的内存地址是:%p a的类型是%t\n", a, a, a)
fmt.Printf("b 中存储的内存地址对应的值为%v\n", *b)
fmt.Printf("b 的值为: %v b的内存地址是:%p b的类型是%t\n", b, b, b)
}
/*
a 的值为: 100 a的内存地址是:%!p(int=100) a的类型是%!t(int=100)
b 中存储的内存地址对应的值为100
b 的值为: 0xc000058080 b的内存地址是:0xc000058080 b的类型是%!t(*int=0xc000058080)
a 的值为: 200 a的内存地址是:%!p(int=200) a的类型是%!t(int=200)
b 中存储的内存地址对应的值为200
b 的值为: 0xc000058080 b的内存地址是:0xc000058080 b的类型是%!t(*int=0xc000058080)
*/
func test2(a *int) {
*a =
}
func test3(a *[]int) {
(*a)[] =
}
func test4(a []int){
a[] =
}
func modifytest() {
// var a int = 2
// test2(&a)
// fmt.Printf("修改后a的值为 %d", a) //修改后a的值为 200
// a := [3]int{1, 2, 3}
// test3(&a)
// fmt.Printf("修改后a的值为 %v", a) // 修改后a的值为 [1000 2 3]
a:= []int{,,,,}
test4(a[:])
fmt.Printf("修改后a的值为 %v", a) // 修改后a的值为 [123 5 6 4 5]
}
func main() {
// test1()
modifytest()
}
make 和 new
make用来分配引用类型的内存,比如 map、slice以及channel
new用来分配除引用类型的所有其他类型的内存,比如 int、数组等
package main
import "fmt"
func testNew() {
var a *int = new(int)
*a =
fmt.Printf("a=%v, a的内存地址%p, *a= v% *a的内存地址%p\n", a, a, *a, &(*a))
var b *[]int = new([]int)
*b = make([]int, , )
(*b)[] =
fmt.Printf("b=%v, b的内存地址%p, *b= v% *b的内存地址%p\n", b, b, *b, &(*b))
}
func main() {
testNew()
}
值拷贝和引用拷贝
值拷贝
package main
import (
"fmt"
)
func main() {
var a int =
b := a
}

引用拷贝
package main
import (
"fmt"
)
func main() {
var a int =
var b *int = &a
var c *int = b
*c =
}

package main import "fmt" // 值拷贝
func test1() {
var a int =
b := a
fmt.Printf("a= %d, a的内存地址为%p\n", a, &a)
fmt.Printf("b= %d, b的内存地址为%p\n", b, &b) } /*
a= 100, a的内存地址为0xc000058080
b= 100, b的内存地址为0xc000058088
*/ // 引用拷贝
func test2() {
var a int =
var b *int
b = &a
fmt.Printf("a= %d, a的内存地址为%p\n", a, &a)
fmt.Printf("b= %v, b的内存地址为%p *b=%d\n", b, &b, *b) *b =
fmt.Printf("a= %d, a的内存地址为%p\n", a, &a)
fmt.Printf("b= %v, b的内存地址为%p *b=%d\n", b, &b, *b)
} /*
a= 10, a的内存地址为0xc000058080
b= 0xc000058080, b的内存地址为0xc000080018 *b=10
a= 100, a的内存地址为0xc000058080
b= 0xc000058080, b的内存地址为0xc000080018 *b=100
*/ func test3() {
var a []int = []int{, , }
var b *[]int b = &a fmt.Printf("a= %d, a的内存地址为%p\n", a, &a)
fmt.Printf("b= %v, b的内存地址为%p *b=%d\n", b, &b, *b) (*b)[] =
fmt.Printf("a= %d, a的内存地址为%p\n", a, &a)
fmt.Printf("b= %v, b的内存地址为%p *b=%d\n", b, &b, *b) }
/*
a= [1 2 3], a的内存地址为0xc0000560c0
b= &[1 2 3], b的内存地址为0xc000080018 *b=[1 2 3]
a= [1 100 3], a的内存地址为0xc0000560c0
b= &[1 100 3], b的内存地址为0xc000080018 *b=[1 100 3]
*/ func main() {
// test1()
// test2()
test3()
}
练习 交换两个变量的值
package main
import "fmt"
func swap1(a int, b int) {
fmt.Printf("swap 交换前 a= %d b=%d\n", a, b)
a, b = b, a
fmt.Printf("swap 交换后 a= %d b=%d\n", a, b)
}
func swap2(a *int, b *int) {
fmt.Printf("swap 交换前 a= %d b=%d\n", *a, *b)
*a, *b = *b, *a
fmt.Printf("swap 交换后 a= %d b=%d\n", *a, *b)
}
func main() {
var a int =
var b int =
// fmt.Printf("main 交换前 a= %d b=%d\n", a, b)
// swap1(a, b)
// fmt.Printf("main 交换后 a= %d b=%d\n", a, b)
/*
main 交换前 a= 10 b=20
swap 交换前 a= 10 b=20
swap 交换后 a= 20 b=10
main 交换后 a= 10 b=20
*/
var c *int
var d *int
c = &a
d = &b
fmt.Printf("main 交换前 a= %d b=%d\n", a, b)
swap2(c, d)
fmt.Printf("main 交换后 a= %d b=%d\n", a, b)
/*
main 交换前 a= 10 b=20
swap 交换前 a= 10 b=20
swap 交换后 a= 20 b=10
main 交换后 a= 20 b=10
*/
}
go 指针类型的更多相关文章
- 对于C语言复杂指针类型的分析
转载自:http://www.slyar.com/blog/complicated-point-type.html int p; p是一个普通的整型变量. int *p; 1.p与*结合,说明p是一个 ...
- C++指针类型识别正确姿势
指针是C和C++中编程最复杂也是最有技巧的部分,但对于新手来说,指针无疑是最致命的,让很多人望而退步.不过很多事情都是从陌生开始,然后渐渐熟悉起来的,就像交朋友一样,得花点时间去培养感情才行.不过指针 ...
- C语言指针类型
1:只要是指针类型,不管是几级指针[带几个*],其宽度都是4字节 2:任何数据类型[包括自己定义的结构体]前面都能加*号,表示该数据类型的一个指针 3:由于是386处理器,其数据处理的宽度都是四个字节 ...
- 《精通C#》自定义类型转化-扩展方法-匿名类型-指针类型(11.3-11.6)
1.类型转化在C#中有很多,常用的是int类型转string等,这些都有微软给我们定义好的,我们需要的时候直接调用就是了,这是值类型中的转化,有时候我们还会需要类类型(包括结构struct)的转化,还 ...
- 编程范式 epesode7,8 stack存放指针类型and heap,register
这一节从后往前写. ____stack and heap ___stack由 汇编语言操控管理,数据先入后出. 栈是存放局部变量,函数调用子函数时,该函数在栈中占用的空间会增大,用于存放子函数的局部变 ...
- Swift中对C语言接口缓存的使用以及数组、字符串转为指针类型的方法
由于Swift编程语言属于上层编程语言,而Swift中由于为了低层的高性能计算接口,所以往往需要C语言中的指针类型,由此,在Swift编程语言刚诞生的时候就有了UnsafePointer与Unsafe ...
- C语言 数组类型与数组指针类型
//数组类型与数组指针类型 #include<stdio.h> #include<stdlib.h> #include<string.h> void main(){ ...
- C语言 详解多级指针与指针类型的关系
//V推论①:指针变量的步长只与‘指针变量的值’的类型有关(指针的值的类型 == 指针指向数据的类型) //指针类型跟指针的值有关,指针是占据4个字节大小的内存空间,但是指针的类型却是各不相同的 // ...
- (七)C语言中的void 和void 指针类型
许多初学者对C中的void 和void 的指针类型不是很了解.因此常常在使用上出现一些错误,本文将告诉大家关于void 和void 指针类型的使用方法及技巧. 1.首先,我们来说说void 的含义: ...
- 指针类型(C# 编程指南)
原文地址:https://msdn.microsoft.com/zh-cn/library/y31yhkeb.aspx 在不安全的上下文中,类型可以是指针类型.值类型或引用类型. 指针类型声明采用下列 ...
随机推荐
- MySql--学习成长过程
MySql--学习成长过程 模拟测试: QQ数据库管理 一.创建数据库并添加关系和测试数据 1 ##创建QQ数据库,完成简单的测试 2 3 #创建数据库 4 DROP DATABASE IF EXIS ...
- c++11 类默认函数的控制:"=default" 和 "=delete"函数
c++11 类默认函数的控制:"=default" 和 "=delete"函数 #define _CRT_SECURE_NO_WARNINGS #include ...
- What?
What? 本文主要讲解一下kubernetes周边的概念,可以说是一小部分的生态圈,逐渐了解一下,走进kubernetes的世界.请读者在读的时候,带着批判的态度去读. 一张概览图: 云计算: 原文 ...
- 【算法】Tarjan大锦集
Task1 Description 一位冷血的杀手潜入 Na-wiat,并假装成平民.警察希望能在 N 个人里面,查出谁是杀手. 警察能够对每一个人进行查证,假如查证的对象是平民,他会告诉警察,他认识 ...
- ASP.NET MVC 3 常用
http://blog.csdn.net/churujianghu/article/details/7297358 1.ASP.NET MVC 3 如何去除默认验证 这个默认验证是在web.confi ...
- CentOS7.3 部署Haproxy 1.7.2
haproxy:http://www.haproxy.org/ 本文涉及haproxy的安装,并做简单配置. 一.环境准备 1. 操作系统 CentOS-7-x86_64-Everything-151 ...
- label和fieldset标签
一.label标签 作用:可以通过for属性关联input标签的 id 属性,这样可以实现在点击label标签的内容时,可以使input文本框中获取输入的光标. <body> <la ...
- Docker应用二:docker常用命令介绍
Docker常用命令使用介绍 docker中常用的命令: 1.docker search image_name:搜查镜像 2.docker pull image_name:从镜像库中拉去镜像 3.d ...
- day14 多态与抽象
多态:相同的行为,不同的实现. 多态分为:静态多态和动态多态. 静态多态:在编译期即确定方法的实现和效果.——使用重载实现 动态多态:运行后才能确定方法的实现和执行效果.——使用动态绑定和重写实现 动 ...
- vue中的slot与slot-scope
深入理解vue中的slot与slot-scope vue+element-ui+slot-scope或原生实现可编辑表格 vue插槽详解