|
|
'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 das 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 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#, 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.
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.
Der folgende Code stellt ein minimales C-Programm dar, das eine Meldung auf dem Standardausgabemedium ausgibt.
int main (void)
{
puts ("Hello, World!");
return 0;
}
If ... else
"Hello, World!"-Programm in C
#include
Kontrollstrukturen
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
Eine der grössten Schwächen von C ist die Unvollständigkeit der Sprachspezifikation, die viele Dinge offen lässt. So ist z.B. für viele Operatoren nicht festgelegt, in welcher Reihenfolge eine Reihe von gleichrangig nebeneinander stehenden Operatoren ausgewertet werden, ebensowenig, in welcher Reihenfolge die Argumente eines Funktionsaufrufs ausgewertet werden.
Beispiele:
Nimmt man nun stattdessen
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.
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.
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.
Der Programmierer muss den dynamischen Speicher selbst verwalten. Hierzu stehen in der Regel Bibliotheksfunktionen zur Verfügung.
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 ale 32 Bits lang, so dass sich dies als Quasistandard etabliert hat. Dies und einige weitere Eigenschaften der Sprachdefinition (Ergebnistyp bei Zeigersubtraktion, Alignment von Datentypen) bereiten bei der Portierung auf modernere 64-Bit-Architekturen Probleme.
Stärken von C
Schwächen von C
Unvollständigkeit der Spezifikation
a=b*c*d;
Hier ist nicht festgelegt, ob nun zuerst b*c oder c*d ausgewertet wird.
In Bezug auf Rundungsfehler und Überläufe macht das bereits einen Unterschied.
Noch deutlicher wird der Unterschied bei Operatoren (und Funktionsaufrufen, die als Operanden auch erlaubt sind) mit Seiteneffekten. a=b++ * ++b * b;
so ergeben sich mehrere mögliche Endergebnisse, u.a.
b*(b+2)*(b+2); (Auswertung von Links nach Rechts, Seiteneffekte sofort effektiv)
(b+1) * (b+1) * b; (Auswertung von Rechts nach Links, Seiteneffekte sofort effektiv);
b*b*b (Wenn die Seiteneffekte nicht sofort effektiv werden).
Anmerkung: Die Spezifikation von C liefert eindeutige Regeln für solche Ausdrücke. Siehe Diskussion.Stringunterstützung
Felder
"Wilde" Pointer
Speicherverwaltung
Portabilitätsprobleme
Literatur
Weblinks
zh-tw:C編程語言