Frage zu Zeigern. Ich weiß in der Deklaration int* pn = &n
, pn
wird als Zeiger auf die Speicheradresse n
initialisiert. Warum können wir nicht einfach int pn = &n
sagen? Wenn wir es so schreiben würden, wäre das nicht dasselbe, als würde man die Variable pn
auf den Speicherort von n
setzen? Ich verstehe nicht genau, warum die *
notwendig ist.Was ist der Unterschied zwischen int * pn = & n und int pn = & n in C Sprache
Antwort
Ich nehme an, dass Ihre Frage darauf hinausläuft: Warum gibt es einen Zeigertyp in C, wenn Adressen wirklich nur ganze Zahlen sind? Dafür gibt es einige Gründe.
Zunächst das Offensichtliche, könnte der Adressbus eine andere Größe als die Integer-Typ des Systems, so dass es möglicherweise nicht in einer ganzen Zahl passen. Als Randnotiz ist der Typ
int
signiert, so dass es wahrscheinlich auch aus diesem Grund nicht möglich ist, eine Adresse zu speichern, da Adressen normalerweise ohne Vorzeichen sind.Aber auch, weil wir einen eindeutigen Zeigertyp wollen, der nicht mit ganzen Zahlen verwechselt werden kann. C verhindert, dass Sie implizite Konvertierungen zwischen Ganzzahlen zu/von Zeigern durchführen. Die Zeile
int pn = &n
wird nicht wirklich kompiliert, weil sie gegen diese Typsicherheit verstößt (die "einfache Zuweisung" -Regel). Einige Compiler sind ein wenig nachlässig dafür, Compiler-Fehler dafür zu geben, obwohl es sich um eine C-Standardverletzung handelt. (In GCC stellen Sie sicher, dass Sie-pedantic-errors
gesetzt haben)Und da wir einen eindeutigen Zeigertyp haben, ermöglicht uns C auch Pointerarithmetik basierend auf dem Spitzentyp, der mächtig praktisch ist. Zum Beispiel erlaubt es uns, Zeiger so zu verwenden, als ob sie Arrays wären.
Moderne C führt zwei neue Integer-Typen, die verwendet werden können, sicher zu Adressen speichern: uintptr_t
und intptr_t
. Diese sind garantiert groß genug sein, sicher eine Adresse zu speichern, aber Sie haben noch eine explizite Umwandlung zum/vom Zeigertyp verwenden:
uintptr_t pn = (uintptr_t)&n;
(intptr_t
ist mild nützlich, obwohl es exotische Fälle, in denen Sie haben tatsächlich negative Adressen. Ich glaube, dass einige virtuelle Speicheradressierung auf bestimmten Systemen negative Adressen verwenden können, um Kerneladressraum anzuzeigen.)
Lundin vielen Dank für diese hilfreichen Informationen! Ich schätze es sehr. –
Es ist anzugeben, dass pn
ist ein Zeiger auf eine int
und nicht tatsächlich eine int
. Die Größe eines Zeigers ist nicht identisch mit der Größe des Objekts (in den meisten Fällen). Lesen Sie mehr über Zeiger für weitere Details.
Die große Unterschied ist, dass in dem ersten Fall ist ein pn
Zeiger und man kann sie als solche verwendet werden, einschließlich der Verwendung von Array-Indexierung und die Dereferenzierungsoperator.
Im zweiten Fall pn
ist eine einfache int
Variable, deren Inhalt gerade die Adresse n
enthält. Der zweite Fall ist auch tückisch, wenn Sie sich auf einem 64-Bit-System befinden, dessen Adressen 64 Bit (8 Byte) breit sind und int
normalerweise 32 Bit (4 Byte) breit ist.
Mehr "grafisch" wird wie folgt angesehen werden:
den Code
int n = some value;
int *p = &n; // Make p point to n
int v = &n; // Initialize v to the address of n
Dann
+---+ +---+ | p | ---> | n | +---+ +---+ +---+ | v | +---+
Die Variable v
nur allein so etwas wie es aussieht Nimmt man sitzt , was den Wert enthält, mit dem es initialisiert wurde. Aber Punkte auf den Standort n
.
Das in der Realität, auf der tatsächlichen Hardware, ist der Inhalt von und v
gleich (auf Plattformen, wo sizeof(int) == sizeof(int *)
) ist nicht wirklich wichtig. Es ist wie der Compiler diese verschiedenen Variablen behandelt, das ist der Punkt (Wortspiel nicht beabsichtigt).
Dies ist eine perfekte Erklärung. Vielen Dank! –
Ich verstehe nicht genau, warum das * notwendig ist.
Um zwischen einem Zeiger und einer Ganzzahl wahrscheinlich zu unterscheiden, weil sie auch unterschiedliche Bedeutung und Funktionalität haben.
Die Anweisung int pn = &n;
ist falsch, wenn Sie & in Ihrem Code verwenden c Compiler versteht, dass Sie Woth-Adressen behandeln werden. In anderen, einfacheren Worten können wir sagen, dass & Adresse des Operators ist.
In Ihrer Anweisung versuchen Sie, eine normale Integer-Variable mit der Adresse des anderen zu initialisieren, was nicht korrekt ist.Wenn Sie &n
Compiler denken, dass Sie eine Variable mit der Adresse von n initialisieren werden, sollte diese Variable definitiv ein Zeiger sein, da Adressen nicht in einer normalen Variablen gespeichert werden können. Ich hoffe, es wird dir helfen.
- 1. Was ist der Unterschied zwischen 'int?' und 'int' in C#?
- 2. Was ist der Unterschied zwischen "$^N" und "$ +"?
- 3. Was ist der Unterschied zwischen \ n und \ r \ n?
- 4. Was ist der Unterschied zwischen int [] [] und int [,]?
- 5. was ist der Unterschied zwischen 'neuen()' int und 'int * p'
- 6. Was ist der Unterschied zwischen int ++ und ++ int?
- 7. Was ist der Unterschied zwischen "int * a = new int" und "int * a = new int()"?
- 8. Was ist der Unterschied zwischen int und C.int in go?
- 9. Unterschied zwischen int * i und int * ich
- 10. Was ist der Unterschied zwischen int x = 1 und int x (1) in C++?
- 11. Was ist der Unterschied zwischen `extern int (x) []` und `extern int x []` in C?
- 12. In Javascript, was ist der Unterschied zwischen '\' und '\ n'?
- 13. Unterschied zwischen char [N] und char (&) [N] in Parameterliste
- 14. Was ist der Unterschied zwischen int (* p) [3] und int * p [3]?
- 15. Unterschied zwischen Long und Int in C#?
- 16. Unterschied zwischen void (int) und void (*) (int)
- 17. Was ist der Unterschied zwischen "% [^ \ n]" und "% s" für scanf?
- 18. Unterschied zwischen "\ n" und Environment.NewLine
- 19. Was ist der Unterschied zwischen foo (int arr []) und foo (int arr [10])?
- 20. Was ist der Unterschied zwischen replyate n mal und n direkt in Stichprobe von R generieren?
- 21. Unterschied zwischen \ r und \ n
- 22. praktische Unterschied zwischen int und char
- 23. Unterschied zwischen O (n) und O (log (n)) - was ist besser und was genau ist O (log (n))?
- 24. Was ist der Unterschied zwischen int: Int und var in swift
- 25. C: Unterschied zwischen (int) x und Boden (x)?
- 26. Was ist der Unterschied zwischen% d und% * d in der Sprache c?
- 27. Unterschied zwischen \ n und CR
- 28. Was ist die Größe eines SQL Int (N)?
- 29. Was ist der Unterschied zwischen [T; N] und U wenn U immer auf [T; N]?
- 30. C/C++ int [] vs int * (Zeiger vs. Array-Notation). Was ist der Unterschied?
Weil so die Sprache entworfen wird. Es wäre ein Durcheinander, wenn es so funktioniert, wie Sie es vorschlagen. –
Der Compiler gab Ihnen keinen Hinweis, wenn Sie versuchten, Code wie diesen zu kompilieren? –
Solche grundlegenden Fragen werden von jedem C-Buch beantwortet. Lesen Sie einen. – Olaf