From cb8055ca917bd5bd6ddd7ced2ea51c9eecebc2b1 Mon Sep 17 00:00:00 2001 From: xlj Date: Tue, 19 Dec 2023 15:38:42 +0800 Subject: [PATCH] add doc for pointer --- 120-Pointers/pointer-1.gop | 19 +++++++++++++++++++ 120-Pointers/pointer-2.gop | 26 ++++++++++++++++++++++++++ 120-Pointers/pointer-3.gop | 14 ++++++++++++++ 120-Pointers/pointer-4.gop | 17 +++++++++++++++++ 120-Pointers/pointer.gop | 1 - 5 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 120-Pointers/pointer-1.gop create mode 100644 120-Pointers/pointer-2.gop create mode 100644 120-Pointers/pointer-3.gop create mode 100644 120-Pointers/pointer-4.gop delete mode 100644 120-Pointers/pointer.gop diff --git a/120-Pointers/pointer-1.gop b/120-Pointers/pointer-1.gop new file mode 100644 index 0000000..58b5cfb --- /dev/null +++ b/120-Pointers/pointer-1.gop @@ -0,0 +1,19 @@ +// A pointer is a variable whose value is a memory address. Pointers are defined using an ampersand (the & character), known as the address operator, followed by +// the name of a variable +// +// A pointer’s type is fixed, which means that when you create a pointer +// to an int, for example, you change the value that it points to, but you can’t use it to point to the memory +// address used to store a different type, such as a float64. This restriction is important, pointers are +// not just memory addresses but, rather, memory addresses that may store a specific type of value. +// +// The type of a pointer is based on the type of the variable from which it is created, prefixed with an +// asterisk (the * character). The type of variable named second is *int, because it was created by applying +// the address operator to the first variable, whose value is int. When you see the type *int, you know it is a +// variable whose value is a memory address that stores an int variable. +// + +first := 100 +var second *int = &first +first++ +println("First:", first) +println("Second:", second) diff --git a/120-Pointers/pointer-2.gop b/120-Pointers/pointer-2.gop new file mode 100644 index 0000000..93630fc --- /dev/null +++ b/120-Pointers/pointer-2.gop @@ -0,0 +1,26 @@ +# Following a Pointer +// The phrase following a pointer means reading the value at the memory address that the pointer refers +// to, and it is done using an asterisk (the * character). The asterisk tells Go+ to follow the pointer and get the value at the memory location. This is known as dereferencing the pointer. + +first := 100 +second := &first +first++ +*second++ +var myNewPointer *int +myNewPointer = second +*myNewPointer++ +println("First:", first) +println("Second:", *second) + +// The first new statement defines a new variable, which I have done with the var keyword to emphasize +// that the variable type is *int, meaning a pointer to an int value. The next statement assigns the value of +// the second variable to the new variable, meaning that the values of both second and myNewPointer are the +// memory location of the first value. Following either pointer accesses the same memory location, which +// means incrementing myNewPointer affects the value obtained by following the second pointer. +// +// A common misconception is that the first and second variables have the same value, but that’s not +// what is happening. There are two values. There is an int value that can be accessed using the variable +// named first. There is also an *int value that stores the memory location of the first value. The *int value +// can be followed, which will access the stored int value. But, because the *int value is, well, a value, it can be +// used in its own right, which means that it can be assigned to other variables, used as an argument to invoke a +// function, and so on. diff --git a/120-Pointers/pointer-3.gop b/120-Pointers/pointer-3.gop new file mode 100644 index 0000000..31b1ddc --- /dev/null +++ b/120-Pointers/pointer-3.gop @@ -0,0 +1,14 @@ +# Understanding Pointer Zero Values +// Pointers that are defined but not assigned a value have the zero-value nil. +// +// The pointer second is defined but not initialized with a value and is written out using the println +// function. The address operator is used to create a pointer to the first variable, and the value of second is +// written out again. +// +// A runtime error will occur if you follow a pointer that has not been assigned a value + +first := 100 +var second *int +println(second) +second = &first +println(second) diff --git a/120-Pointers/pointer-4.gop b/120-Pointers/pointer-4.gop new file mode 100644 index 0000000..f19ced6 --- /dev/null +++ b/120-Pointers/pointer-4.gop @@ -0,0 +1,17 @@ +# Pointing at Pointers +// Given that pointers store memory locations, it is possible to create a pointer whose value is the memory +// address of another pointer. + +first := 100 +second := &first +third := &second +println(first) +println(*second) +println(**third) + +// The syntax for following chains of pointers can be awkward. In this case, two asterisks are required. +// The first asterisk follows the pointer to the memory location to get the value stored by the variable named +// second, which is an *int value. The second asterisk follows the pointer named second, which gives access +// to the memory location of the value stored by the first variable. This isn’t something you will need to do +// in most projects, but it does provide a nice confirmation of how pointers work and how you can follow the +// chain to get to the data value. diff --git a/120-Pointers/pointer.gop b/120-Pointers/pointer.gop deleted file mode 100644 index 8b13789..0000000 --- a/120-Pointers/pointer.gop +++ /dev/null @@ -1 +0,0 @@ -