Frage zu Zeigern

Gast #2642068
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
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
>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
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
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
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
@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
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
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

Eine eigene Frage? Dieser Thread ist über 14 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.