Zum Inhalt springen

C (Programmiersprache)

aus Wikipedia, der freien Enzyklopädie
Dies ist eine alte Version dieser Seite, zuletzt bearbeitet am 7. März 2004 um 15:14 Uhr durch MarsMaster (Diskussion | Beiträge). Sie kann sich erheblich von der aktuellen Version unterscheiden.

Die Programmiersprache C wurde von Ken Thompson und Dennis Ritchie in den frühen 1970er Jahren für das neu entwickelte Betriebssystem Unix entworfen. Ken Thompson passte zunächst die Programmiersprache BCPL auf seine Bedürfnisse an und nannte die so entstandene Sprache 'B' (nach den 'Bell Labs' in denden die Sprache entwickelt wurde). Aus dieser Sprache entstand dann 'C'. Die grundlegenden Programme aller Unix-Systeme und die Kernel vieler Betriebssysteme sind in 'C' programmiert. Die heute populäre Sprache C++ ist eine objektorienterte Erweiterung von 'C'. Auch andere moderne Sprachen haben ihre Wurzeln in 'C'.

'C' ist eine Programmiersprache, die auf fast allen Computersystemen zur Verfügung steht. Im Gegensatz zu z.B. BASIC gibt es seit der Definition von ANSI-C relativ einheitliche Implementationen auf den verschiedenen Plattformen. In jedem C-System steht auch die genormte Standard C Library zur Verfügung. Dies und die sehr gute Performance der resultierenden Programme erklärt die weiterhin relativ hohe Popularität der Sprache, sowohl im kommerziellen als auch im Open-Source-Bereich.

Es gibt Meinungen, dass C softwaretechnologisch gesehen nicht dem heutigen Stand der Technik entspäche, oft wird C auch als portabler Highlevel-Assembler bezeichnet. Dem lässt sich entgegen halten das die Kerne fast aller heute verbreiteten Betriebssysteme in C implementiert wurden, und dies obwohl C++ bereits seit über 20 Jahren zur Verfügung steht. C eignet sich hervorragend für die Systemprogrammierung, anders sieht die Sache jedoch bei der Anwendungsentwicklung aus. Dort wird C zunehmend durch die objektorientierten Sprachen C++, Java und C# verdrängt, die C in Bezug auf Wartbarkeit, Produktivität, Entwurfsunterstützung, Abstraktionsniveau, geringerer Fehleranfälligkeit, betriebssystemunabhängiger Ablauffähigkeit und Leistungsfähigkeit der zugehörigen Bibliotheken teilweise eklatant ausstechen.

An anderer Stelle zeigen sich die einfache Struktur und der kleine Umfang der Sprache als großer Vorteil: Die Portierung eines C-Compilers auf eine neue Prozessor-Plattform ist verglichen mit anderen Sprachen wenig aufwändig, so dass sich dies vom einfachsten Mikrocontroller bis zum Großrechner-Prozessor praktisch immer lohnt. Für den Entwickler bedeutet das, dass er, egal für welche Plattform er programmiert, immer davon ausgehen kann, einen C-Compiler zu bekommen. Die prozessor-spezifische Programmierung in Assembler bleibt ihm dadurch ganz oder weitgehend erspart, und er kann Quellcode, den er für andere Plattformen geschrieben hat, auf eine neue Plattform mitnehmen, und dieser wird (ganz ohne oder mit kleinen Änderungen) laufen.

Die Sprachbeschreibung wurde 1972 erstmals publiziert.

Ein ausführbares C-Programm wird durch den so genannten Linker aus Objektcode erzeugt (gebunden). Die Objektcodedateien ihrerseits werden durch den Compiler aus Textdatei(en) erzeugt (übersetzt), die eine Anzahl Funktions- und Variablendefinitionen enthalten. Ein ausführbares Programm muss eine Funktion mit dem Namen main enthalten.

"Hello, World!"-Programm in C

Der folgende Code stellt ein minimales C-Programm dar, das eine Meldung auf dem Standardausgabemedium ausgibt.


#include <stdio.h>
int main (void)
{
    puts ("Hello, World!");
    return 0;
}


If ... else

  if (Bedingung) {
     Anweisungen;
  }
  [else {
     Anweisungen;
  }]


While-Schleife

  while (Bedingung) {
     Anweisungen
  }


Do ... while

  do {
     Anweisungen
  } while (Bedingung);


For-Schleife

  for (Startausdruck; Bedingung; Inkrementierausdruck) {
     Anweisungen
  }


Switch-Ausdruck

  switch (Ausdruck) {
     case marke1 :
        Anweisungen;
        break;
     case marke2 :
        Anweisungen;
        break;
     default :
        Anweisungen;
  }

Siehe auch: C++, Objective-C, GCC, Zeittafel der Programmiersprachen

Stärken von C

  • minimalistischer Sprachumfang, der kleinste bekannte C Compiler besteht aus 3742 Bytes C Code und kann sich selbst compilieren.
    • C Programme bestehen nur aus Unterprogrammen.
    • Das Hauptprogramm ist ein Unterprogramm mit dem speziellen Namen main
    • Kontrollstrukturen für strukturierte Programmierung
    • Umfangreiche Datenstrukturen (Feldkonstanten, struct, Bitfelder)
    • Vorbelegung aller Datenstrukturen mit Konstanten
    • Keine symbolischen Konstanten (ersetzt durch Makroprozessor)
    • Keine dynamische Speicherverwaltung (ersetzt durch Bibliotheksfunktionen)
    • Keine Felder (ersetzt durch Feldkonstanten und Behandlung von Feldern als Zeiger)
    • Zeigerarithmetik ermöglicht die effiziente Behandlung von Feldzugriffen, Parametern usw.
    • Strings ersetzt durch eingebaute Stringkonstanten und einfache Bibliotheksfunktionen
    • Zeiger auf Unterprogramme in Datenstrukturen speicherbar
    • Einfache Variablen nur als Wertparameter, Felder nur als Referenzparameter
    • Referenzparameter für einfache Variablen werden durch Zeiger ersetzt.
  • Hardwarenahe Programmierung ist möglich, direkter Umgang mit Bits, Bytes, direkter Speicherzugriff und Zeigerarithmetik
  • niedriger Abstraktionsgrad
  • Präprozessor zur Spracherweiterung und bedingten Übersetzung
  • Linker (C war eine der ersten Sprachen, die das Einbinden von externen vorübersetzten Routinen in der Sprachdefinition berücksichtigt)
  • Viele Optimierungen bei Übersetzung möglich
  • Ein C-Compiler ist auf nahezu jedem modernen Prozessor vorhanden, sei es ein kleiner 8-Bit Kontroller oder ein High-End 64-Bit Prozessor.

Schwächen von C

  • Stringunterstützung
    • Den Typ String (Zeichenkette) gibt es nicht im Sprachstandard. Stattdessen wird ein Zeichenfeld verwendet, das mit einem Nullzeichen abgeschlossen wird. Die Speicherverwaltung von Zeichenketten muss vom Programmierer vorgenommen werden.
  • Felder
    • C kennt zwar den Datentyp Feld und erlaubt sogar die Definition von Feldern, die mit Konstanten vorbelegt sind. Intern werden Felder jedoch immer als Zeiger verwaltet. Dies bedeutet, dass eine eventuell nötige dynamische Speicherverwaltung von Feldern vom Programmierer implementiert werden muss. Auch die Feldgröße wird beim Zugriff nicht überprüft. Durch Programmierfehler können Speicherbereiche durch illegale Feldzugriffe unabsichtlich verändert werden, ohne dass dies während der Laufzeit überprüft werden kann.
  • "Wilde" Pointer
    • Man kann Pointer auf beliebige Stellen des Speichers richten. Insbesondere zeigen nicht explizit initialisierte Stack-Variablen oft auf beliebige Stellen des Speichers. Die Folge sind schwer zu diagnostizierende Fehler.
  • Speicherverwaltung
    • Der Programmierer muss den dynamischen Speicher selbst verwalten. Hierzu stehen in der Regel Bibliotheksfunktionen zur Verfügung.
  • Portabilitätsprobleme
    • C schreibt die Speichergröße verschiedener Typen in der Sprachdefinition nicht vor. Dies ermöglicht die Portierung bestehender Programme auf andere, auch neue Prozessoren. Es ist nur zugesichert, dass ein short int nicht länger sein darf als ein long int. In den 1980er und 1990er Jahren wurden vorwiegend 32-Bit Systeme wie VAX, 68000, i386 eingesetzt. Bei diesen waren Zeiger, int und long alle 32 Bits lang, so dass sich dies als Quasistandard etabliert hat. Dies bereitet Probleme bei der Portierung auf modernere 64-Bit-Architekturen, falls der Programmierer von bestimmten Längen ausgegangen ist.
    • Einige weitere Eigenschaften der Sprachdefinition (Ergebnistyp bei Zeigersubtraktion, Alignment von Datentypen) bereiten ebenfalls Probleme, wenn statt der empfohlenen abstrakten Typen (wie ptrdiff_t für Zeigersubtraktionen, size_t für Größen von Speicherbereichen) direkt fundamentale Typen wie int verwendet werden.
    • Dieses Problem der unspezifizierten Breiten von Typen gehört seit der Sprachversion C99 der Vergangenheit an, da dort Datentypen mit expliziten Bit-Längen definiert sind (int8_t, int16_t, etc.).

Wie man der Formulierung der Schwächen bereits entnehmen kann, sind dies nicht eigentlich Schwächen der Programmiersprache, sondern ein zu freier Umgang der Programmierer mit ihren Möglichkeiten. Man kann also durchaus sagen, daß die größte Stärke von C - uneingeschränkte Freiheit des Progammierers mit Zeigern und Speicherstrukturen - gleichzeitig ihre größte Schwäche ist. Da dieser freizügige Umgang der Programmiersprache mit dem Speicher in kritischen Umgebungen (Banken, Börsen, Versicherungen, ...) leicht hohe Schäden nach sich ziehen kann, wird hier mittlerweile ernsthaft erwogen, diese Programmiersprache bei neuen Projekten zu verbieten.

Literatur