zoukankan      html  css  js  c++  java
  • <11>Golang基础进阶——指针

    Golang基础进阶——指针

    变量和内存地址

    每个变量都有内存地址,可以理解为变量来操作对应的内存,go语言的取地址符是&,放到一个变量前使用就会返回相应变量的内存地址,&符跟指针类型息息相关

    func main() {
    	var a int = 10
    	fmt.Printf("变量地址:%x
    ", &a)
    }
    

    指针类型介绍

    指针类型,变量存的是一个地址,这个地址存的才是值

    获取指针类型所指向的值,使用 *。示例:

    func main(){
    	var a int
    	var p *int
    	// 指针只能存储地址否则报错, &a表示取a的地址存储到p
    	p = &a
    	// p存储的是a的内存地址,取出a地址指向的值就得需要加*,才能从地址中取值
    	fmp.Println(*p)
    	fmp.Println(p)
    }
    

    值类型和引用类型

    • 值类型:int、float、bool、array、struct、string这些类型都属于值类型,使用这些类型的变量直接指向存在内存中的值,值类型的变量的值存储在栈中。当使用等号=将一个变量的值赋给另一个变量时,如 j = i ,实际上是在内存中将 i 的值进行了拷贝。特点:变量直接存储值,内存通常在栈中分配,栈在函数调用完会被释放
    • 引用类型:特指指针、slice、map、channel这三种预定义类型。引用类型拥有更复杂的存储结构:(1)分配内存 (2)初始化一系列属性等一个引用类型的变量r1存储的是r1的值所在的内存地址(数字),或内存地址中第一个字所在的位置,这个内存地址被称之为指针,这个指针实际上也被存在另外的某一个字中。特点:变量存储的是一个地址,这个地址存储最终的值。内存通常在堆上分配,通过GC回收。
    var 指针变量名 *指针类型
    

    示例:

    func main() {
    	var a int = 20
    	var ip *int
    	// 指针存地址
    	ip = &a
    	// %x 以十进制方式表示
    	fmt.Printf("a的地址:%x
    ", &a)
    	fmt.Printf("ip变量的值:%x
    ", ip)
    	fmt.Printf("ip指向的变量的值:%d
    ", *ip)
    }

     空指针

    当一个指针被定义后没有分配到任何变量时,它的值为 nil

    func main() {
    	var p *int
    	fmt.Println(p)
    	fmt.Printf("p的值 %x
    ", p)
    }

    值传递和引用传递

    示例1:

    func swap(a, b *int) {
    	fmt.Println(a, b)
    	*a, *b = *b, *a
    }
    
    func main() {
    	a, b := 3, 4
    	swap(&a, &b)
    	fmt.Println(a, b)
    }

    示例2:

    func swap(a, b *int) (*int, *int) {
    
    	a, b = b, a
    	return a, b
    }
    
    func main() {
    	a, b := 3, 4
    	c, d := swap(&a, &b)
    	fmt.Println(*c, *d)
    
    	a = *c
    	// *d 指向 a,a更改为4,所以*d也更改为4
    	b = *d
    	fmt.Println(a, b)
    
    }

    new()和make()

    • make()用来分配引用类型的内存,例如slice、map、channel并且初始化内存
    • new()用来分配各种类型的内存,但它不会初始化内存,创建之后是一个指针类型
    • make()的用途不同于new(),它只能创建slice、map、channel,并返回类型为T(非指针)的已初始化(非零值)的值

    示例:

    func main() {
    	p := new(int)
    	fmt.Println(p)        // 0xc000054080
    	fmt.Println(*p)       // 0
    	fmt.Printf("%T
    ", p) // *int
    
    	m := make([]int, 10, 50)
    	fmt.Println(m)
    }
    加油,你们是最棒的!
  • 相关阅读:
    编程习俗和设计模式
    Design Patterns Quick Memo
    Monty Hall Problem
    RPG game: the lost Roman Army
    A Geeky Game Idea
    App自动化测试:等待webview页面数据加载完成
    Android自动化测试元素定位
    IOS苹果开发者免费证书申请&使用Xcode打包
    pytest测试夹具(fixture)简介
    Unittest与Pytest参数化区别
  • 原文地址:https://www.cnblogs.com/Wshile/p/12793624.html
Copyright © 2011-2022 走看看