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)
    }
    加油,你们是最棒的!
  • 相关阅读:
    JDBC 查询的三大参数 setFetchSize prepareStatement(String sql, int resultSetType, int resultSetConcur)
    有空必看
    SpringMVC 利用AbstractRoutingDataSource实现动态数据源切换
    FusionCharts JavaScript API Column 3D Chart
    FusionCharts JavaScript API
    FusionCharts JavaScript API
    Extjs 继承Ext.Component自定义组件
    eclipse 彻底修改复制后的项目名称
    spring 转换器和格式化
    Eclipse快速生成一个JavaBean类的方法
  • 原文地址:https://www.cnblogs.com/Wshile/p/12793624.html
Copyright © 2011-2022 走看看