Forum: PC-Programmierung Frage zu Zeigern


von Joachim (Gast)


Lesenswert?

Hallo,

kann mir jemand den Unterschied zwischen folgenden beiden 
Zeiger-Zuweisungen erklären?

1
int b = 1;
2
int  *t  = &b; 
3
int *tt = t;

1
int b = 1;
2
int  *t  = &b; 
3
int **tt = &t;


Das zweite Beispiel ist mir unklar. Was bedeutet der Doppelstern?

Vielen Dank für Eure Hilfe.

MFG, Joachim

von Metaspast (Gast)


Lesenswert?

1) t zeigt auf b.
   tt zeigt auf b.

2) t zeigt auf b.
   tt zeigt auf t, der auf b zeigt.

von Chris S. (hondaracer1)


Lesenswert?

der doppelstern erzeugt dir einen zeiger der auf einen zeiger zeigt. Und 
geil anhören tut sich das doch schonmal =D

einen zeiger kannst du mit einem array vergleichen
also:
int *t = 3; entspricht prinzipiell  int t[1] = {3};
einen zeiger auf einen zeiger kannst du auch mit einem 2 dimensionalen 
array vergleichen, also:
int **t = 3; entspricht prinzipiell  int t[1][1] = {3};
einzigster unterschied, beim array meckert der compiler wenn du das 10te 
element aus einem 9 Felder großen array abfragst.

von Joachim (Gast)


Lesenswert?

>   tt zeigt auf t, der auf b zeigt.

Wieso kann ich dann nicht folgendes schreiben:
1
int b = 1;
2
int  *t  = &b; 
3
int *tt = &t;

?

von Andreas B. (andreas_b77)


Lesenswert?

Joachim schrieb:
> Wieso kann ich dann nicht folgendes schreiben:
>
>
1
> int b = 1;
2
> int  *t  = &b;
3
> int *tt = &t;
4
>

tt soll ein Zeiger auf ein int sein, du initialisierst den aber mit 
der Adresse von einem Zeiger auf ein int. Das passt nicht.

von Joachim (Gast)


Lesenswert?

>tt soll ein Zeiger auf ein int sein, du initialisierst den aber mit
>der Adresse von einem Zeiger auf ein int. Das passt nicht.

Ich befürchte, dass ich das noch nicht ganz verstanden habe. Kann mir 
jemand eine Skizze liefern, aus der der Unterschied deutlich wird?

Vielen Dank, Joachim

von Metaspast (Gast)


Lesenswert?

Das sind übelste Grundlagen.
Gibt es tausend Bücher drüber. Thema: Zeiger in C.

WIESO MUSS MAN SO ETWAS IN EINEM FORUM ERFRAGEN???

von Gert (Gast)


Lesenswert?

Grundlagen Videos zu Pointern in C:
http://et-tutorials.de/mikrocontroller/
Videos 36ff

von Karl H. (kbuchegg)


Lesenswert?

Chris S. schrieb:

> einen zeiger kannst du mit einem array vergleichen

Nein.

> also:
> int *t = 3; entspricht prinzipiell  int t[1] = {3};

Nein

> einen zeiger auf einen zeiger kannst du auch mit einem 2 dimensionalen
> array vergleichen, also:
> int **t = 3; entspricht prinzipiell  int t[1][1] = {3};
Nein

von Karl H. (kbuchegg)


Lesenswert?

Joachim schrieb:

> Ich befürchte, dass ich das noch nicht ganz verstanden habe. Kann mir
> jemand eine Skizze liefern, aus der der Unterschied deutlich wird?

Fall 1

int b = 1;

                                             b
                                             +-----+
                                             |  1  |
                                             +-----+

int  *t  = &b;
in t wird die Adresse von b gespeichert
                   t                         b
                  +--------+                 +-----+
                  |   o--------------------->|  1  |
                  +--------+                 +-----+

int *tt = t;
in tt wird derselbe Wert gespeichert, der auch in t steht. tt ist eine 
Kopie von t. tt zeigt daher auf Dasselbe, auf das auch t zeigt
                   t                         b
                  +--------+                 +-----+
                  |   o--------------------->|  1  |
                  +--------+            +--->+-----+
                                        |
                                        |
                   tt                   |
                  +--------+            |
                  |   o-----------------+
                  +--------+

um an den Integer zu kommen, musst du von t ausgehend 1 Pfeil verfolgen. 
Daher auch nur 1 Stern.

Fall 2

int b = 1;

                                             b
                                             +-----+
                                             |  1  |
                                             +-----+

int  *t  = &b;
in t wird die Adresse von b gespeichert
                   t                         b
                  +--------+                 +-----+
                  |   o--------------------->|  1  |
                  +--------+                 +-----+

int **tt = &t;
in tt wird die Adresse von t abgelegt. tt zeigt also auf t

                   t                         b
                  +--------+                 +-----+
                  |   o--------------------->|  1  |
                  +--------+                 +-----+
                      ^
                      |
                  tt  |
                  +---|----+
                  |   o    |
                  +--------+

um an den Integer zu kommen, musst du von tt ausgehend 2 Pfeile 
verfolgen. Der erste bringt dich von tt nach t, der zweite von t dann 
zum Integer. 2 Pfeile, daher auch 2 Sterne. Jeder Stern symbolisiert 
einen Pfeil aus der Skizze. So viele Pfeile, wie du verfolgen musst, bis 
du dann schlussendlich irgendwann beim tatsächlchen Wert-Objekt 
angelangt bist (in diesem konkreten Fall eben dem Integer), so viele * 
brauchst du auch.

von Joachim (Gast)


Lesenswert?

Hallo Karl,

jetzt habe ich es verstanden. Deine Erklärung ist sehr gut, vielen Dank 
hierfür.


>WIESO MUSS MAN SO ETWAS IN EINEM FORUM ERFRAGEN???

Wieso nicht? Anscheinend können andere Wissende auch noch etwas dabei 
lernen.



MFG, Joachim

von Chris S. (hondaracer1)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Chris S. schrieb:
>
>> einen zeiger kannst du mit einem array vergleichen
>
> Nein.
>
>> also:
>> int *t = 3; entspricht prinzipiell  int t[1] = {3};
>
> Nein
>
>> einen zeiger auf einen zeiger kannst du auch mit einem 2 dimensionalen
>> array vergleichen, also:
>> int **t = 3; entspricht prinzipiell  int t[1][1] = {3};
> Nein

sehr schön, wieder jeder mit halbwissen (oder weniger) der einfach nur 
nein schreiben kann ohne sinnvolle Argumentation, weil er nix weiß 
ausser wie man nein schreibt.

von NurEinGast (Gast)


Lesenswert?

@Chris S.

7 Minuten später hat "derjenige mit halbwissen (oder weniger)" eine 
perfekte Erlärung abgegeben. Besser gehts doch gar nicht.

Du hast offensichtlich sein nächstes Posting einfache ignorieren wollen 
?

von NurEinGast (Gast)


Lesenswert?

Sorry - Erklärung nicht Erlärung

von Udo S. (urschmitt)


Lesenswert?

Chris S. schrieb:
> sehr schön, wieder jeder mit halbwissen (oder weniger) der einfach nur
> nein schreiben kann ohne sinnvolle Argumentation, weil er nix weiß
> ausser wie man nein schreibt.

Junge Junge, bevor man hier jemanden anmacht der dir die C Standards 
fast auswendig herunterbeten kann und schon hunderten Fragenden 
kompetent und ausführlich geholfen hat, sollte man sein eigenes 1/100 
stel Wissen erst mal überprüfen bevor man sich auf so dünnes Eis begibt.
Auch wenn Zeiger und Arrayschreibweise äquivalent sind ist ein Zeiger 
nicht gleich ein Array!
Du solltest selbst noch mal etwas mehr ins C Buch schauen und eine 
Entschuldigung wäre angebracht, sowohl gegenüber dem TO den du mit 
deinen Aussagen verwirrt hast als auch gegenüber Karl Heinz.

von Klaus W. (mfgkw)


Lesenswert?

Chris S. schrieb:
> sehr schön, wieder jeder mit halbwissen (oder weniger) der einfach nur
> nein schreiben kann ohne sinnvolle Argumentation, weil er nix weiß
> ausser wie man nein schreibt.

wo war nochmal die bessere Erklärung von dir?

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Chris S. schrieb:
> Karl Heinz Buchegger schrieb:
>> Chris S. schrieb:
>>
>>> int *t = 3; entspricht prinzipiell  int t[1] = {3};
>>
>> Nein
>
> sehr schön, wieder jeder mit halbwissen (oder weniger) der einfach nur
> nein schreiben kann ohne sinnvolle Argumentation, weil er nix weiß
> ausser wie man nein schreibt.

*räusper* Das hab ich jetzt überlesen.

Das erste ist offenbar ein Zeigen, das zweite ein Array.
Versuch einfach mal im nachfolgenden Code ein t = 0;
Der Zeigervariablen kann man es zuweisen, dem Array, das lediglich ein 
Symbol repräsentiert, natürlich nicht.

Auch der Zugriff siegt anders aus, hier explizit gemacht mit avr-gcc:
1
extern int *t;
2
3
int* read_t (void)
4
{
5
    return t;
6
}

wird zu
1
read_t:
2
  lds r24,t
3
  lds r25,t+1
4
  ret

Und das zweite Codeschnippel
1
extern int t[];
2
3
int* read_t (void)
4
{
5
    return t;
6
}

wird hingenen übersetzt zu
1
read_t:
2
  ldi r24,lo8(t)
3
  ldi r25,hi8(t)
4
  ret
Von Adresse t zu lesen wäre im zweiten Fall offenbar falsch, denn dann 
würde t[0] gelesen und als int* interpretiert werden.

Der Wert von t ist also zur Laufzeit bekannt und unveränderlich; das ist 
im ersten Fall komplett anders.

Logischerweise erfolgt auch ein Zugriff wie *t anders:
1
  lds r30,t
2
  lds r31,t+1
3
  ld r24,Z
4
  ldd r25,Z+1

und im t[] Fall
1
  lds r24,t
2
  lds r25,t+1
Im ersten Fall ist eine Indirektion notwendig, im zweiten nicht und wäre 
wie gesagt falsch.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.