Die Go-Sprache verfügt nicht über Zeigerarithmetik. Die Syntax der Go-Sprache unterstützt keine Zeigerarithmetik und alle Zeiger werden innerhalb eines kontrollierbaren Bereichs verwendet. Tatsächlich kann die Go-Sprache den Zeiger jedoch indirekt über die Pointer()-Methode des unsicheren Pakets in eine Zahl vom Typ uintptr umwandeln Implementieren Sie Zeigerarithmetik.
Die Betriebsumgebung dieses Tutorials: Windows 7-System, GO Version 1.18, Dell G3-Computer.
Speicher ist eine Reihe von Speichereinheiten mit Seriennummern. Variablen sind Spitznamen, die der Compiler den Speicheradressen zuweist.
Ein Zeiger ist ein Wert, der auf eine andere Speicheradressenvariable zeigt
Der Zeiger zeigt auf die Speicheradresse der Variablen, und der Zeiger ist wie die Speicheradresse des Variablenwerts
Werfen wir einen Blick auf einen Code snippet
func main() { a := 200 b := &a *b++ fmt.Println(a) }
In der Hauptfunktion definieren wir in der ersten Zeile eine neue Variable a und weisen ihr den Wert 200 zu. Als nächstes definieren wir eine Variable b und weisen b die Adresse der Variablen a zu. Wir kennen die genaue Speicheradresse von a nicht, aber wir können die Adresse von a trotzdem in der Variablen b speichern.
Aufgrund der starken Typisierung von Go ist die dritte Codezeile vielleicht die aufdringlichste, aber wir möchten den in der a-Variablen gespeicherten Wert erhöhen .
Auf diese Weise müssen wir b dereferenzieren und stattdessen auf a verweisen, indem b dem Zeiger folgt.
Dann addieren wir 1 zum Wert und speichern ihn wieder an der in b hinterlegten Speicheradresse.
Die letzte Zeile gibt den Wert von a aus. Sie können sehen, dass der Wert von a auf 201 gestiegen ist Um
eine bestimmte Variable zu ändern, können wireine Zeigervariable erstellen , die auf die Adresse der Variablen zeigt.
Im Gegensatz zu Zeigern in C/C++ können Zeiger in der Go-Sprache nicht versetzt und bedient werden und sind sichere Zeiger
.Um Zeiger in der Go-Sprache zu verstehen, müssen Sie zunächst drei Konzepte kennen: Zeigeradresse, Zeigertyp und Zeigerwert. Zeigeradresse und Zeigertyp
Zeigeroperationen in der Go-Sprache sind sehr einfach. Sie müssen sich nur zwei Symbole merken: & (Adresse abrufen) und * (Wert basierend auf Adresse abrufen).
Jede Variable hat zur Laufzeit eine Adresse, die den Speicherort der Variablen darstellt. In der Go-Sprache wird das &-Zeichen vor der Variablen verwendet, um „die Adresse“ der Variablen abzurufen.
Die Syntax zum Erfassen eines Variablenzeigers lautet wie folgt:
ptr := &v // v的类型为T
v: Die Variable, die die übernommene Adresse darstellt, der Typ ist Tptr: Die Variable, die zum Empfangen verwendet wird Adresse, der Typ von ptr ist * T wird als Zeigertyp von T bezeichnet. * steht für Zeiger.
func main() { a := 10 b := &a fmt.Printf("a:%d ptr:%p\n", a, &a) // a:10 ptr:0xc00001a078 fmt.Printf("b:%p type:%T\n", b, b) // b:0xc00001a078 type:*int fmt.Println(&b) // 0xc00000e018 }
Zeigeroperator
1. Wenn der Zeigeroperator ein L-Wert ist, können wir den Status des Zielobjekts aktualisieren; wenn es ein R-Wert ist, dient er dazu, den Status des Ziels zu erhalten .
func main() { x := 10 var p *int = &x //获取地址,保存到指针变量 *p += 20 //用指针间接引用,并更新对象 println(p, *p) //输出指针所存储的地址,以及目标对象 }
0xc000040780 30
func main() { x := 10 p := &x p++ //编译报错 invalid operation: p++ (non-numeric type *int) var p2 *int = p+1 //invalid operation: p + 1 (mismatched types *int and int) p2 = &x println(p == p2) //指向同一地址 }
Zeigerarithmetik
In vielen Golang-Programmen werden zwar Zeiger verwendet, Zeiger werden jedoch nicht addiert oder subtrahiert, was sich stark von C-Programmen unterscheidet. Golangs offizielles Einführungs-Lerntool (go-Tour) besagt sogar, dass Go keine Zeigerarithmetik unterstützt. Obwohl dies nicht wirklich der Fall ist, habe ich anscheinend noch nie Zeigerarithmetik in gewöhnlichen Go-Programmen gesehen (naja, ich weiß, dass Sie ungewöhnliche Programme schreiben möchten).
- 但实际上,go 可以通过
unsafe.Pointer
来把指针转换为uintptr
类型的数字,来间接实现指针运算。- 这里请注意,
uintptr
是一种整数类型,而不是指针类型。
比如:
uintptr(unsafe.Pointer(&p)) + 1
就得到了 &p
的下一个字节的位置。然而,根据 《Go Programming Language》 的提示,我们最好直接把这个计算得到的内存地址转换为指针类型:
unsafe.Pointer(uintptr(unsafe.Pointer(&p) + 1))
因为 go 中是有垃圾回收机制的,如果某种 GC 挪动了目标值的内存地址,以整型来存储的指针数值,就成了无效的值。
同时也要注意,go 中对指针的 + 1,真的就只是指向了下一个字节,而 C 中 + 1
或者 ++
考虑了数据类型的长度,会自动指向当前值结尾后的下一个字节(或者说,有可能就是下一个值的开始)。如果 go 中要想实现同样的效果,可以使用 unsafe.Sizeof
方法:
unsafe.Pointer(uintptr(unsafe.Pointer(&p) + unsafe.Sizeof(p)))
最后,另外一种常用的指针操作是转换指针类型。这也可以利用 unsafe 包来实现:
var a int64 = 1 (*int8)(unsafe.Pointer(&a))
如果你没有遇到过需要转换指针类型的需求,可以看看这个项目(端口扫描工具),其中构建 IP 协议首部的代码,就用到了指针类型转换。
Das obige ist der detaillierte Inhalt vonWas sind die Operationen für Zeiger in der Go-Sprache?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!