Was ist der Unterschied zwischen scanf ("% d", * p) und scanf ("% d", p)?

7

Zeiger sind eine neue Sache für mich und ich bemühe mich, sie zu verstehen, aber ich werde nicht nachgeben und hoffentlich lernen.

Was wäre der Unterschied zwischen scanf ("%d", *p) und scanf ("%d", p) ?

In Beispielen habe ich gesehen, dass ich, wenn ich einen Wert in eine Variable eingeben möchte, scanf ("%d", p) verwenden soll. Das ergibt für mich keinen Sinn. Sollte es nicht scanf ("%d", *p) sein?

Ich interpretiere es als: "setze einen ganzzahligen Wert, auf den der Zeiger zeigt" und zum Beispiel zeigt es auf die Variable x und dann sollte es x = 10 sein, aber es ist nicht. Und wie dann scanf() und Zeiger verwenden, um Werte in einem Array zu setzen?

Wo und was mache ich falsch? Ich versuche das mit der Sprache C zu lernen, da es die ist, die ich in meiner Klasse verwenden soll.

Zum Beispiel:

%Vor%

Warum ist% p + i in der ersten for () {} und *(p + i) in der zweiten Schleife? Ich würde *(p + i) auch in die erste for () {} setzen. *(p + i) für mich ist wie: "was das (p + i) te Element ist und mache es gleich einem Wert".

    
Nick 15.04.2014, 22:00
quelle

4 Antworten

18

*p bedeutet, gehen Sie zum Ort p Punkte zu
&p bedeutet, nehmen Sie die Adresse von p , oder "erhalten Sie einen Zeiger auf" p

%Vor%

Die obligatorische visuelle Erklärung ist Pointer Fun mit Binky .

Sie können die Typen von rechts nach links lesen:

int *p = & gt; " p hat den Typ int * " = & gt; p ist ein Zeiger auf ein int
int *p = & gt; " *p hat den Typ int " = & gt; *p ist die int , auf die p

zeigt     
Ryan Haining 15.04.2014, 22:02
quelle
12

Eins hat recht, das andere ist falsch. (Oder beides kann falsch sein, abhängig davon, was p ist.)

Wenn Sie

anrufen %Vor%

then SOMETHING muss ein Zeiger auf ein int sein.

Wenn Sie ein int -Objekt haben, verwenden Sie unary & , um seine Adresse zu erhalten (d. h. einen Zeiger auf das Objekt):

%Vor%

Wenn p zufällig ein int* ist, dann können Sie ihren Wert verwenden:

%Vor%

Aber hier habe ich p keinen Wert zugewiesen, also kompiliert, hat aber undefiniertes Verhalten. Das ist in Ordnung:

%Vor%

Wie bei *p wäre das nur dann gültig, wenn p ein Zeiger auf einen Zeiger auf ein int ist:

%Vor%

Aber es würde selten Sinn machen, das zu tun. In den meisten Fällen wird das Argument einfach die Adresse einiger int -Objekte sein, wie &n .

Wenn n ein int ist, dann würde die Übergabe von n an scanf nicht sinnvoll sein. Sie würden lediglich den aktuellen Wert von n übergeben. Der Punkt ist, dass Sie scanf erlauben möchten, einen neuen Wert in n zu speichern, und dafür muss scanf die Adresse von n .

    
Keith Thompson 15.04.2014 22:05
quelle
2

Funktionsaufrufe in C übergeben Argumente nach Wert, nicht nach Referenz. Wenn Sie also eine Funktion mit Argumenten aufrufen, empfängt die Funktion Kopien der Argumente, und diese Funktion kann die ursprünglichen Argumente der Callsite nicht direkt ändern. Das ist:

%Vor%

foo kann die Variable x nicht ändern, und der Code wird immer 42 ausgeben.

Es gibt jedoch viele Fälle, in denen eine Funktion die Argumente des Aufrufers ändern möchte. scanf ist ein solcher Fall. Um dies zu erreichen, müssen diese Funktionen eine Ebene der Indirektion verwenden. Anstatt die zu ändernde Variable direkt an die Funktion zu übergeben, übergibt der Aufrufer stattdessen einen Zeiger an diese Variable. Die Funktion empfängt dann eine Kopie des Zeigers und kann durch Dereferenzierung auf die Variable zugreifen und diese ändern, auf die sie zeigt.

Ich empfehle, etwas Zeit mit dem Lesen der comp.lang.c FAQ zu verbringen. Dieses Thema wird in folgendem Thema behandelt:

jamesdlin 16.04.2014 03:12
quelle
1

Wenn p die Variable ist (zB ein int), verwenden Sie & amp; p , um den Zeiger an scanf zu übergeben. p allein ist kein Zeiger und * p verbindet das Problem.

    
Phil Perry 15.04.2014 22:03
quelle

Tags und Links