403 Stimmen

Zeiger in C: Wann werden das kaufmännische Und und das Sternchen verwendet?

Ich fange gerade erst an, mit Zeigern zu arbeiten, und bin etwas verwirrt. Ich weiß & die Adresse einer Variablen bedeutet und dass * kann vor einer Zeigervariablen verwendet werden, um den Wert des Objekts zu erhalten, auf das der Zeiger zeigt. Anders sieht es aus, wenn Sie mit Arrays oder Strings arbeiten oder wenn Sie Funktionen mit einer Zeigerkopie einer Variablen aufrufen. Es ist schwierig, in all dem ein logisches Muster zu erkennen.

Wann sollte ich die & y * ?

7voto

paxdiablo Punkte 809679

Eigentlich haben Sie es im Griff, mehr brauchen Sie nicht zu wissen :-)

Ich würde nur die folgenden Punkte hinzufügen:

  • Die beiden Vorgänge liegen am entgegengesetzten Ende des Spektrums. & nimmt eine Variable und gibt Ihnen die Adresse, * nimmt eine Adresse und gibt Ihnen die Variable (oder den Inhalt).
  • Arrays werden zu Zeigern "degradiert", wenn Sie sie an Funktionen übergeben.
  • können Sie tatsächlich mehrere Ebenen der Umleitung haben ( char **p bedeutet, dass p ist ein Zeiger auf einen Zeiger auf eine char .

Dass die Dinge anders laufen, nicht wirklich:

  • Arrays werden, wie bereits erwähnt, zu Zeigern (auf das erste Element im Array) degradiert, wenn sie an Funktionen übergeben werden; sie behalten keine Größeninformationen.
  • In C gibt es keine Zeichenketten, sondern nur Zeichenarrays, die gemäß der Konvention eine Zeichenkette darstellen, die mit einer Null abgeschlossen wird ( \0 ) Zeichen.
  • Wenn Sie die Adresse einer Variablen an eine Funktion übergeben, können Sie den Zeiger de-referenzieren, um die Variable selbst zu ändern (normalerweise werden Variablen als Wert übergeben (außer bei Arrays)).

6voto

Prasoon Saurav Punkte 88056

Ich glaube, Sie sind ein wenig verwirrt. Sie sollten ein gutes Tutorial/Buch über Zeiger lesen.

Diese Tutorial ist sehr gut für den Anfang (erklärt deutlich, was & y * sind). Und ja, vergessen Sie nicht, das Buch zu lesen Zeiger in C von Kenneth Reek.

Der Unterschied zwischen & y * ist sehr klar.

Beispiel:

#include <stdio.h>

int main(){
  int x, *p;

  p = &x;         /* initialise pointer(take the address of x) */
  *p = 0;         /* set x to zero */
  printf("x is %d\n", x);
  printf("*p is %d\n", *p);

  *p += 1;        /* increment what p points to i.e x */
  printf("x is %d\n", x);

  (*p)++;         /* increment what p points to i.e x */
  printf("x is %d\n", x);

  return 0;
}

4voto

Jay Conrod Punkte 27696

Wenn Sie eine Zeigervariable oder einen Funktionsparameter deklarieren, verwenden Sie das *:

int *x = NULL;
int *y = malloc(sizeof(int)), *z = NULL;
int* f(int *x) {
    ...
}

NB: Jede deklarierte Variable benötigt einen eigenen *.

Wenn Sie die Adresse eines Wertes übernehmen wollen, verwenden Sie &. Wenn Sie den Wert in einem Zeiger lesen oder schreiben wollen, verwenden Sie *.

int a;
int *b;
b = f(&a);
a = *b;

a = *f(&a);

Arrays werden in der Regel einfach wie Zeiger behandelt. Wenn Sie einen Array-Parameter in einer Funktion deklarieren, können Sie ihn genauso gut als Zeiger deklarieren (es bedeutet dasselbe). Wenn Sie ein Array an eine Funktion übergeben, übergeben Sie eigentlich einen Zeiger auf das erste Element.

Funktionszeiger sind die einzigen Dinge, die sich nicht ganz an die Regeln halten. Sie können die Adresse einer Funktion übernehmen, ohne & zu verwenden, und Sie können einen Funktionszeiger aufrufen, ohne * zu verwenden.

1voto

wheaties Punkte 34965

Ok, sieht so aus, als wäre dein Beitrag bearbeitet worden...

double foo[4];
double *bar_1 = &foo[0];

Sehen Sie, wie Sie die & um die Adresse des Beginns der Array-Struktur zu erhalten? Das Folgende

Foo_1(double *bar, int size){ return bar[size-1]; }
Foo_2(double bar[], int size){ return bar[size-1]; }

wird das Gleiche tun.

1voto

piertoni Punkte 1827

Das Verständnis von Zeigern ist anfangs kompliziert, man muss Übungen machen und viel üben. Erwarten Sie nicht, dass Sie es bei der ersten Wiederholung verstehen oder dass Sie eine Erklärung lesen und denken, dass Sie es verstanden haben, denn sehr wahrscheinlich haben Sie es nicht...

Wenn Sie mehr als nur ein theoretisches Verständnis haben wollen, empfehle ich Ihnen Folgendes Kurs von Stanford CS107 zu besuchen und die vorgegebenen Übungen zu machen, zumindest die ersten drei Lektionen, in denen Zeiger erklärt werden.

Stanford CS107 von Jerry Cain

Ein weiteres sehr wertvolles Instrument ist gdb wo Sie ein interaktives Shell, wie Sie sie zum Beispiel in Python haben. Mit gdb können Sie spielen und experimentieren:

 (gdb) x pp.name
0x555555555060 <_start>:        0x8949ed31
(gdb) x &pp.name
0x7fffffffdc38: 0x55555060
(gdb) p &pp.name
$4 = (char **) 0x7fffffffdc38
(gdb) p *pp.name
$5 = 49 '1'

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X