diff --git a/eBook/04.9.md b/eBook/04.9.md index e19d48e..4656aa6 100644 --- a/eBook/04.9.md +++ b/eBook/04.9.md @@ -9,17 +9,17 @@ Go 语言的取地址符是 `&`,放到一个变量前使用就会返回相应变量的内存地址。 下面的代码片段(示例 4.9 [pointer.go](examples/chapter_4/pointer.go))可能输出 `An integer: 5, its location in memory: 0x6b0820`(这个值随着你每次运行程序而变化)。 - + ```go var i1 = 5 fmt.Printf("An integer: %d, it's location in memory: %p\n", i1, &i1) -``` +``` 这个地址可以存储在一个叫做指针的特殊数据类型中,在本例中这是一个指向 int 的指针,即 `i1`:此处使用 *int 表示。如果我们想调用指针 intP,我们可以这样声明它: - + ```go var intP *int -``` +``` 然后使用 `intP = &i1` 是合法的,此时 intP 指向 i1。 @@ -41,10 +41,10 @@ intP 存储了 i1 的内存地址;它指向了 i1 的位置,它引用了变 对于任何一个变量 var, 如下表达式都是正确的:`var == *(&var)`。 -现在,我们应当能理解 pointer.go 中的整个程序和他的输出: +现在,我们应当能理解 pointer.go 的全部内容及其输出: 示例 4.21 [pointer.go](examples/chapter_4/pointer.go): - + ```go package main import "fmt" @@ -54,7 +54,7 @@ func main() { var intP *int intP = &i1 fmt.Printf("The value at memory location %p is %d\n", intP, *intP) -} +} ``` 输出: @@ -71,7 +71,7 @@ func main() { 它展示了分配一个新的值给 *p 并且更改这个变量自己的值(这里是一个字符串)。 示例 4.22 [string_pointer.go](examples/chapter_4/string_pointer.go) - + ```go package main import "fmt" @@ -83,7 +83,7 @@ func main() { fmt.Printf("Here is the string *p: %s\n", *p) // prints string fmt.Printf("Here is the string s: %s\n", s) // prints same string } -``` +``` 输出: @@ -100,12 +100,12 @@ func main() { **注意事项** 你不能得到一个文字或常量的地址,例如: - + ```go const i = 5 ptr := &i //error: cannot take the address of i ptr2 := &10 //error: cannot take the address of 10 -``` +``` 所以说,Go 语言和 C、C++ 以及 D 语言这些低级(系统)语言一样,都有指针的概念。但是对于经常导致 C 语言内存泄漏继而程序崩溃的指针运算(所谓的指针算法,如:`pointer+2`,移动指针指向字符串的字节数或数组的某个位置)是不被允许的。Go 语言中的指针保证了内存安全,更像是 Java、C# 和 VB.NET 中的引用。 @@ -122,7 +122,7 @@ ptr2 := &10 //error: cannot take the address of 10 对一个空指针的反向引用是不合法的,并且会使程序崩溃: 示例 4.23 [testcrash.go](examples/chapter_4/testcrash.go): - + ```go package main func main() { @@ -131,7 +131,7 @@ func main() { } // in Windows: stops only with: // runtime error: invalid memory address or nil pointer dereference -``` +``` **问题 4.2** 列举 Go 语言中 * 号的所有用法。