美文网首页
go内存地址

go内存地址

作者: seven_son | 来源:发表于2017-08-17 10:53 被阅读1453次

go内存地址

  • 内存地址
    在go中获得该变量的内存地址 用&a
func main() {
    a := 43
    b := &a
    fmt.Println("a - ", a)
    fmt.Println("b - ", b)
}

首先声明了一个int类型的变量a,它的值为0,然后又声明了一个a的引用b,b只是a的一个别名而已,并没有占用内存空间。实际上他们是同一个同西,在内存中占用同样的一个存储单元。

  • 变量名是个什么东西 赋的值又是个什么东西
    char a;
    1 变量
    用来标识(identify)一块内存区域,这块区域的值一般是可以更改的,这就是它“变”的由来,但是我们可以通过使用如
    const等一些修饰符号来限定这一内存区域的操作特性(characteristic),即变量的操作特性。用const修饰的使变量不能更改
    的就和常量一样的变量叫做常变量。
    2 变量名
    是一个标识符(identifier),用来指代一块内存区域,即变量,使用变量使我们操作内存以区域(area),以块(block)为单位,
    提高了方便性。
    3 变量名不会出现在机器中
    你的机器代码中,是不会出现变量名的;变量名是给我们程序员操作内存来使用的。
    想想在汇编年代,没有变量名,我们操作内存,都是用地址来直接操作的,还要控制区域大小;当然汇编语言已经有了简·
    单的变量。
    4 赋值操作过程
    对于编译器,它会搜集我们的变量名,比如我们定义了一个全局的int a;那么编译器都为我们做了什么呢?
    它会为程序预留4个字节的空间(假设在32位平台),并把我们的变量名“a”保存进符号表,并用这个符号表的索引对应实
    际的空间
    如果下面出现b = a;那么它就会根据符号表找到变量的真正的物理位置,取得它的值,赋给b。
    这是写编译器需要做的,我们需要建立符号表。
    但是实际在汇编层次上,操作的都是地址而已,不存在任何名称了。
    1、a 表示一块内存空间 表示本身的值
    2、&a 表示当前内存空间的地址 值所对应的地址
    那么指针变量就具有3种形态:
    1、a 表示指针a对应的内存空间(可以说就是指针本身的值)
    2、&a 表示当前指针对应的内存空间的首地址(存放指针的地址) 指针就是一个地址
    3、*a 表示指针a所指向的变量对应的整个内存空间。(指针指向的空间)

  • 指针变量 普通变量 内存 和地址的全面对比
    1 内存
    是什么,内存是实实在在的硬件,可以存数据,运行时的数据全放在里面
    想想一点,内存就像一个个的小个子,每个格子的带下是一个一个字节,可以存放一个字节的数据
    2 地址
    地址是内训的一个表标识,每一个地址度对应一个内训,所以内存和地址一一对相应
    3 普通变量
    如 char a; 就是一个普通变量。普通变量a其实是语言本身创造了,是为了更方便的表示内存。我们对a进行访问其实就
    是直接对内存进行访问。至于a表示的内存的地址是多少,程序员一般不用关心。编译器会自动分配地址,也就是常说的
    为a分配一个地址。如果想知道a的地址也可以通过&a得知。
    4 指针变量
    他和普通变量的区别在于,普通变量是和一块内存空间关联。而指针变量却是和两块内存空间想关联:

5 go中所有的都是按值传递,对于复杂类型,传的是指针的拷贝

     func main() {
    var m map[int]string = map[int]string{
        0: "0",
        1: "1",
    }
    mm := m
    fmt.Printf("%p\n", &m)  //0xc42002a028
    fmt.Printf("%p\n", &mm) //0xc42002a030
    fmt.Println(m)          // map[0:0 1:1]
    fmt.Println(mm)         //map[1:1 0:0]
    changeMap(m)
    fmt.Printf("%p\n", &m)  //0xc42002a028
    fmt.Printf("%p\n", &mm) //0xc42002a030
    fmt.Println(m)          //map[2:2 0:0 1:1]
    fmt.Println(mm)         //map[0:0 1:1 2:2]
    }
    func changeMap(mmm map[int]string) {
    mmm[2] = "2"
    fmt.Printf("changeMap func %p\n", mmm) //changeMap func 0xc420014150
   }

直接传指针 也是传指针的拷贝

func main() {
    var m map[int]string = map[int]string{
        0: "0",
        1: "1",
    }
    mm := m
    fmt.Printf("%p\n", &m)  //0xc42002a028
    fmt.Printf("%p\n", &mm) //0xc42002a030
    fmt.Println(m)          // map[0:0 1:1]
    fmt.Println(mm)         //map[1:1 0:0]
    changeMap(&mm)
    fmt.Printf("%p\n", &m)  //0xc42002a028
    fmt.Printf("%p\n", &mm) //0xc42002a030
    fmt.Println(m)          //map[2:2 0:0 1:1]
    fmt.Println(mm)         //map[0:0 1:1 2:2]
}
func changeMap(mmm *map[int]string) {
    mmm = nil
    fmt.Printf("changeMap func %p\n", mmm) //changeMap func 0xc420014150
}

相关文章

  • go内存地址

    go内存地址 内存地址在go中获得该变量的内存地址 用&a 首先声明了一个int类型的变量a,它的值为0,然后又声...

  • go 内存地址

  • day02-13pointer

    指针(指向内存的地址) &:取内存地址 *:根据内存地址取值 vscode 不支持go module new 函数...

  • Go-Pointer

    go 指针 声明指针类型 x 错误写法此时创建的是一个空指针,而空指针无法获取到内存地址,也就无法根据内存地址找到...

  • 【Golang进阶】指针的详细讲解

    指针是一个代表着某个内存地址的值, 这个内存地址往往是在内存中存储的另一个变量的值的起始位置. Go语言对指针的支...

  • 对Java中HashCode方法的深入思考

    前言 最近在学习 Go 语言,Go 语言中有指针对象,一个指针变量指向了一个值的内存地址。学习过 C 语言的猿友应...

  • 2019-05-21 Go语言学习二(接上)

    三、更多类型:struct、slice和映射 1.指针 Go 的指针保存了值的内存地址。 类型 *T 是指向 T ...

  • 【技术】Golang初探——指针、数组、map、函数

    指针 Go 具有指针。 指针保存了变量的内存地址。类型 *T 是指向类型 T 的值的指针。其零值是 nil。 '*...

  • GO语言基础(三)

    指针 Go 拥有指针。指针保存了值的内存地址。 类型 *T 是指向 T 类型值的指针。其零值为 nil。 & 操作...

  • Go 指南 复杂类型

    一、指针 Go 具有指针。 指针保存了变量的内存地址。 类型 *T 是指向类型 T 的值的指针。其零值是 nil ...

网友评论

      本文标题:go内存地址

      本文链接:https://www.haomeiwen.com/subject/ptwbrxtx.html