Leseadressen in C (Leseadressen in C), Lektion, Seite 723258
https://www.purl.org/stefan_ram/pub/lesezeiger_c (Permalink) ist die kanonische URI dieser Seite.
Stefan Ram
C-Kurs

Leseadressen in C 

»int const *« — Leseaddresse

In einer Spezifizierer-Qualifizierer-Auflistung können Typspezifizierer (wie »int«) und Typqualifizierer (wie »const«) in beliebiger Reihenfolge direkt hintereinander aufgelistet werden. Die Reihenfolge hat keine Bedeutung. Die in der Deklaration verwendete Spezifizierer-Qualifizierer-Auflistung »int const« bedeutet dasselbe wie die Spezifizierer-Qualifizierer-Auflistung »const int«. Zur Vereinfachung beschränken wir uns ab hier auf eine Schreibweise, nämlich die mit dem nachgestellten »const«, also »int const«.

type-specifier:

char

int

double

type-qualifier:
const
specifier-qualifier-list:

type-specifier specifier-qualifier-list/opt

type-qualifier specifier-qualifier-list/opt

Wenn T ein Typ ist (»int«, »char« oder »double«), dann nennen wir den Typ »T const *« einen Lesetyp.

Eine Adresse, deren Typ ein Lesetyp ist, nennen wir eine Leseadresse.

Ein Objekt, dessen Typ ein Lesetyp ist, nennen wir eine Leseobjekt. Ein Leseobjekt enthält eine Leseadresse.

Eine Leseadresse kann nur verwendet werden, um aus dem Referenten zu lesen (sie kann nicht verwendet werden, um etwas in den Referenten zu schreiben).

Das folgende Programmbeispiel zeigt einen Lesezeiger »r« und eine Adresse »w«. Der Lesezeiger erlaubt es, das Objekt »i« durch Auswertung des Ausdrucks »*r« zu lesen, aber nur die Adresse »w« erlaubt es, mit »*w =« in das Objekt »i« zu schreiben. Würde versucht werden, mit »*r =« zu schreiben, so gäbe es eine Fehlermeldung.

main.c

#include <stdio.h>

int main( void )
{ int i = 27;
int const * r = &i;
int * w = &i;
printf( "%d\n", *r );
*w = 40;
printf( "%d\n", *r ); }

stdout
27
40

Der Lesezeiger kann  geändert werden. Im folgenden Beispiel enthält »p« zuerst die Adresse von »i« und später die Adresse von »k«. Ein Lesezeiger ist also selber nicht notwendigerweise ein konstanter Zeiger.

main.c

#include <stdio.h>

int main( void )
{ int i = 27;
int k = 40;
int const * p = &i;
printf( "%d\n", *p );
p = &k;
printf( "%d\n", *p ); }

stdout
27
40

Die Existenz einer Leseadresse auf ein Objekt bedeutet nicht  unbedingt, daß dieses Objekt konstant ist. Es kann durchaus möglich sein, daß das Objekt direkt oder über eine andere Adresse geändert werden kann.

Das folgende Programm zeigt, wie das Objekt »i« sowohl über »i =« als auch über »*q =« geändert werden kann, es kann nur nicht über »*p =« geändert werden.

main.c

#include <stdio.h>

int main( void )
{ int i = 27;
int const * p = &i;
int * q = &i;
printf( "%d\n", *p );
i = 40;
printf( "%d\n", *p );
*q = 60;
printf( "%d\n", *p ); }

stdout
27
40
60

Wurde ein Objekt als konstant gekennzeichnet, so sind nur Leseaddressen dieses Objekts erlaubt!

main.c

#include <stdio.h>

int main( void )
{ int const i = 27;
int const * p = &i;
printf( "%d\n", *p );
/* int * q = &i;
error: initialization discards 'const' qualifier from pointer target type */ }

stdout
27

Das voranstehende Programmbeispiel zeigt auch noch einmal, daß eine „Konstante“ (also hier »i«) in C  kein richtiger Name für einen Wert ist (das wäre hier der Wert 27), sondern doch erst einmal ein Name für ein Objekt. Dieses Objekt enthält dann der Wert der Konstanten. Wenn dies nicht so wäre, dann könnte man nämlich nicht die Adresse einer Konstanten (also hier »&i«) angeben.

(Die oben gezeigte Fehlermeldung könnte unter einigen Implementation auch als bloße Warnung erscheinen.)

Wenn durch »const« einmal eine Einschränkung festgelegt wurde, dann verhindert das Typsystem von C  es, daß diese Einschränkung unter Verwendung des Namen, der mit der Einschränkung versehen ist, wieder aufgehoben wird. Daher kann eine Leseadresse im allgemeinen nicht  zur Initialisierung eines Zeigers, der kein Lesezeiger ist, verwendet werden.

main.c

#include <stdio.h>

int main( void )
{ int const i = 27;
int const * p = &i;
printf( "%d\n", *p );
/* int * w = p;
error: initialization discards 'const' qualifier from pointer target type */ }

stdout
27

Seiteninformationen und Impressum   |   Mitteilungsformular  |   "ram@zedat.fu-berlin.de" (ohne die Anführungszeichen) ist die Netzpostadresse von Stefan Ram.   |   Eine Verbindung zur Stefan-Ram-Startseite befindet sich oben auf dieser Seite hinter dem Text "Stefan Ram".)  |   Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram. Schlüsselwörter zu dieser Seite/relevant keywords describing this page: Stefan Ram Berlin slrprd slrprd stefanramberlin spellched stefanram723258 stefan_ram:723258 Leseadressen in C Stefan Ram, Berlin, and, or, near, uni, online, slrprd, slrprdqxx, slrprddoc, slrprd723258, slrprddef723258, PbclevtugFgrsnaEnz Erklärung, Beschreibung, Info, Information, Hinweis,

Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram.
https://www.purl.org/stefan_ram/pub/lesezeiger_c