2.4    Symbole in C

Jede Programmiersprache hat einen festgelegten Satz von Symbolen, und es ist daher unerlässlich, dass Sie die Regeln für gültige Symbole in C kennen. Symbole werden durch »fest verdrahtete« Zeichenfolgen definiert, und diese Zeichenfolgen werden quasi als Einheit betrachtet. Symbole nennt man auch Tokens. Sie sollten mit dem Begriff Token vertraut sein, weil dieser manchmal in den Fehlerausgaben des GCC-Compilers auftaucht. Wenn Sie beispielsweise die Fehlermeldung »error using token ›=‹« bekommen, haben Sie das Gleichheitssymbol falsch verwendet und z. B. 1=A statt A=1 geschrieben. In den nächsten Anschnitten werden wir nun die einzelnen Symboltypen behandeln.

2.4.1    Bezeichner

Bezeichner sind Namen für Objekte in einem Programm, die vom Programmierer festgelegt werden können, etwa Variablen, Funktionen usw. Für die Namen für gültige Bezeichner gelten folgende Regeln:

Zur Demonstration sollen einige falsche und richtige Bezeichner aus einem Codeausschnitt gezeigt werden. In der Codezeile

int maxSpieler = 100;

ist maxSpieler der einzige Bezeichner, den Sie als Programmierer festlegen, und zwar der Name einer Variablen. 100 ist ein Literal für die Zahl Hundert. Der Variablen maxSpieler wird der Wert 100 zugewiesen. int ist ein Schlüsselwort von C und gibt an, dass Sie der Variablen maxSpieler nur ganze Zahlen zuweisen können.

Weitere Beispiele für gültige – und unterschiedliche – Bezeichner sind:

maxspieler, ival, i

Ungültig sind z. B.:

2terSpieler, zweiter Spieler, for, _Bool, Spieler(maxAnz)

Die Gründe: Eine Ziffer am Anfang wie bei 2terSpieler ist nicht erlaubt, Leerzeichen wie bei zweiter Spieler sind nicht erlaubt, for ist ein Schlüsselwort, _Bool ebenso, und die Klammern bei Spieler(maxAnz) sind hier nicht erlaubt, weil sie normalerweise Teil einer Funktionsdeklaration sind.

Nicht verwendet werden sollten z. B.:

_Spieler, __spieler, _i3

Diese Bezeichner mit einem führenden Unterstrich liegen im reservierten Bereich, sind also reservierte Bezeichner.

Reservierte Bezeichner

Auf Bezeichner, die mit zwei sequenziellen Unterstrichen oder einem Unterstrich, gefolgt von einem Großbuchstaben beginnen, sollten Sie verzichten, weil sie für C-Implementierungen reserviert sind. Bezeichner wie __asdf sind für gewöhnlich für Compiler-Zwecke, Bezeichner wie _Asdf für Betriebssystem- und Bibliothekszwecke gedacht.

2.4.2    Reservierte Schlüsselwörter

Reservierte Schlüsselwörter haben als Bestandteile der Sprache C eine festgelegte Bedeutung. Sie dürfen nicht anderweitig verwendet werden. So dürfen Sie beispielsweise keine Variable mit dem Bezeichner int verwenden, da es auch einen Basisdatentyp mit diesem Namen gibt. Der Compiler würde sich ohnehin darüber beschweren. In Tabelle 2.2 finden Sie die reservierten Schlüsselwörter in C.

auto

break

case

char

const

continue

default

do

double

else

enum

extern

float

for

goto

if

int

long

register

return

short

signed

sizeof

unsigned

void

volatile

while

C99

inline

restrict

_Bool

_Complex

_Imaginary

C11

_Alignas

_Alignof

_Atomic

_Generic

_Noreturn

_Static_assert

_Thread_local

Tabelle 2.2    Reservierte Schlüsselwörter in C

Vielleicht ist Ihnen aufgefallen, dass printf kein Schlüsselwort und nach den Regeln ein erlaubter Bezeichner ist. Aber printf hat doch eine festgelegte Bedeutung? printf ist in der Tat ein erlaubter Bezeichner – er wurde nur bereits verwendet, nämlich von den Programmierern, deren Code Sie über stdio.h einbinden. Es ist der Name der Funktion, die Sie für die Ausgabe kennen. Ihre eigene Funktion sollten Sie vernünftigerweise nicht genauso nennen, wenn Sie stdio.h verwenden. Bei einer Kollision dieser Art wird sich der Compiler bei Ihnen beschweren. Vom Grundprinzip von C her ist es nicht verboten, printf als Bezeichner zu verwenden, weil Sie theoretisch auch Ihr eigenes printf programmieren und dieses dann anstelle der Version der Standardbibliothek verwenden könnten. Aus der Einführung wissen Sie ja noch, dass C aus einem Sprachkern und der Standardbibliothek besteht. Es ist also lediglich verboten, Bezeichner des Sprachkerns zu verwenden.

2.4.3    Literale

Als Literale werden Zahlen, Zeichenketten und Wahrheitswerte im Quelltext bezeichnet. Sie müssen ebenfalls nach einem bestimmten Muster aufgebaut sein. Literale sind von einer Programmiersprache fest definierte Zeichenfolgen für die Darstellung von Werten, z. B. 10 für die Zahl Zehn oder Auto für das Wort Auto. Literale sind aber keine Tokens.

Zahlenliterale

Vielleicht überrascht es Sie: Literale für Zahlenwerte können nicht nur Ziffern enthalten, sondern auch Buchstaben. Sie werden sich vielleicht jetzt fragen, warum dies so ist. Nun, es gibt ja nicht nur das Dezimalsystem, und C versteht auch Zahlen, die Sie oktal, hexadezimal oder binär angeben können. Für Hexadezimalzahlen werden die Buchstaben A bis F gebraucht, um überhaupt die nötigen 16 verschiedenen Zeichen zusammenzubekommen (a bis f sind ebenfalls erlaubt). Außerdem wird der Buchstabe x und die Ziffer 0 benötigt, um anzuzeigen, dass ein Zahlenwert anders als dezimal zu verstehen ist. Dies funktioniert über ein Präfix, also eine vorangestellte Zeichenfolge:

Darüber hinaus werden Buchstaben benötigt, um den Datentyp genauer zu bestimmen, und zwar über Suffixe, also angehängte Zeichenfolgen. So stehen U oder u für eine positive Zahl ohne Vorzeichen (für engl. unsigned, vorzeichenlos), L oder l für den Datentyp long für ganze Zahlen, die größer sein dürfen als solche ohne das L. F oder f stehen für eine Fließkommazahl.

Schließlich verwenden Dezimalzahlen einen Punkt (.), wo im Deutschen ein Komma steht, also vor den »Nachkommastellen«.

Einige Beispiele:

Zeichenliterale

Ein Zeichenliteral wird zwischen einfachen Hochkommata (single quotes) eingeschlossen ('A', 'B', 'C', ... '$', '&' usw.). Wenn Sie nicht druckbare Zeichen (siehe Abschnitt 2.3.2, »Einige wichtige Escape-Sequenzen«) wie beispielsweise einen Tabulator oder Zeilenvorschub darstellen wollen, müssen Sie eine Escape-Sequenz (auch Steuerzeichen oder Fluchtsequenz genannt) verwenden. Escape-Sequenzen werden mit einem Backslash (\) eingeleitet (z. B. ein Tabulator mit '\t' oder ein Zeilenvorschub mit '\n').

Zeichenkettenliteral

Eine Zeichenkette (häufig auch String genannt) ist eine Sequenz von Zeichen, die zwischen doppelte Hochkommata (double quotes) gestellt werden kann, z. B. "Ich bin eine Zeichenkette"). Es ist sehr wichtig zu wissen, dass jede Zeichenkette um ein Zeichen länger ist, als sichtbar dargestellt. Für gewöhnlich werden Zeichenketten durch das Zeichen mit dem ASCII-Wert 0 (nicht die dezimale Null) abgeschlossen (0x00 oder als einzelnes Zeichen '\0'). Diese ASCII-0 kennzeichnet immer das Ende einer Zeichenkette. Somit enthält beispielsweise die Zeichenkette "ABC" vier Zeichen, weil am Ende auch das Zeichen 0x00 (oder '\0') abgelegt ist.

2.4.4    Einfache Begrenzer

Um einzelne Symbole voneinander zu trennen, werden sogenannte Begrenzer benötigt. Fast alle diese einfachen Begrenzer haben Sie bereits in Ihrem ersten Listing verwendet. Tabelle 2.3 fasst die wichtigsten Begrenzer zusammen:

Begrenzer

Bedeutung

Semikolon (;)

Dient als Abschluss einer Anweisung. Jeder Ausdruck, der mit einem Semikolon endet, wird als Anweisung behandelt. Der Compiler weiß dann, dass hier das Ende der Anweisung ist, und fährt nach der Abarbeitung dieser Anweisung mit der nächsten fort.

Komma (,)

Mit dem Komma trennen Sie für gewöhnlich gleichartige Elemente, z. B. können Sie mehrere Variablen für Ganzzahlen so definieren:

int minSp, maxSp, startSp;

Andere Beispiele werden Sie jeweils im Kontext kennenlernen.

geschweifte Klammern ({})

Zwischen den geschweiften Klammern wird ein Anweisungsblock zusammengefasst. In diesem befinden sich alle Anweisungen (abgeschlossen mit einem Semikolon), die ausgeführt werden sollen.

Gleichheitszeichen (=)

Das Gleichheitszeichen = steht in C für eine Zuweisung, z. B. in int maxSpieler = 500;

Tabelle 2.3    Einfache Begrenzer in C