Frage zu Zeigern

Gast #2642068
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
#2642122
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.
Gast #2642158
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
#2642299
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.
Gast #2642898
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
#2643014
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.
Gast #2643036
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 
?
#2643047
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.
Persönliche Seite #2643175
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren