C ist in der Embedded-Entwicklung eine überaus beliebte Programmiersprache. Ihre immense Flexibilität und Ausdrucksstärke birgt aber auch größte Gefahren für unerfahrene oder leichtfertige Programmierer. Daher ist es essentiell, sich ausgiebig mit den Grundlagen der Sprache vertraut zu machen.
Um die Grundlagen von C zu beherrschen, sollte man sich zuallererst mit den lexikalischen Elemente, gewissermaßen dem "Wortschatz" der Programmiersprache, auseinandersetzen.
(Bild: Clipdealer)
C stellt eine sehr populäre, imperative Sprache dar, die sich durch zahlreiche Eigenschaften auszeichnet. Sie verfügt über einen relativ kleinen Sprachkern und eine kompakte Notation. Sie besitzt einen reichhaltigen Satz von Standarddatentypen und einen ebenso reichhaltigen Satz von Operatoren. Sie verfügt über Zeiger (pointer), Felder und Verbünde für komplexe Datenstrukturen, und sie kann diese sehr gut auf Maschinenebene abbilden, was eine hohe Effizienz bei vergleichsweise wenig Code ermöglicht. Alles andere, z.B. wie E/A oder Speicherverwaltung, ist in Standard-Bibliotheken untergebracht. Das alles zusammengenommen macht C zu einer kompakten und relativ einfach zu erlernenden Sprache, die auch in der Embedded-Entwicklung weite Verbreitung gefunden hat, und die sich gut zwischen unterschiedlichen Systemen portieren lässt.
Die immense Flexibilität und Ausdrucksstärke von C birgt aber auch größte Gefahren in der Hand eines unerfahrenen oder leichtfertigen Programmierers. C ist per se keine sichere Sprache – wenn auch bei entsprechender Programmierdisziplin (und bei Befolgung entsprechender Coding-Standards) C durchaus auch für sichere Embedded-Software geeignet ist.
Lexikalische Elemente: Der "Wortschatz" von C
Wie bereits erwähnt handelt es sich bei C um eine Imperative Programmiersprache. Ein imperatives Programm beschreibt eine Berechnung durch eine Folge von Anweisungen, die den Status des Programms verändern. Im Gegensatz dazu wird in einer deklarativen Sprache bzw.Programm eine Berechnung beschrieben, in der codiert wird, was berechnet werden soll, aber nicht wie. Mit anderen Worten: In imperativen Sprachen wie C werden die Algorithmen bis ins letzte Detail so beschrieben, wie sie auch auszuführen sind.
Um das Prinzip der imperativen Programmierung besser verständlich zu machen gehen wir in diesem (und weiteren) Grundlagenartikeln zu C auf die essentiellen Elemente der Programmiersprache ein. Den Anfang stellen die sogenannten lexikalischen Elemente dar; auf Syntax, Präprozessor und die Standardbibliothek wird später in gesonderten Artikeln eingegangen werden.
Der Grundzeichensatz von C
Der Grundzeichensatz für C-Quelltexte umfasst folgende sichtbare Zeichen:
Großbuchstaben: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
Kleinbuchstaben: a b c d e f g h i j k l m n o p q r s t u v w x y z
BEL [Alarmglocke (bell)], mit der Ersatzdarstellung \a
BS [Rückschritt (backspace)], mit der Ersatzdarstellung \b
FF [Seitenvorschub (form feed)], mit der Ersatzdarstellung \f
NL [Zeilenvorschub (newline)], mit der Ersatzdarstellung \n
CR [Wagenrücklauf (carriage return)], mit der Ersatzdarstellung \r
HT [Horizontaltabulator (horizontal tab)], mit der Ersatzdarstellung \t
VT [Vertikaltabulator (vertical tab)], mit der Ersatzdarstellung \v
Es gibt auch Ersatzdarstellungen für die Anführungszeichen und zwei weitere Sonderzeichen zur Verwendung in Zeichen- und Zeichenkettenkonstanten. Hier dient der Rückschrägstrich dazu, die Sonderbedeutung des betreffenden Zeichens zu unterdrücken: \“, \‘, \?, \\. Um alle Zeichen des Zeichensatzes der Maschine darstellen zu können, gibt es ferner so genannte numerische Escape-Sequenzen (Ersatzdarstellungen):
\d, oder \dd oder \ddd d (1...3) ist Oktalziffer (oft gebraucht: ‚\0‘, die Null)
\xh oder \xhh oder . . . h (beliebige Anzahl) ist Hexadezimalziffer (0 bis 9, A bis F oder a bis f)
In Zeichen- und Zeichenkettenkonstanten (auch Literale genannt) können alle Zeichen des verwendeten Systems vorkommen.
White Space (Leerraum)
Als Leerraum (white space) gelten Leerzeichen, Zeilenvorschub, Wagenrücklauf, vertikaler und horizontaler Tabulator, sowie Seitenvorschub. Kommentare gelten auch als Leerraum. Leerraum wird syntaktisch ignoriert, außer in Zeichenketten- oder Zeichenkonstanten; er dient dazu, sonst aneinandergrenzende Wörter, Zeichen etc. zu trennen und den Quelltext für Menschen durch übersichtliche Gestaltung, z.B. Einrückungen nach Kontrollstruktur etc., gut lesbar zu machen.
Kommentare
Kommentare werden durch die Zeichenpaare /* und */ erzeugt. Alles, was dazwischen steht – auf einer Zeile oder mit beliebig vielen Zeilen dazwischen, gilt als Kommentar. Kommentare dürfen nicht geschachtelt werden.
/* Das ist zum Beispiel ein Kommentar . . . und hier geht er immer noch weiter */
Schlüsselwörter in C
C hat die folgenden 32 Schlüsselwörter (reserved words, keywords):
Bezeichner in C (identifier), sonst auch schlicht Namen genannt, werden folgen dermaßen gebildet (als regular expression (regulärer Ausdruck) in Unix-Notation): [A-Za-z_][A-Za-z_0-9]*. d.h. Buchstabe oder Unterstrich optional gefolgt von beliebiger (auch Null) Folge eben dieser, inklusive der Ziffern.
Bezeichner dürfen nicht mit einer Ziffer beginnen, Groß- und Kleinbuchstaben sind als verschieden zu werten. Bezeichner dürfen nicht aus der Menge der o.g. Schlüsselwörter sein (oder aus der Menge von Namen, die für die Standardbibliothek reserviert sind, sie müssen sich mindestens in den ersten 31 Zeichen unterscheiden. Mit Unterstrich beginnende Namen sind für das System reserviert und sollten nicht verwendet werden. Bezeichner mit externer Bindung (d.h. Weiterverarbeitung durch Linker etc.) können weiteren Beschränkungen unterliegen.
Stand: 08.12.2025
Es ist für uns eine Selbstverständlichkeit, dass wir verantwortungsvoll mit Ihren personenbezogenen Daten umgehen. Sofern wir personenbezogene Daten von Ihnen erheben, verarbeiten wir diese unter Beachtung der geltenden Datenschutzvorschriften. Detaillierte Informationen finden Sie in unserer Datenschutzerklärung.
Einwilligung in die Verwendung von Daten zu Werbezwecken
Ich bin damit einverstanden, dass die Vogel Communications Group GmbH & Co. KG, Max-Planckstr. 7-9, 97082 Würzburg einschließlich aller mit ihr im Sinne der §§ 15 ff. AktG verbundenen Unternehmen (im weiteren: Vogel Communications Group) meine E-Mail-Adresse für die Zusendung von redaktionellen Newslettern nutzt. Auflistungen der jeweils zugehörigen Unternehmen können hier abgerufen werden.
Der Newsletterinhalt erstreckt sich dabei auf Produkte und Dienstleistungen aller zuvor genannten Unternehmen, darunter beispielsweise Fachzeitschriften und Fachbücher, Veranstaltungen und Messen sowie veranstaltungsbezogene Produkte und Dienstleistungen, Print- und Digital-Mediaangebote und Services wie weitere (redaktionelle) Newsletter, Gewinnspiele, Lead-Kampagnen, Marktforschung im Online- und Offline-Bereich, fachspezifische Webportale und E-Learning-Angebote. Wenn auch meine persönliche Telefonnummer erhoben wurde, darf diese für die Unterbreitung von Angeboten der vorgenannten Produkte und Dienstleistungen der vorgenannten Unternehmen und Marktforschung genutzt werden.
Meine Einwilligung umfasst zudem die Verarbeitung meiner E-Mail-Adresse und Telefonnummer für den Datenabgleich zu Marketingzwecken mit ausgewählten Werbepartnern wie z.B. LinkedIN, Google und Meta. Hierfür darf die Vogel Communications Group die genannten Daten gehasht an Werbepartner übermitteln, die diese Daten dann nutzen, um feststellen zu können, ob ich ebenfalls Mitglied auf den besagten Werbepartnerportalen bin. Die Vogel Communications Group nutzt diese Funktion zu Zwecken des Retargeting (Upselling, Crossselling und Kundenbindung), der Generierung von sog. Lookalike Audiences zur Neukundengewinnung und als Ausschlussgrundlage für laufende Werbekampagnen. Weitere Informationen kann ich dem Abschnitt „Datenabgleich zu Marketingzwecken“ in der Datenschutzerklärung entnehmen.
Falls ich im Internet auf Portalen der Vogel Communications Group einschließlich deren mit ihr im Sinne der §§ 15 ff. AktG verbundenen Unternehmen geschützte Inhalte abrufe, muss ich mich mit weiteren Daten für den Zugang zu diesen Inhalten registrieren. Im Gegenzug für diesen gebührenlosen Zugang zu redaktionellen Inhalten dürfen meine Daten im Sinne dieser Einwilligung für die hier genannten Zwecke verwendet werden. Dies gilt nicht für den Datenabgleich zu Marketingzwecken.
Recht auf Widerruf
Mir ist bewusst, dass ich diese Einwilligung jederzeit für die Zukunft widerrufen kann. Durch meinen Widerruf wird die Rechtmäßigkeit der aufgrund meiner Einwilligung bis zum Widerruf erfolgten Verarbeitung nicht berührt. Um meinen Widerruf zu erklären, kann ich als eine Möglichkeit das unter https://contact.vogel.de abrufbare Kontaktformular nutzen. Sofern ich einzelne von mir abonnierte Newsletter nicht mehr erhalten möchte, kann ich darüber hinaus auch den am Ende eines Newsletters eingebundenen Abmeldelink anklicken. Weitere Informationen zu meinem Widerrufsrecht und dessen Ausübung sowie zu den Folgen meines Widerrufs finde ich in der Datenschutzerklärung, Abschnitt Redaktionelle Newsletter.
Konstanten
C kennt vier Hauptgruppen von Konstanten:
Ganzzahlkonstanten Dezimal-, Oktal- oder Hex-Darstellung
Gleitpunktzahlkonstanten mit Dezimalpunkt und/oder Exponentkennung
Zeichenkonstanten eingeschlossen in ‚. . . ‚
Zeichenkettenkonstanten eingeschlossen in „. . . „
Numerische Konstanten sind immer positiv, ein etwa vorhandenes Vorzeichen gilt als unärer Operator auf der Konstanten und gehört nicht dazu. Ganzzahlkonstanten sind vom Typ int, wenn das nicht ausreicht, vom Typ long, wenn auch das nicht ausreicht, vom Typ unsigned long. Man kann die größeren Typen auch durch Anfügen von Suffixen erzwingen, wie aus der folgenden Übersicht hervorgeht:
Dezimalziffern 0 1 2 3 4 5 6 7 8 9
Oktalziffern 0 1 2 3 4 5 6 7
Hexziffern 0 1 2 3 4 5 6 7 8 9 A B C D E F a b c d e f
0 Die Konstante 0 (Null)
l L Ganzzahlsuffix für long (Achtung, Verwechslungsgefahr l ['kleines L'] mit 1!)
u U Ganzzahlsuffix für unsigned
f F l L Gleitpunktzahlsuffix für float bzw. long double (s.o.)
e E Gleitpunktzahlkennung für Exponent
Beginnt die Ganzzahlkonstante mit 0x oder 0X, so liegt Hexnotation vor und es folgen eine oder mehrere Hexziffern. Dabei stehen A-F bzw. a-f für die Werte 10...15. Beginnt andernfalls die Ganzzahlkonstante mit einer 0, so liegt Oktalnotation vor und es folgen eine oder mehrere Oktalziffern, andernfalls liegt Dezimalnotation vor.
Gleitpunktzahlkonstanten sind immer vom Typ double, falls nicht durch Suffix als float oder long double gekennzeichnet. Zur Erkennung müssen mindestens der Dezimalpunkt oder die Exponentkennung vorhanden sein.
Eine Zeichenkonstante (character constant) ist ein in einfache Hochkommata eingeschlossenes Zeichen aus dem Zeichensatz oder seine (auch mehrere Zeichen umfassende) Ersatzdarstellung. Die Betrachtung sog. wide character constants, sowie sog. multi byte character constants unterbleibt hier. Zeichenkonstanten sind vom Typ int, dürfen aber nicht wertmäßig größer als der entsprechende Typ char sein.
Eine Zeichenkettenkonstante (string constant) ist eine in sogenannte doppelte Anführungszeichen eingeschlossene Zeichenkette auf einer Zeile. Sie darf alle Zeichen des Zeichensatzes, inklusive etwaiger Ersatzdarstellungen, und (dann signifikanten) Leerraum enthalten. Nur durch Leerraum getrennte Zeichenketten werden vom Präprozessor zusammengefügt und gelten als eine Zeichenkette. Man kann eine Zeile auch umbrechen, indem man sie mit einem Rückschrägstrich terminiert. Die auf diese Weise fortgeführte Zeile gilt dann als eine logische Zeile.
Zeichenketten werden standardgemäß als array of char von niederen zu höheren Adressen mit terminierendem Nullwert im Speicher abgelegt. Ihre Speichergröße ist daher immer um 1 größer als die Größe, die der Anzahl der enthaltenen Zeichen entsprechen würde. Das sind also die allseits verbreiteten so genannten C-Strings. Der Nullwert dient als Terminierungsmarke für alle Routinen der Standardbibliothek und kann folglich im String selbst nicht vorkommen. Der terminierende Nullwert gehört somit nicht zu den Zeichen des Strings und wird folglich bei Ermittlung seiner Länge auch nicht mitgezählt.
Eine Zeichenkette als Typ array of char zu sehen, nimmt man aber nur bei der Initialisierung von Arrays oder der Anwendung des sizeof-Operators wahr. Bei den meisten Verwendungen treten jedoch sofort die üblichen syntaktischen Umwandlungen von C in Kraft, und man sieht nur noch einen Zeiger auf das erste Zeichen, also den Typ char *, über den man dann alle weitere Verarbeitung steuern kann.
Dies stellt einen Überblick über die lexikalischen Elemente der Programmiersprache C dar; also eine Zusammenfassung des von C aufgefassten und interpretierbaren Wortschatzes. Um hiermit Ausdrücke, Anweisungen oder Funktionen umsetzen zu können, kommt es auf den richtigen kontextuellen Zusammenhang dieser lexikalischen Elemente an. Dies wid demnach auch als die Syntax" von C bezeichnet. Auf diese syntaktischen Elemente von C gehen wir in einem anderen Beitrag näher ein.