Adreßtypen in C
Der Typ eines &-Ausdrucks
Falls der Ausdruck »W « den Typ »T« hat, so hat »&W « einen Typ, der »T *« genannt wird. »T *« ist also der Typ, den die Adresse eines T -Objekts hat. Solch einen Typ einer Adresse nennen wir auch einen Adreßtyp.
Der Typ eines *-Ausdrucks
Falls der Ausdruck »W « den Typ »T *« hat, so hat »*W « den Typ »T «. Da »T *« ja der Typ ist, den die Adresse eines T -Objekts hat, ist der Typ des adressierten Objekts selber wieder »T «.
Deklaration von Variablen mit Adreßtypen
Eine Variablenname wird in der Deklaration einer Variablen auch als ein „Deklarator “ bezeichnet.
Beispielsweise ist »w« int »int w;« ein Deklarator.
An Stelle eines Deklarators »W « kann auch »( *W )« als Deklarator verwendet werden. Wenn »W « vor der Ersetzung den Typ »T « hatte, so hat es danach den Typ »T *«.
Ist beispielsweise »int w;« die Deklaration einer Variablen »w«, so erhält man durch Ersetzung von »w« durch »( *w )« die neue Deklaration »int ( *w );«. Diese deklariert »w« nun so, daß es den Typ »int *« hat. Dies ist der Typ eines Objekts, das die Adresse eines int-Objekts aufnehmen kann.
In dem folgenden Programm wird auf diese Weise eine Variablen »w« so deklariert, daß ihr Typ der Typ von »&v« ist.
Diese Variable »w« wird dann mit der Adresse der Variablen »v« initialisiert. Danach kann dann später mit »( *w )« wieder das Objekt zu der Adresse »w« erhalten werden. »( *w )« bedeutet in dem Programm also soviel wie »v«. In dem Programm wird der Wert dieses Objekt dann beispielsweise zur Initialisierung der Variablen »u« verwendet.
main.c
#include <stdio.h>
int main( void )
{ int v = 31;
int ( *w ) = &v;
int u =( *w );
printf( "%d", u ); }stdout
31
Die Bedeutung von »int( *w );« ergibt sich einfach daraus, daß der Ausdruck »( *w )« den Typ »int« haben soll, also: »int ( *w );«.
Wenn die Klammern nicht nötig sind, um zu verdeutlichen, daß »*w« eine Einheit bilden soll, können sie entfallen. Dies ist beispielsweise in dem folgenden Fall möglich, wo »*p« verwendet wird, Dort ist es nicht nötig, »( *p )« zu verwenden.
main.c
#include <stdio.h>
int main( void )
{ int i = 2;
int *p;
p = &i;
printf( "%d", *p ); }Protokoll
2
Man kann hier »int *p« also so lesen, daß »*p« den Typ »int« hat oder so daß »p« den Typ »int *« hat.
Nach »p = &i« kann »*p« wie »i« verwendet werden.
Der Typ einer Adresse wird auch ein Adreßtyp (address type) genannt.
Mehrere 〈init-declarator 〉s in einer Deklaration
Das folgende Programm zeigt eine Folge mehrerer kommagetrennter 〈init-declarator 〉s (also so viel wie Deklaratoren) hinter den 〈declaration-specifiers 〉.
In der Deklaration in »int* p, i;« werden die 〈declaration-specifiers 〉 nur von dem Worte »int« gebildet.
Der erste 〈init-declarator 〉 in »int* p, i;« ist »* p«, der zweite ist »i«. Jeder 〈init-declarator 〉 wird nun mit dem am Anfang stehenden 〈declaration-specifiers 〉 deklariert.
»p« wird in »int* p, i;« daher als »int*« deklariert.
»i« wird in »int* p, i;« daher als »int« deklariert (und nicht etwa als »int *«).
- 〈declaration-specifiers 〉 und 〈init-declarator 〉s in »int* p, i;«
declaration-specifiers int
/ \
/ \
/ \
/ \
init-declarator * p imain.c
#include <stdio.h>
int main( void )
{ int* p, i;
i = 27;
p = &i;
printf( "%d\n", *p ); }stdout
27
Die beiden Deklarationen in dem folgenden Programm haben dieselbe Bedeutung wie die Deklaration in dem voranstehenden Programm.
main.c
#include <stdio.h>
int main( void )
{ int* p;
int i;
i = 27;
p = &i;
printf( "%d\n", *p ); }stdout
27
Das folgende Beispiel zeigt, wie die Zuweisungen durch Initialisierungen ersetzt werden können. (Ein 〈init-declarator 〉 darf auch noch eine Initialisierung enthalten.)
main.c
#include <stdio.h>
int main( void )
{ int i = 27, *p = &i;
printf( "%d\n", *p ); }stdout
27
Skalare Typen
(Wir hatte schon gelernt, daß Adressen Skalare sind.)
Die arithmetischen Typen (wie »int« und »double«) werden mit den Adreßtypen (wie »int *«) zusammen als skalare Typen bezeichnet.
- N1570
- Arithmetic types and pointer types are collectively called scalar types.
Vergleich von Adressen
Adressen von Objekten desselben Typs können verglichen werden.
main.c
#include <stdio.h>
int main( void )
{ int i;
int k;
printf( "%d\n", &i == &i );
printf( "%d\n", &i == &k );
printf( "%d\n", &k == &k ); }stdout
1
0
1
Übungsfragen
? Übungsfrage
Ist das folgende Programm korrekt?
main.c
#include <stdio.h>
int main( void )
{ int i = 2;
int *p = &i;
*p = &i;
printf( "%d\n", *p ); }