Ich fange gerade mit Zeigern an und bin etwas verwirrt. Ich weiß, &
bedeutet die Adresse einer Variablen, *
die vor einer Zeigervariablen verwendet werden kann, um den Wert des Objekts zu erhalten, auf das der Zeiger zeigt. Aber die Dinge funktionieren anders, wenn Sie mit Arrays, Strings arbeiten oder wenn Sie Funktionen mit einer Zeigerkopie einer Variablen aufrufen. Es ist schwierig, in all dem ein logisches Muster zu erkennen.
Wann soll ich &
und verwenden *
?
RTFM
ist nicht hilfreich und ehrlich gesagt sehr unhöflich. Wenn Sie keine Zeit haben zu antworten, respektieren Sie diejenigen, die sich Zeit nehmen, um diese Fragen zu beantworten. Ich wünschte, ich könnte dies an "anon" senden, aber offensichtlich hat er / sie nicht die Zeit, auf sinnvolle Weise einen Beitrag zu leisten.Antworten:
Sie haben Zeiger und Werte:
Sie verwandeln einen Zeiger in einen Wert mit
*
:Sie verwandeln einen Wert in einen Zeiger mit
&
:Bearbeiten: Bei Arrays werden sie sehr ähnlich wie Zeiger behandelt. Wenn Sie sie als Zeiger betrachten, werden Sie sie verwenden
*
, um zu den Werten in ihnen zu gelangen, wie oben erläutert. Es gibt jedoch auch eine andere, häufigere Methode, den[]
Operator zu verwenden:So erhalten Sie das zweite Element:
Der
[]
Indexierungsoperator ist also eine spezielle Form des*
Operators und funktioniert folgendermaßen:quelle
int aX[] = {3, 4}; int *bX = &aX;
int *bX = &aX;
funktioniert das Beispiel nicht, weil dasaX
bereits die Adresse vonaX[0]
(dh&aX[0]
) zurückgibt , also&aX
die Adresse einer Adresse erhalten würde, die keinen Sinn ergibt . Ist das richtig?int aX[] = {3,4};
,int **bX = &aX;
ist ein Fehler.&aX
ist vom Typ "Zeiger auf Array [2] vonint
", nicht "Zeiger auf Zeiger aufint
". Insbesondere wird der Name eines Arrays nicht als Zeiger auf sein erstes Element für unär behandelt&
. Sie können tun:int (*bX)[2] = &aX;
Beim Umgang mit Arrays und Funktionen gibt es ein Muster. es ist zunächst nur ein wenig schwer zu sehen.
Beim Umgang mit Arrays ist Folgendes zu beachten: Wenn in den meisten Kontexten ein Array-Ausdruck angezeigt wird, wird der Typ des Ausdrucks implizit von "N-Element-Array von T" in "Zeiger auf T" konvertiert und sein Wert festgelegt um auf das erste Element im Array zu zeigen. Die Ausnahmen von dieser Regel sind , wenn der Array Ausdruck erscheint als Operanden entweder die
&
odersizeof
Betreiber, oder wenn es ein Stringliteral als Initialisierer in einer Erklärung verwendet wird.Wenn Sie also eine Funktion mit einem Array-Ausdruck als Argument aufrufen, erhält die Funktion einen Zeiger und kein Array:
Dies ist , warum Sie nicht die Verwendung
&
auf „% s“ entsprechenden Operator für Argumentescanf()
:scanf()
Empfängt aufgrund der impliziten Konvertierung einenchar *
Wert, der auf den Anfang desstr
Arrays zeigt. Dies gilt für jede Funktion mit einem Array Ausdruck als Argument (nur über eine der genanntenstr*
Funktionen*scanf
und*printf
Funktionen, etc.).In der Praxis werden Sie wahrscheinlich niemals eine Funktion mit einem Array-Ausdruck mit dem
&
Operator aufrufen , wie in:Ein solcher Code ist nicht sehr verbreitet; Sie müssen die Größe des Arrays in der Funktionsdeklaration kennen, und die Funktion funktioniert nur mit Zeigern auf Arrays bestimmter Größe (ein Zeiger auf ein Array mit 10 Elementen von T ist ein anderer Typ als ein Zeiger auf ein Array mit 11 Elementen von T).
Wenn ein Array-Ausdruck als Operand für den
&
Operator angezeigt wird , ist der Typ des resultierenden Ausdrucks "Zeiger auf N-Element-Array von T" oderT (*)[N]
unterscheidet sich von einem Array von Zeigern (T *[N]
) und einem Zeiger auf den Basistyp ().T *
).Beim Umgang mit Funktionen und Zeigern gilt folgende Regel: Wenn Sie den Wert eines Arguments ändern und im aufrufenden Code wiedergeben möchten, müssen Sie einen Zeiger auf das Element übergeben, das Sie ändern möchten. Wieder werfen Arrays einen kleinen Schraubenschlüssel in die Werke, aber wir werden uns zuerst mit den normalen Fällen befassen.
Denken Sie daran, dass C alle Funktionsargumente als Wert übergibt . Der formale Parameter erhält eine Kopie des Werts im tatsächlichen Parameter, und Änderungen am formalen Parameter werden nicht im tatsächlichen Parameter berücksichtigt. Das häufigste Beispiel ist eine Swap-Funktion:
Sie erhalten folgende Ausgabe:
Die formalen Parameter
x
undy
sind verschiedene Objekte vona
undb
, daher ändern sich Änderungen anx
undy
werden nicht ina
und wiedergegebenb
. Da wir die Werte vona
und ändern möchtenb
, müssen wir Zeiger darauf an die Swap-Funktion übergeben:Jetzt wird Ihre Ausgabe sein
Beachten Sie, dass wir in der Swap-Funktion nicht die Werte von
x
und änderny
, sondern die Werte von whatx
undy
zeigen auf . Schreiben an*x
unterscheidet sich vom Schreiben anx
; Wir aktualisieren den Wert nicht anx
sich, wir erhalten einen Speicherort vonx
und aktualisieren den Wert an diesem Speicherort.Dies gilt auch, wenn wir einen Zeigerwert ändern möchten. wenn wir schreiben
dann ändern wir den Wert des Eingabeparameters
stream
, nicht wasstream
ändern zeigt. Eine Änderungstream
hat also keine Auswirkung auf den Wert vonin
. Damit dies funktioniert, müssen wir einen Zeiger auf den Zeiger übergeben:Auch hier werfen Arrays einen kleinen Schraubenschlüssel in die Werke. Wenn Sie einen Array-Ausdruck an eine Funktion übergeben, empfängt die Funktion einen Zeiger. Aufgrund der Definition der Array-Subskription können Sie einen Indexoperator für einen Zeiger genauso verwenden wie für ein Array:
Beachten Sie, dass Array-Objekte möglicherweise nicht zugewiesen werden. dh du kannst so etwas nicht machen
Sie sollten also vorsichtig sein, wenn Sie mit Zeigern auf Arrays arbeiten. etwas wie
wird nicht funktionieren.
quelle
Einfach ausgedrückt
&
bedeutet die Adresse von , Sie werden sehen, dass in Platzhaltern für Funktionen zum Ändern der Parametervariablen wie in C Parametervariablen als Wert übergeben werden, wobei das kaufmännische Und als Referenz verwendet wird.*
bedeutet die Dereferenzierung einer Zeigervariable, was bedeutet, den Wert dieser Zeigervariable zu erhalten.Das obige Beispiel zeigt, wie eine Funktion
foo
mithilfe der Referenzübergabe aufgerufen wird. Vergleichen Sie diesHier ist ein Beispiel für die Verwendung einer Dereferenzierung
Das Obige zeigt, wie wir die Adresse von erhalten
y
und sie der Zeigervariablen zugewiesen habenp
. Dann dereferenzieren wir,p
indem wir das*
an der Vorderseite anbringen , um den Wert von zu erhaltenp
, dh*p
.quelle
Ja, das kann ziemlich kompliziert sein, da das
*
in C / C ++ für viele verschiedene Zwecke verwendet wird.Wenn
*
vor einer bereits deklarierten Variablen / Funktion angezeigt wird, bedeutet dies entweder:*
gibt Zugriff auf den Wert dieser Variablen (wenn der Typ dieser Variablen ein Zeigertyp ist oder der*
Operator überladen ist ).*
hat die Bedeutung des Multiplikationsoperators, in diesem Fall muss links von der eine andere Variable stehen*
Wenn es
*
in einer Variablen- oder Funktionsdeklaration erscheint, bedeutet dies, dass diese Variable ein Zeiger ist:Wenn es
&
in einer Variablen- oder Funktionsdeklaration erscheint, bedeutet dies im Allgemeinen, dass diese Variable eine Referenz auf eine Variable dieses Typs ist.Wenn
&
vor einer bereits deklarierten Variablen angezeigt wird, wird die Adresse dieser Variablen zurückgegebenAußerdem sollten Sie wissen, dass Sie beim Übergeben eines Arrays an eine Funktion immer auch die Arraygröße dieses Arrays übergeben müssen, es sei denn, das Array ist so etwas wie eine 0-terminierte Zeichenfolge (char-Array).
quelle
Wenn Sie eine Zeigervariable oder einen Funktionsparameter deklarieren, verwenden Sie das *:
NB: Jede deklarierte Variable benötigt ihre eigene *.
Wenn Sie die Adresse eines Werts übernehmen möchten, verwenden Sie &. Wenn Sie den Wert in einem Zeiger lesen oder schreiben möchten, verwenden Sie *.
Arrays werden normalerweise nur wie Zeiger behandelt. Wenn Sie einen Array-Parameter in einer Funktion deklarieren, können Sie genauso einfach deklarieren, dass es sich um einen Zeiger handelt (dies bedeutet dasselbe). Wenn Sie ein Array an eine Funktion übergeben, übergeben Sie tatsächlich einen Zeiger auf das erste Element.
Funktionszeiger sind die einzigen Dinge, die den Regeln nicht ganz folgen. Sie können die Adresse einer Funktion ohne Verwendung von & übernehmen und einen Funktionszeiger ohne Verwendung von * aufrufen.
quelle
Ich war alle durch die wortreichen Erklärungen suchen , so stattdessen auf ein Video von der University of New South Wales für rescue.Here gedreht ist die einfache Erklärung: Wenn wir eine Zelle , die Adresse hat
x
und Wert7
, die indirekte Art und Weise für die Adresse des Wertes zu stellen7
ist&7
und die indirekte Art und Weise für Wert bei der Adresse zu fragenx
ist*x
.So(cell: x , value: 7) == (cell: &7 , value: *x)
.another Art und Weise, diese zu prüfen:John
sitzt auf7th seat
.Der*7th seat
wird PunktJohn
und&John
gebenaddress
/ Position der7th seat
. Diese einfache Erklärung hat mir geholfen und hoffe, dass sie auch anderen hilft. Hier ist der Link für das hervorragende Video: Klicken Sie hier.Hier ist ein weiteres Beispiel:
Add-on: Initialisieren Sie den Zeiger immer, bevor Sie ihn verwenden. Wenn nicht, zeigt der Zeiger auf etwas, was zum Absturz des Programms führen kann, da das Betriebssystem Sie daran hindert, auf den Speicher zuzugreifen, von dem Sie wissen, dass Sie ihn nicht besitzen
p = &x;
Wir weisen dem Zeiger eine bestimmte Position zu.quelle
Eigentlich hast du es geschafft, es gibt nichts mehr, was du wissen musst :-)
Ich würde nur die folgenden Bits hinzufügen:
&
nimmt eine Variable und gibt Ihnen die Adresse,*
nimmt eine Adresse und gibt Ihnen die Variable (oder den Inhalt).char **p
bedeutet, dass diesp
ein Zeiger auf einen Zeiger auf a istchar
.Was die Dinge betrifft, die anders funktionieren, nicht wirklich:
\0
) abgeschlossen ist.quelle
Ich denke du bist ein bisschen verwirrt. Sie sollten ein gutes Tutorial / Buch über Zeiger lesen.
Dieses Tutorial ist sehr gut für den Anfang (erklärt klar, was
&
und*
sind). Und ja, vergessen Sie nicht, das Buch Pointers in C von Kenneth Reek zu lesen .Der Unterschied zwischen
&
und*
ist sehr klar.Beispiel:
quelle
Ok, es sieht so aus, als ob dein Beitrag bearbeitet wurde ...
Sehen Sie, wie Sie die verwenden können
&
, um die Adresse des Anfangs der Array-Struktur zu erhalten? Folgendewerde das gleiche tun.
quelle