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 在不安全的上下文中,类型可以是指针类型.值类型或引用类型. 指针类型声明采用下列 ...
随机推荐
- Linux下安装 mongodb
1.下载 去官网 https://www.mongodb.com 找到对应版本的mongodb 的下载地址 这样的: https://fastdl.mongodb.org/linux/mongodb ...
- svmrank 的误差惩罚因子c选择 经验
C是一个由用户去指定的系数,表示对分错的点加入多少的惩罚,当C很大的时候,分错的点就会更少,但是过拟合的情况可能会比较严重,当C很小的时候,分错的点可能会很多,不过可能由此得到的模型也会不太正确,所以 ...
- Codeforces 633C Spy Syndrome 2 | Trie树裸题
Codeforces 633C Spy Syndrome 2 | Trie树裸题 一个由许多空格隔开的单词组成的字符串,进行了以下操作:把所有字符变成小写,把每个单词颠倒过来,然后去掉单词间的空格.已 ...
- 【BZOJ4916】神犇和蒟蒻 解题报告
[BZOJ4916]神犇和蒟蒻 Description 很久很久以前,有一群神犇叫sk和ypl和ssr和hjh和hgr和gjs和yay和xj和zwl和dcx和lyy和dtz和hy和xfz和myh和yw ...
- 【bzoj1483】 HNOI2009—梦幻布丁
http://www.lydsy.com/JudgeOnline/problem.php?id=1483 (题目链接) 题意 $n$个布丁摆成一行,进行$m$次操作.每次将某个颜色的布丁全部变成另一种 ...
- Kerberos无约束委派的攻击和防御
0x00 前言简介 当Active Directory首次与Windows 2000 Server一起发布时,Microsoft就提供了一种简单的机制来支持用户通过Kerberos对Web服务器进行身 ...
- 方程式EQGRP_Lost_in_Translation工具之fb.py
使用方法: 环境搭建:win2003下测试: 下载python2.6并安装 下载pywin32并安装 将C:\Python26添加到环境变量PATH中 将整个windows目录复制到windows20 ...
- 开源分布式工作流任务调度系统Easy Scheduler Release 1.0.2发布
Easy Scheduler Release 1.0.2===Easy Scheduler 1.0.2是1.x系列中的第三个版本.此版本增加了调度开放接口.worker分组(指定任务运行的机器组).任 ...
- oracle表结构和数据导出时的一些勾选项说明
使用pl/sql developer导出oracle数据库的表结构和表数据时,有一些勾选项供用户选择,需要用户根据实际情况进行勾选或取消. 导出方法如下:一.只导出表结构1.使用pl/sql deve ...
- isscroll插件 实现下拉加载 上啦刷新 转
http://www.jb51.net/article/98394.htm 下面是别人的代码 <!DOCTYPE html> <html> <head> <m ...