变量和内存地址

每个变量都有内存地址,可以说通过变量来操作对应大小的内存

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 指针类型的更多相关文章

  1. 对于C语言复杂指针类型的分析

    转载自:http://www.slyar.com/blog/complicated-point-type.html int p; p是一个普通的整型变量. int *p; 1.p与*结合,说明p是一个 ...

  2. C++指针类型识别正确姿势

    指针是C和C++中编程最复杂也是最有技巧的部分,但对于新手来说,指针无疑是最致命的,让很多人望而退步.不过很多事情都是从陌生开始,然后渐渐熟悉起来的,就像交朋友一样,得花点时间去培养感情才行.不过指针 ...

  3. C语言指针类型

    1:只要是指针类型,不管是几级指针[带几个*],其宽度都是4字节 2:任何数据类型[包括自己定义的结构体]前面都能加*号,表示该数据类型的一个指针 3:由于是386处理器,其数据处理的宽度都是四个字节 ...

  4. 《精通C#》自定义类型转化-扩展方法-匿名类型-指针类型(11.3-11.6)

    1.类型转化在C#中有很多,常用的是int类型转string等,这些都有微软给我们定义好的,我们需要的时候直接调用就是了,这是值类型中的转化,有时候我们还会需要类类型(包括结构struct)的转化,还 ...

  5. 编程范式 epesode7,8 stack存放指针类型and heap,register

    这一节从后往前写. ____stack and heap ___stack由 汇编语言操控管理,数据先入后出. 栈是存放局部变量,函数调用子函数时,该函数在栈中占用的空间会增大,用于存放子函数的局部变 ...

  6. Swift中对C语言接口缓存的使用以及数组、字符串转为指针类型的方法

    由于Swift编程语言属于上层编程语言,而Swift中由于为了低层的高性能计算接口,所以往往需要C语言中的指针类型,由此,在Swift编程语言刚诞生的时候就有了UnsafePointer与Unsafe ...

  7. C语言 数组类型与数组指针类型

    //数组类型与数组指针类型 #include<stdio.h> #include<stdlib.h> #include<string.h> void main(){ ...

  8. C语言 详解多级指针与指针类型的关系

    //V推论①:指针变量的步长只与‘指针变量的值’的类型有关(指针的值的类型 == 指针指向数据的类型) //指针类型跟指针的值有关,指针是占据4个字节大小的内存空间,但是指针的类型却是各不相同的 // ...

  9. (七)C语言中的void 和void 指针类型

    许多初学者对C中的void 和void 的指针类型不是很了解.因此常常在使用上出现一些错误,本文将告诉大家关于void 和void 指针类型的使用方法及技巧. 1.首先,我们来说说void 的含义: ...

  10. 指针类型(C# 编程指南)

    原文地址:https://msdn.microsoft.com/zh-cn/library/y31yhkeb.aspx 在不安全的上下文中,类型可以是指针类型.值类型或引用类型. 指针类型声明采用下列 ...

随机推荐

  1. BZOJ5100 POI2018Plan metra(构造)

    容易发现要么1和n直接相连,要么两点距离即为所有dx,1+dx,n的最小值.若为前者,需要满足所有|d1-dn|都相等,挂两棵菊花即可.若为后者,将所有满足dx,1+dx,n=d1,n的挂成一条链,其 ...

  2. 深入理解HashMap(原理,查找,扩容)

    面试的时候闻到了Hashmap的扩容机制,之前只看到了Hasmap的实现机制,补一下基础知识,讲的非常好 原文链接: http://www.iteye.com/topic/539465 Hashmap ...

  3. 如何添加ORACLE 的 ODBC

    找到  C:\windows\SysWOW64\odbcad32.exe 新增odbc ,提示 报错忽略,一直点确定就是,会建成功的! 点OK即可.新建完毕

  4. BZOJ 2844: albus就是要第一个出场

    2844: albus就是要第一个出场 Time Limit: 6 Sec  Memory Limit: 128 MBSubmit: 1134  Solved: 481[Submit][Status] ...

  5. hdu5909 Tree Cutting 【树形dp + FWT】

    题目链接 hdu5909 题解 设\(f[i][j]\)表示以\(i\)为根的子树,\(i\)一定取,剩余节点必须联通,异或和为\(j\)的方案数 初始化\(f[i][val[i]] = 1\) 枚举 ...

  6. 洛谷 P4128 [SHOI2006]有色图 解题报告

    P4128 [SHOI2006]有色图 题目描述 如果一张无向完全图(完全图就是任意两个不同的顶点之间有且仅有一条边相连)的每条边都被染成了一种颜色,我们就称这种图为有色图.如果两张有色图有相同数量的 ...

  7. 【bzoj3573】 Hnoi2014—米特运输

    http://www.lydsy.com/JudgeOnline/problem.php?id=3573 (题目链接) 题意 题意是这道题最大的难点→_→ Solution 沙茶树形dp,考虑一定会存 ...

  8. MyBatis.2剖析

    上次给大家介绍了一下properties 和 environments 的配置, 接下来就正式开始看源码了: 上次例子中,我们以 SqlSessionFactoryBuilder 去创建 SqlSes ...

  9. Maven问题合集

    背景:总结maven使用过程中的相关问题,方便以后查询! 1 问题汇总 今天在导入github上下载的maven项目时候,出现了一堆错误,一时间不知道该如何下手. 根据错误提示,发现是一些依赖的jar ...

  10. (转)maven镜像详解

    背景:一直以来,对maven镜像不是特别的了解,这里通过对网上资料的收集,做个详细的记录. 镜像介绍 如果仓库X可以提供仓库Y存储的所有内容,那么就可以认为X是Y的一个镜像.换句话说,任何一个可以从仓 ...