变量和内存地址

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

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. 对CAS机制的理解(二)

    一.Java当中CAS的底层实现首先看看AtomicInteger的源码,AtomicInteger中常用的自增方法 incrementAndGet: public final int increme ...

  2. SQLServer 重建索引前后对比 (转)

    https://www.cnblogs.com/mingl12/p/5730178.html

  3. ldap添加memberof支持

    安装请查看上一篇博客,传送门:https://www.cnblogs.com/crysmile/p/9470508.html 如果使用LDAP仅仅作为用户统一登录中心,则参考安装文档即可:如果ldap ...

  4. 只会java,参加acm如何?

    作者:董适链接:https://www.zhihu.com/question/31213070/answer/51054677来源:知乎著作权归作者所有,转载请联系作者获得授权. 当然合适,有什么不合 ...

  5. 【转】VS2012简单的使用感受+插件推荐

    转自:http://blog.sina.com.cn/s/blog_58c506600101b34t.html ~PS:后面有博主自己补充的VS2013的哦~ 1.Visual Studio Achi ...

  6. 【Cf #299 C】Tavas and Pashmaks(单调栈,凸性)

    一个经典的二维数点模型,如果某个人 $ x $ 两个速度都比另一个人 $ y $ 大,显然 $y$ 是不可能成为winner的. 但这里只考虑两个人$x$,$y$在两个属性各有千秋的时候,一定存在正整 ...

  7. 【uoj33】 UR #2—树上GCD

    http://uoj.ac/problem/33 (题目链接) 题意 给出一棵${n}$个节点的有根树,${f_{u,v}=gcd(dis(u,lca(u,v)),dis(v,lca(u,v)))}$ ...

  8. 用C语言获取任意文件的长度(可能大于2GB)#define _FILE_OFFSET_BITS 64

    打开文件后用 fseek() 函数把文件位置指针移动到文件的末尾,用 ftell() 获得这时位置指针距文件头的字节数,这个字节数就是文件的长度.但是这样做也会受到下面的限制:ftell() 函数的返 ...

  9. Android Layout_weight 属性

    Android 对Layout_weight属性完全解析以及使用ListView来实现表格http://blog.csdn.net/xiaanming/article/details/13630837 ...

  10. Python中__init__.py文件的作用详解

    转自http://www.jb51.net/article/92863.htm Python中__init__.py文件的作用详解 http://www.jb51.net/article/86580. ...