2016-04-04 9 views
-1

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

+0

Weil so die Sprache entworfen wird. Es wäre ein Durcheinander, wenn es so funktioniert, wie Sie es vorschlagen. –

+0

Der Compiler gab Ihnen keinen Hinweis, wenn Sie versuchten, Code wie diesen zu kompilieren? –

+0

Solche grundlegenden Fragen werden von jedem C-Buch beantwortet. Lesen Sie einen. – Olaf

Antwort

1

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.)

+0

Lundin vielen Dank für diese hilfreichen Informationen! Ich schätze es sehr. –

2

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.

3

Die große Unterschied ist, dass in dem ersten Fall ist ein pnZeiger 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).

+0

Dies ist eine perfekte Erklärung. Vielen Dank! –

4

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.

1

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.

Verwandte Themen