C-Kurzreferenz

Die C-Kurzreferenz gibt eine kompakte tabellarische Übersicht der wichtigsten C-Befehle mit Syntax, Beschreibung und Beispiel. C-Schlüsselwörter sind grün und Konzepte grau markiert.

Befehl Syntax Beschreibung Beispiel
1 Programm­struktur
Quellcode *.c Header *.h Anweisungen Kommentare main #include #define
// Kommentar 
#include <programmbibliothek.h>
#define bezeichner wert
int main(void){
  /* Kommentar ... 
  TODO: Anweisungen einfügen */
}
Eine C-Quellcode-Datei besteht aus Anweisungen und Kommentaren. Am Anfang stehen die #include- und #define-Direktiven, gefolgt von der main-Funktion und weiteren Funktionen. Die main-Funktion ist der Einstiegspunkt, jedes Programm hat genau eine. Mit #include werden Programmbibliotheken eingebunden.
// Quellcode-Datei: myprog.c
#include <stdio.h>
#include <stdlib.h>
#define PI 3.14159
int main(void){
  /* Dies ist ...
  ... ein minimales Programm! */
}
1-1 Makros
#Direktive #define
#define bezeichner wert
#define bezeichner ausdruck
Die Präprozessor-Direktive #define erstellt ein Makro: sie ersetzt im Quellcode jedes Vorkommen des Namens mit dem angegebenen Ausdruck oder Wert.
#define WAHR 1
#define FALSCH 0
#define MAX(a, b) (a > b ? a: b)
1-2 Variablen
Datentyp int float double char
datentyp varname;
datentyp varname = wert;
datentyp varname1, varname2;
Durch die Variablen-Deklaration wird einen benannter Speicherplatz angelegt, in dem Werte des angegebenen Datentyps abgelegt werden können. Häufig verwendete Datentypen sind: int, float, double, und char.
char zeichen = 'A';
int a = 0, b = 0, c = 0;
float x = 1.5; double y = 3.3333;
// Der Wert einer Variablen kann
// geändert werden.
a = 10; a = a + 2; // a ist jetzt 12
1-3 Konstante
const
const datentyp myconst; 
Die Definition einer Konstanten erfolgt mit Hilfe des Schlüsselwortes const, der Datentyp muss angegeben werden.
const double PI  = 3.14; 
// Der Wert einer Konstanten kann
// nicht geändert werden
PI = 3.14159; // Fehler!
1-4 Operatoren
Arithmetisch +, -, *, / Modulo % Inkrementierung ++ Logisch && || ! Vergleich >, >=, <, <= == !=
// Unärer Operator
ausdruck = var op
// Binärer Operator
ausdruck = var1 op var2

// Ausdruck mit mehreren
// Variablen und Klammern
ausdruck = (var1 op1 var2) op2 var3
Berechnungen werden durchgeführt, indem Variablen über Operatoren zu Ausdrücken verknüpft werden, z.B.
(a + b ) * c / d.
Man unterscheidet zwischen arithmetischen, logischen, binären und Vergleichsoperatoren.

Die Auswertungsreihenfolge wird durch eine festgelegte Priorität der Operatoren und durch runde Klammern gesteuert.
int a = 25, b = 3, c = 0;
// Inkrementierung - erhöhe Wert um 1
a++; // a = 26	
// Abkürzende Zuweisung
b *= 2; // b = 6
// Modulo-Operator: Rest der Teilung
c = 17 % 5; // c = 2
// Ausdruck 1
float res1 = 2.0*(a + b) / (a - b);
// Ausdruck 2
res1 = (a + b) / 2.0*(a - b);
2 Eingabe
Syntax Beschreibung Beispiel
2-1 Eingabe über Konsole
scanf Platzhalter %d,%f,%lf %c,%s
scanf(formatzeichenkette,
      &adressenliste);
Die scanf-Funktion erhält als ersten Parameter eine formatierende Zeichenkette, z.B. "%d %lf", gefolgt von einer Liste von Variablen, deren Anzahl und Datentyp zu den Formatbeschreibern passen muss. Jeder Variablen muss ein &-Zeichen vorangestellt werden, das die Adresse der Variablen bezeichnet.
int a = 0; double b = 0.0;
printf("Eingabe a: ");  
scanf("%d", &a);
printf("Eingabe b: "); 
scanf("%lf", &b);
3 Ausgabe
Syntax Beschreibung Beispiel
3-1 Ausgabe auf die Konsole
printf Platzhalter %d,%f,%lf %c,%s Steuerzeichen \n
// (1) Statischer Text
printf(zeichenkette);
// (2) Text mit Variablen
printf(formatzeichenkette,
       variablenliste); 
Die printf-Funktion für die Ausgabe auf die Konsole hat als ersten Parameter eine formatierende Zeichenkette, gefolgt von einer Liste von Variablen. Die formatierende Zeichenkette enthält Text, der einfach ausgegeben wird, und Formatzeichen %d, %lf, %c, %s etc., an deren Stelle die Werte der Variablen aus der Variablen­liste eingesetzt werden.
printf("Hallo!\n"); 
double x = 1.99; 
char z = '?';
printf("x=%5.1lf, z=%c\n", 
        x, z);
3-2 Ausgabe in Dateien
fprintf fopen fclose %d,%f,%lf %c,%s \n
FILE *fp = fopen(datei, modus);
if (fp == NULL)
   return;
fprintf(fp, format, variablen);
fclose(fp); 
Der Zugriff auf eine Datei geschieht mit Hilfe des Zeigers FILE *fp und der Funktionen fopen (Datei öffnen) und fclose (Datei schließen). Nachdem eine Datei schreibend geöffnet wurde, kann sie mit Hilfe der Funktion fprintf() beschrieben werden. Der Aufruf von fprintf() funktioniert ähnlich wie printf(), mit dem Unterschied, dass man als erstes Argument den Datei-Zeiger fp übergibt.
FILE *fp = fopen("daten.txt", "w");
if (fp == NULL)
   return;
fprintf(fp, "%s\n", "Hallo!");
fclose(fp); 
4 Verzweigungen
Syntax Beschreibung Beispiel
4-1 Einfache Verzweigung
if else
if (bedingung){
    anweisungen1  
} 
else {
    anweisungen2
}
Eine bedingte Verzweigung legt fest, welcher von zwei Anweisungsblöcken, abhängig von einer Bedingung, ausgeführt wird.

Der else-Teil ist optional.
int x = -1;
if (x > 0){
    printf("positiv!\n");  
} else {
    printf("nicht positiv!\n");
}
4-2 Mehrfache Verzweigung
if else if else
if (bedingung1) {
  anweisungen1
}
else if (bedingung2){
  anweisungen2
}
else {
  anw_default
}
Eine mehrfache Verzweigung prüft die angegebenen Bedingungen von oben nach unten, führt die Anweisungen beim ersten Zutreffen aus, und springt danach in die erste Anweisung nach der Verzweigung:
Wenn die Bedingung bedingung1 wahr ist,
führe Anweisungen anweisungen1 aus.
Sonst wenn Bedingung bedingung2 wahr ist,
führe Anweisung anweisungen2 aus.
. . .
Sonst führe die Default-Anweisung aus.
double temp = 19.0;
if (temp > 30)
  printf("Heiss!\n";
else if (betrag > 20)
   printf("Warm!\n";
else if (betrag > 10)
   printf("Angenehm!\n";
else
     printf("Kalt!\n";
4-3 Fall­unterscheidung
switch case break
switch(ausdr){
  case ausdr1: 
    anw1;break; 
  case ausdr2: 
    anw2;break; 
  case ausdr_n:  
    anw_n;break;
  default:
    anw_default;
}

Fallunterscheidung: Ein Ausdruck bzw. der Wert einer Variablen wird mit verschiedenen Werten verglichen. Bei Übereinstimmung wird die entsprechende Anweisung ausgeführt. Die break-Anweisung bewirkt, dass der case-Zweig sofort verlassen wird. Wenn break in einem Zweig weggelassen wird, werden auch die folgenden case-Zweige ausgeführt, bis ein break gefunden wird, oder die switch-Anweisung zu Ende ist. Der optionale default-Zweig greift dann, wenn es keine Übereinstimmung gibt.

int wahl;
printf("Eingabe: 1, 2 oder 3:");
scanf("%d",&wahl);
switch(wahl){
  case 1: 
  printf("Erste Wahl\n");break; 
  case 2: 
  printf("Zweite Wahl\n");break; 
  case 3:  
    printf("Dritte Wahl\n");break;
  default:
  printf("Fehler!\n");
}
5 Schleifen
Syntax Beschreibung Beispiel
5-1 while-Schleife
while
while (bedingung){
  anweisungen
}
Mit der while-Schleife werden Anweisungen ausgeführt, solange eine Bedingung wahr ist.
int i = 0; double sum = 0.0;
while (i<=5){
  sum += i;
  i++;
}
printf("Summe = %.2f\n", sum);
5-2 for-Schleife
for
for(zähler=start;
    zähler<=end;
    zähler+=schritt){
    anweisungen
}
Mit Hilfe der for-Schleife werden Anweisungen wiederholt ausgeführt. Die Anzahl der Ausführungen wird durch Zählvariablen gesteuert, für die man Startwert, Endwert und Schrittweite festlegt.
double sum = 0.0;
for(int i=1;i<=5;i++){
  sum += i;
}
printf("Summe = %.2f\n", sum);
5-3 Schleifen­abbruch
break
while(bedingung){
    anweisungen
    if (bedingung2 == 1)
      break;
}
Eine Schleife kann mit break sofort verlassen werden.
int sum=0, i=0;
while(1){
  sum += i;i++;
  if(i==10)
    break;
}
printf("Summe = %.2f\n", sum);
5-4 Schleifen­schritt überspringen
continue
while(bedingung){
    anweisungen
    if (bedingung2 == 1)
     continue;
}
Einzelne Schleifenschritte in einer while-oder for-Schleife können mit continue übersprungen werden.
int sum=0, i=0;
while(1){
  sum += i;i++;
  if(i%2== 1)
    continue;
}
printf("Summe = %.2f\n", sum);
6 Funktionen
Syntax Beschreibung Beispiel
6-1 Funktion ohne Rückgabewert
void Funktionsdefinition Funktionsprototyp Funktionsaufruf
#include <stdio.h>
/* (1) Funktionsprototyp */
void myfunc(typ1,... typn);

int main(void){
  /* (3) Funktionsaufruf */
  myfunc(arg1, ..., argn);
}

/* (2) Funktionsdefinition */
void myfunc(typ1 par1, 
            ...
           typn parn){
  // Anweisungen ...
}
Eine Funktion mit Rückgabetyp void (leerem Rückgabetyp) ist eine benannte Gruppierung von Anweisungen und besteht aus:
(1) Funktionsprototyp: deklariert Rückgabetyp, Name und Parameterliste.
(2) Funktionsdefinition: enthält die Anweisungen.

Die Funktion wird einmal definiert und kann mit passenden Argumenten beliebig oft aufgerufen werden. Die Funktionsaufrufe erfolgen durch Angabe des Funktionnamens und der Argumente, die in Anzahl, Reihenfolge und Datentyp mit den Parametern übereinstimmen müssen.
#include <stdio.h>
/* (1) Funktionsprototyp */
void AusgabeInEuro(double);

int main(void){
  double b1 = 49.99;
  /* (3) Funktionsaufrufe */
  AusgabeInEuro(b1);
  AusgabeInEuro(2.5);
}

/* Funktionsdefinition */
void AusgabeInEuro(double b){
  printf("Betrag: %.2f Euro\n", b);
}
6-2 Funktion mit Rückgabewert
return Funktionsdefinition Funktionsprototyp Funktionsaufruf
/* (1) Funktionsprototyp */
r_yp myfunc(typ1,... typ_n);

int main(void){
  /* (3) Funktionsaufrufe */
  rwerta = myfunc(arg1a,... argna);
  rwertb = myfunc(arg1b,... argnb);
}

/* (2) Funktionsdefinition */
rtyp myfunc(par1, ... parn){
  rtyp rwert;
  // Anweisungen ...
  return rwert;
  }
Eine Funktion mit nicht-leerem Rückgabetyp ist eine benannte Gruppierung von Anweisungen, die einen Rückgabewert berechnet, der in der aufrufenden Funktion weiter verwendet werden kann.

Der Rückgabewert wird mit Hilfe der Anweisung return zurückgegeben.

Die Funktionsaufrufe erfolgen durch Angabe des Funktionnamens und der Argumente, die in Anzahl, Reihenfolge und Datentyp mit den Parametern übereinstimmen müssen.
/* (1) Funktionsprototyp */
float brutto_aus_netto(float, int);

int main(void){
  /* (3) Funktionsaufruf */
  printf("Brutto = %.2f\n", 
    brutto_aus_netto(12.55, 19) ); 
}

/* (2) Funktionsdefinition */
float brutto_aus_netto(float netto,
                       int mwst){
  return netto + netto*mwst/100;
}
7 Arrays
Syntax Beschreibung Beispiel
7-1 Eindimensionale Arrays
Element Index Größe
// Deklaration
datentyp arr[groesse];
// Zuweisung
arr[0] = wert_0;
// ...
arr[groesse-1] = wert_x;
Array: eine statische Datenstruktur, speichert Datenobjekte desselben Datentyps. Die Größe eine 1D-Arrays muss als Konstante angegeben werden.

Ein einzelnes Datenobjekt wird Element des Arrays genannt. Die Position einer Elementes wird über einen Index angegeben, der bei 0 anfängt.
// Zuweisung durch Auflistung
float a[] = {0.1, 0.2, 0.3, 0.4};
 
// Zuweisung mit Schleife
float b[4] = {0.0};
for(int i=0;i<4;i++){
  b[i] = 0.1*(i+1);
}
7-2 Zweidimensionale Arrays
Zeilen Spalten
// Explizite Aufzählung
datentyp arr[M][N] = {{zeile 0}, 
                      {zeile 1}, 
                      ... 
                      {zeile M-1}};

// Erst Deklaration ...
datentyp arr[M][N];
// dann Zuweisung
arr[0][0] = wert_0;
// ...
arr[M-1][N-1] = wert_x;
Bei der Deklaration eines 2D-Arrays wird der benötigte Speicherbereich durch zwei Konstanten festgelegt: die maximale Anzahl Zeilen (hier mit M bezeichnet) und maximale Anzahl Spalten (hier mit N bezeichnet).

Die Zuweisung kann gleichzeitig mit der Deklaration durch explizite Aufzählung der Elemente erfolgen, oder nach der Deklaration durch Zuweisung von Werten an die einzelnen Elemente.
// Zuweisung durch Auflistung
int a[2][2] = { {1, 0}, 
                {0, 1} };
// Zuweisung mit Schleifen
int b[3][3] = {0}; 
for(int i=0;i<3;i++){
  for(int j=0;j<3;j++){
    if (i==j) 
      b[i][j] = 1;
  }
}

8 Zeiger / Pointer
Syntax Beschreibung Beispiel
8-1 Pointer / Zeiger verwenden
Pointer Adresse
// Variable deklarieren
datentyp var;
// Pointer deklarieren
datentyp *pointer;
// Pointer = Adresse
pointer = &var;
Bei der Deklaration einer Variablen n legt der Compiler einen Speicherplatz der Größe x (1, 4, oder 8) Byte an und vergibt dabei eine Adresse (z.B. 0x46fc80), unter der die Variable gefunden werden kann.

Ein Zeiger / Pointer ist eine Referenzvariable, die die Adresse einer anderen Variablen speichern kann und z.B.für dynamische Speicherallokation, Textbearbeitung oder Referenzparameter in Funktionen verwendet wird.
Wert der Variablen a wird mittels Pointer z geändert.
int a = 10, *z = NULL;   
z = &a; // z zeigt auf a
*z = 20; // Wert von a wird auf 20 gesetzt
printf("Wert von a = %d\n",*z);
Array arr wird mittels Pointer p durchlaufen.
double *p = NULL; // p mit NULL initialisieren
double arr[] = {1.2, 2.3, 3.4};
p = &arr[0]; // p zeigt auf den Anfang von arr
p++; // Zeiger p inkrementieren
p zeigt jetzt auf arr[1]
printf("%.2lf\n",*p); // Ausgabe: 2.3
8-2 Pointer-Anwendung: Dynamische Speicherallokation
malloc calloc free
// Reserviere n Speicherplätze
dtyp *p =  
     (dtyp*) malloc(n* sizeof(dtyp)); 

// Reserviere n Speicherplätze
// Der Speicher wird mit 0 initialisiert
dtyp *p =  
      (dtyp*) calloc(n, sizeof(dtyp)); 
Dynamische Speicherallokation bedeutet, dass die Größe des reservierten Speicherbereichs verändert und freigegeben werden kann. Die C-Standardbibliothek <stdlib.h> stellt für die dynamische Speicherallokation die Funktionen malloc, calloc(), realloc() und free() zur Verfügung, mit denen man einen Speicherbereich für eine Anzahl von Daten desselben Datentyps reservieren bzw. freigeben kann.
// Dynamische Speicherallokation
char *s = (char *)malloc(20*sizeof(char));
// Alternativ mit calloc(): 
// char *s = (char *)calloc(20, sizeof(char));

// falls kein Speicher reserviert werden kann
if (s == NULL)
	return; // beende das Programm
printf("Speicherallokation ok!\n");
Befehl Syntax Beschreibung Beispiel

Tools, Quellen und weiterführende Links

  1. Visual Studio Community Edition: Für die Entwicklung von C-Programmen. Visual Studio unterstützt C-Programmierung indirekt über C++ und die Vollversion wird in vielen Unternehmen als Entwicklungsumgebung eingesetzt.
  2. yED Graph Editor: Für die Entwicklung von Fluss­diagrammen bzw. Programm­ablauf­plänen.
  3. Jürgen Wolf, C von A bis Z: openbook.rheinwerk-verlag.de/c_von_a_bis_z/, 2020.
  4. Thomas Theis: Einstieg in C. Für Programmiereinsteiger geeignet, Galileo Press, 2014.
  5. Manfred Daussman, C als erste Programmiersprache: Vom Einsteiger zum Fortgeschrittenen. Vieweg, 2010.
  6. Axel Böttcher, Franz Kneißl. Informatik für Ingenieure: Grundlagen und Programmierung in C. Oldenbourg Verlag, 1999.
  7. Brian Kernighan, Dennis Ritchie, The C programming language. Prentice-Hall, 2010.
  8. Visual Studio C Language Reference, https://docs.microsoft.com/en-us/cpp/c-language