:: wikimiki.org ::
| GNAT |
GNAT
GCC ist eine Abkürzung aus dem IT-Bereich für eine Sammlung von Programmen mit der ursprünglichen Bedeutung GNU C Compiler. Da GCC inzwischen aber mehr als nur einen C-Compiler beinhaltet, hat GCC (Großbuchstaben) inzwischen die Bedeutung GNU Compiler Collection (engl. für GNU-Compilersammlung). Die Bezeichnung gcc (Kleinbuchstaben) steht immer noch für den C-Compiler.
Überblick
Die Sammlung enthält Compiler für die Programmiersprachen C, C++, Java, Objective-C, Fortran, Treelang und Ada. Die Compilersammlung unterliegt den Bedingungen der GPL.
Die erste öffentliche Version (0.9) des GCC wurde am 22. März 1987 von Richard Stallman für das GNU-Projekt freigegeben (Version 1.0 erschien am 23. Mai desselben Jahres) und wird heute von Programmierern auf der ganzen Welt weiterentwickelt. Die Erweiterung des C-Compilerpakets zur Compiler-Collection erfolgte im Rahmen des EGCS-Projektes, das eine Weile parallel zum GCC existierte und schließlich zum offiziellen GCC wurde.
GCC ist ein umfangreiches Projekt. Es besteht aus über 25.000 Dateien mit über 2,1 Millionen Zeilen Code.
GCC wird von einer Reihe von Systemen als Standardcompiler benutzt, darunter GNU/Linux, BSD, Mac OS X, NextStep, und BeOS bzw. ZETA. Er wurde auf mehr Systeme und Rechnerarchitekturen portiert als jeder andere Compiler und bietet sich besonders für Betriebssysteme an, die auf verschiedenen Hardware-Plattformen laufen sollen.
Das GCC-Projekt entschied sich, einige Plattformen offiziell als primäre und andere als sekundäre Evaluationsplattformen zu bezeichnen. Vor jeder Veröffentlichung einer neuen Version werden insbesondere diese beiden Gruppen getestet. Zu den Prozessoren, für die GCC Programme erzeugen kann, gehören (primäre und sekundäre Evaluationsplattformen sind markiert):
- Alpha (primär, unter Red Hat Linux)
- ARM-Architektur (sekundär, unter Linux)
- H8/300
- S/370, S/390
- x86 und x86-64 (primär unter Linux und FreeBSD)
- IA-64 „Itanium“
- Motorola 68000
- Motorola 88000
- MIPS-Architektur (primär unter IRIX)
- PA-RISC (primär unter HP-UX)
- PDP-11
- PowerPC (primär unter AIX, sekundär unter Linux)
- SuperH
- Sun SPARC (primär unter Solaris, sekundär unter Linux)
- VAX
Dazu kommen noch eine Reihe von Prozessoren aus dem embedded-Bereich, wie z. B. Motorolas 68HC11, A29K, ARC, AVR, C4x, CRIS, D30V, DSP16xx, FR-30, FR-V, Intel i960, IP2000, M32R, MCORE, MMIX, MN10200, MN10300, NS32K, ROMP, Stormy16, V850, und Xtensa.
Struktur
Das externe Interface des gcc entspricht dem eines Standard-Unix-Compilers. Der Benutzer ruft ein Hauptprogramm mit dem Namen gcc auf, das Kommandozeilen-Argumente interpretiert, die in den Eingabedateien vorliegende Programmiersprache feststellt, den entsprechenden Sprach-Compiler aufruft, dem Assembler dessen Ausgabe übergibt und zum Schluss evtl. den Linker aufruft, um ein komplettes Programm zu erhalten.
Jeder Sprachcompiler ist ein separates Programm, das Quellcode entgegennimmt und Assemblersprache produziert. Alle haben eine vergleichbare interne Struktur: Ein sprachabhängiges Frontend parst die Sprache und erzeugt einen abstrakten Syntaxbaum, der an ein Backend übergeben wird, das den Baum in GCCs Register Transfer Language (RTL) überführt, verschiedene Codeoptimierungen durchführt und zum Schluss Assemblersprache erzeugt. Der dazu verwendete Algorithmus basiert auf Arbeiten von Jack Davidson und Chris Fraser zum Pattern Matching.
Fast alle Bestandteile des GCC sind in C geschrieben. Eine Ausnahme bildet das Ada-Frontend, das zum größten Teil in Ada geschrieben ist.
Frontends
Frontends müssen Bäume produzieren, die vom Backend verarbeitet werden können. Wie sie dies erreichen, bleibt ihnen überlassen. Einige Parser benutzen Yacc-ähnliche Grammatiken, andere verwenden handgeschriebene, rekursive Parser.
Bis vor kurzem war die Baumrepräsentation des Programms nicht völlig vom Zielprozessor unabhängig. Die Bedeutung eines Baums konnte für unterschiedliche Sprachfrontends unterschiedlich sein, und Frontends konnten ihren eigenen Baumcode zur Verfügung stellen.
Mit dem Tree-SSA-Projekt, das in die neue Version GCC 4.0 integriert wird, wurden zwei neue Formen von sprachunabhängigen Bäumen eingeführt. Diese neuen Baumformate wurden GENERIC und GIMPLE getauft. Parsing wird nun durchgeführt, indem ein temporärer sprachabhängiger Baum nach GENERIC konvertiert wird. Der so genannte "Gimplifier" überführt diese komplexe Form in die SSA-basierte GIMPLE-Form, von der ausgehend eine Reihe neuer sprach- und architekturunabhängiger Optimierungen durchgeführt werden können.
Optimierung an Bäumen passt eigentlich nicht in das Schema von „Frontend“ und „Backend“, da sie nicht sprachabhängig ist und kein Parsen beinhaltet. Die GCC-Entwickler haben diesem Teil des Compilers daher den Namen „Middleend“ gegeben. Zu den gegenwärtig am SSA-Baum durchgeführten Optimierungen gehören Dead Code Elimination, Partial Redundancy Elimination, Global Value Numbering, Sparse Conditional Constant Propagation, und Scalar replacement of Aggregates. Array-basierende Optimierungen wie zum Beispiel automatische Vektorisierung, wie sie der Intel-Compiler anbietet, werden gegenwärtig entwickelt.
Backend
Das Verhalten des GCC-Backends wird teilweise durch Präprozessor-Makros und architekturspezifische Funktionen bestimmt, mit denen zum Beispiel die Endianness, Wortgröße und Aufrufkonventionen definiert werden. Unter Verwendung dieser Informationen generiert das Backend die Register Transfer Language (RTL). Obwohl diese dem Namen nach prozessorunabhängig ist, ist die Sequenz an abstrakten Instruktionen daher bereits an das Ziel angepasst.
Die Art und Anzahl der vom GCC an der RTL durchgeführten Optimierungen werden mit jeder Compiler-Version weiterentwickelt. Seit der kürzlichen Einführung von globalen SSA-basierten Optimierungen an GIMPLE-Bäumen haben die RTL-Optimierungen leicht an Bedeutung verloren, da in der RTL-Repräsentation des Programms weit weniger der für viele Optimierungen wichtigen High-Level-Informationen enthalten sind.
In einer „Reload“-Phase werden abstrakte Pseudo-Register durch echte Maschinenregister ersetzt, wobei Daten aus Strukturen verwendet werden, die den Befehlssatz des Ziels beschreiben. Diese Phase ist recht kompliziert, da die verschiedenen Eigenheiten der jeweiligen Zielarchitektur hier besonders berücksichtigt werden müssen.
Die letzte Phase ist relativ unspektakulär. Aus der bereits recht maschinennahen Umsetzung der RTL wird Assemblercode generiert, indem die Namen von Registern und Adressen in Strings umgesetzt werden, die die Instruktionen spezifizieren.
Siehe auch
- GNU Compiler for Java
- GCC XML Node Introspector
- Plattformunabhängigkeit
- Free Software Foundation
- GNU
- LLVM
- DISTCC
- CCACHE
- MinGW, eine Portierung auf die Microsoft-Windows-Plattform
- Cygwin
- OpenWatcom
Weblinks
- [http://gcc.gnu.org/ gcc.gnu.org] - Die offizielle GCC-Startseite
- [http://www.lcs-chemie.de/c_comp.htm Kurzanleitung für den GCC]
----
Dieser Artikel basiert auf einer Übersetzung des Artikels :en:GNU Compiler Collection aus der englischen Wikipedia, Version vom 31. Juli 2004
Kategorie:GNU
Kategorie:Programmiersprache C
Kategorie:Programmiersprache C-Plusplus
ja:GNUコンパイラコレクション
InformationstechnikInformationstechnik (IT) (manchmal spricht man auch von Informationstechnologie) ist der Oberbegriff für die Informations- und Datenverarbeitung sowie die dafür benötigte Hardware. Er beschreibt Geräte und Verfahren zur Verarbeitung von Informationen und Daten (Datentechnik), aber auch den Bereich der Telekommunikation. Der Begriff IT bzw. Information Technology wird heutzutage auch oftmals als Bezeichnung der Abteilung eines Unternehmens verwendet, die sich mit der Entwicklung und Betreuung der unternehmensinternen Computer-Infrastruktur (Administration, Intranet, ...) befasst.
Im deutschen Sprachgebrauch beherrschte die englisch ausgesprochene Abkürzung IT [] die Medien, als um die Jahrtausendwende ein allgemeines Boomen der "IT-Branche" verbunden mit einer Knappheit an "IT-Fachkräften" auf dem Arbeitsmarkt bestand. In diesem Zusammenhang wurde durch die Initiative D21 auch in Deutschland das Konzept der Green Card übernommen. Allerdings ist in den letzten Jahren durch die Rezession auch in der IT-Branche die Arbeitslosigkeit stark angestiegen und die Nachfrage nach Arbeitskräften eingebrochen.
Die Weiterentwicklungen der IT haben in den letzten Jahrzehnten alle Lebensbereiche zu verändern bzw. zu prägen begonnen, neben der Wirtschaft auch die Wissenschaft und viele weitere Lebensbereiche. Deshalb wird es immer wichtiger, sowohl die Softwareentwicklungsprozesse als auch die Prozesse zur Erbringung von IT-Dienstleistungen (engl. IT-Services) zu verbessern. Hierbei ist es zunehmend relevant geworden, Erkenntnisse der kritischen Forschung zur Mensch-Computer-Interaktion einzubeziehen.
Spezielle Arbeitsbereiche sind IT-Industrie, IT-Dienstleistungen, IT-Beratung, IT-Unternehmensberatung.
Die korrekte Übersetzung des englischen Begriffs information technology ist Informationstechnik und nicht Informationstechnologie (Es heißt ja auch Elektrotechnik und nicht Elektrotechnologie).
Siehe auch
Datentechnik, Elektronische Datenverarbeitung (EDV), Informatik, Information und Kommunikation, IT-Berufe, Kommunikationstechnik, Kommunikationstechnologie, Medizintechnik
Kategorie:IT-Architektur
Kategorie:IT-Management
ja:情報技術
ko:정보통신기술
ms:Teknologi maklumat
th:เทคโนโลยีสารสนเทศ
ComputerprogrammEin Computerprogramm ist ein festgelegter Ablauf am Computer, mit dessen Hilfe ein bestimmtes Ziel erreicht werden kann. Der Ablauf besteht aus einer Folge von einzelnen Befehlen, die von einem Prozessor verarbeitet werden.
Die Erstellung eines solchen Programms bezeichnet man allgemein als Programmierung oder bezogen auf einen konkreten Lösungsweg (Algorithmus) als Implementierung.
Im Sprachgebrauch wird Computerprogramm meist zu Programm verkürzt oder der engl. Begriff Software (für Ein- und Mehrzahl) synonym verwendet.
Sowohl der in einer Programmiersprache verfasste Quelltext als auch der von einem Computer ausführbare Maschinencode werden als Programm bezeichnet. Um aus dem Quelltext den Maschinencode zu generieren, wird ein Assembler, Compiler oder Interpreter benötigt. Diese übersetzen die Befehle der Programmiersprache, die für menschliche Benutzer verständlich und bearbeitbar sein sollen, in die semantisch entsprechenden Befehle der Maschinensprache des verwendeten Computers.
Geschichte
Das erste Computerprogramm von Ada Lovelace
Als weltweit erstes Computerprogramm gilt eine Vorschrift für die Berechnung von Bernoulli-Zahlen, die Ada Lovelace in den Jahren 1842/1843 für die mechanische Analytical Engine von Charles Babbage erstellte. Dieses Programm konnte zu ihrer Zeit nur von Hand ausgeführt werden, denn wegen Fertigungsproblemen gab es im 19. Jahrhundert keine funktionsfähige Maschine.
Erste Programme auf Lochstreifen
In den Jahren 1936 bis 1941 entwarf Konrad Zuse die Rechner Z1 und Z3, die lange Befehlsfolgen auf einem Lochstreifen verarbeiteten, die ersten Computerprogramme, die auf realen Maschinen ausgeführt werden konnten. Die Rechner beherrschten die vier Grundrechenarten und Quadratwurzelberechnungen auf binären Gleitkommazahlen, der Lochstreifen enthielt jeweils eine Rechenoperation und eine Speicheradresse.
Auf Zuse geht auch die erste höhere Programmiersprache, Plankalkül, zurück. Damit lassen sich Probleme maschinenunabhängig formulieren und später in eine maschinenlesbare Form überführen.
Programme im Arbeitsspeicher
Der EDVAC-Rechner, der auf einem Entwurf von John von Neumann aus dem Jahre 1945 basiert, hatte einen Quecksilber-Verzögerungsspeicher für 1024 Fest- oder Gleitkommazahlen mit jeweils 44 Bits. Jede Speicherzelle konnte statt einer Zahl auch einen Befehl aufnehmen. Bei diesem Rechnerkonzept war es möglich, die Befehle eines Computerprogramms vor der Ausführung erstmals in den Arbeitsspeicher zu übertragen. Dies ist noch heute üblich. EDVAC wurde jedoch erst im Jahre 1951 teilweise fertiggestellt. Der Demonstrationsrechner Manchester SSE und der auf dem EDVAC aufbauende EDSAC-Rechner hatten schon vorher Programme aus dem Arbeitsspeicher ausgegeführt.
Höhere Programmiersprachen und Compiler
Ende der 1950er Jahre wurden Computer so leistungsfähig, dass spezielle Programme, Compiler, Quelltexte (englisch: Sourcecode) in höheren Programmiersprachen automatisch in Maschinenbefehle, also ausführbare Programme, übersetzen konnten. Ausführbare Programme können dann, wie beim EDVAC, in den Speicher geladen und abgearbeitet werden.
Mit Fortran, COBOL, ALGOL und LISP entstanden in den späten 1950er Jahren die ersten standardisierten höheren Programmiersprachen. Programme in diesen Sprachen laufen durch einen entsprechenden Compiler übersetzt auf unterschiedlichen Rechnern. Sie können teilweise auch noch auf modernen Computern eingesetzt werden.
Vom Algorithmus zum Programm
Berechnung des größten gemeinsamen Teilers
Es soll ein Programm zur Bestimmung des größten gemeinsamen Teilers (ggT) zweier Zahlen erstellt werden. Zunächst muss ein geeigneter Algorithmus gefunden werden.
Der euklidische Algorithmus, der bereits um 300 v. Chr. beschrieben wurde, ermittelt den größten gemeinsamen Teilers (ggT) zweier natürlicher Zahlen A und B:
# Sei A die größere der beiden Zahlen A und B (gegenenfalls vertauschen).
# Setze A = A – B.
# Wenn A und B ungleich sind, dann mit Schritt 1 fortfahren, wenn sie gleich sind, dann den Algorithmus beenden: Diese Zahl ist der größte gemeinsame Teiler.
Verwendung einer Programmiersprache
Sobald eine formale Beschreibung eines Algorithmus, also eine genau definierte Verarbeitungsvorschrift, vorliegt, kann der Algorithmus umgesetzt (implementiert) werden. Dazu wird eine geeignete Programmiersprache ausgewählt.
Zur Umsetzung wird heute meist eine höhere Programmiersprache verwendet, die von einem Computer eventuell nicht direkt ausgeführt werden kann, sondern zuerst compiliert oder interpretiert werden muss. In Sprachen wie Pascal dienen Variablen, Ausdrücke, Vergleiche, Zuweisungen und Kontrollstrukturen zur Umsetzung des ggT-Algorithmus:
( - Schritt3: - )
WHILE A <> B DO BEGIN ( - Solange A ungleich B - )
( - Schritt1: - )
IF B > A THEN BEGIN ( - Falls B größer als A - )
H = A; A = B; B = H; ( - A und B vertauschen - )
END; ( - Schritt2: - )
A = A-B; ( - A durch A-B ersetzen - )
END;
Berücksichtigung aller Sonderfälle
Bei der Umsetzung wird mit der Prüfung von Schritt 3 begonnen. Der ursprüngliche Algorithmus berücksichtigt nicht den Fall, dass A und B bereits zu Beginn gleich sein können. Wäre die Aufgabe, den größten Teiler von 103 und 103 zu finden, würde ein Mensch sofort das Ergebnis 103 nennen, er würde den Algorithmus gar nicht bemühen. Der originale Algorithmus würde aber null ergeben. Die Umsetzung auf einem Rechner muss auch alle Sonderfälle berücksichtigen. Durch das Vorziehen von Schritt 3 wird der Sonderfall hier korrekt behandelt.
Elementare Schritte
Pascal und andere Programmiersprachen besitzen keine Operation zum Vertauschen von Zahlen. Dies muss daher in elementarere Schritte umgesetzt werden. Eine zusätzliche Variable H, eine so genannte Hilfsvariable, erlaubt die Vertauschung mit Hilfe von drei Zuweisungen:
H := A; ( - Wert von A in der Hilfsvariablen H retten - )
A := B; ( - A mit dem Wert von B überschreiben - )
B := H; ( - B mit dem Wert von H (=A) überschreiben - )
Dies ist auch ein kleiner Algorithmus.
Ein vollständiges Programm
Damit hieraus ein korrektes Programm wird, muss der Algorithmus noch um Ein- bzw. Ausgabeanweisungen, oft jedoch auch um Variablen und eine Programmstruktur ergänzt werden. Diese sind nicht Teil des eigentlichen Algorithmus:
PROGRAM Ggt(Input,Output); ( - Programmkopf - )
VAR A,B,H: Integer; ( - Variablendefinition - )
BEGIN
ReadLn(A,B); ( - Eingabe von A und B - )
WHILE A <> B DO BEGIN ( - Euklidischer - )
IF B > A THEN BEGIN ( - Algorithmus - )
H := A; A := B; B := H;
END;
A := A-B;
END;
WriteLn(A); ( - Ausgabe von A - )
END. ( - Programmende - )
Übersetzung und Ausführung
Erst dieses Programm kann mit einem Texteditor in eine Datei geschrieben werden, die dann übersetzt und ausgeführt werden kann. Hierzu ist ein Compiler erforderlich, der den Code in der Programmiersprache in Maschinensprache übersetzt und das Ergebnis in eine ausführbare Datei schreibt. Diese kann dann über ein Betriebssystem gestartet werden. Das Programm muss dabei nur einmal übersetzt werden. Es kann danach beliebig oft gestartet werden. (Siehe auch Kompilierung).
Einige Programmiersprachen benötigen keinen Compiler, aber statt dessen einen Interpreter, der Programme ohne vorherige Übersetzung ausführen kann. Der Interpreter selbst ist dann ein ausführbares Programm in Maschinensprache.
Eine weitere Möglichkeit besteht in der Verwendung von Zwischencode (Bytecode), der vom Compiler an Stelle des Maschinencodes generiert wird. Ein Beispiel dafür ist Java: Der Java-Compiler erzeugt Bytecode, welcher dann auf der sogenannten Virtuellen Maschine ausgeführt wird. Die Virtuelle Maschine interpretiert oder übersetzt dann den Bytecode für das darunterliegende Betriebssystem.
Mittels spezieller Programme, so genannter Decompiler, ist es möglich, aus dem Maschinencode wieder einen in Hochsprache lesbaren Quelltext zu erzeugen.
Siehe auch
- Software
- Anwendungsprogramm
- Dienstprogramm
- Betriebssystem
Literatur
- John von Neumann: [http://www.virtualtravelog.net/entries/2003-08-TheFirstDraft.pdf First Draft of a Report on the EDVAC] 1945
Kategorie:Programmierung
ja:プログラム
th:โปรแกรม
ProgrammiersprachenEine Programmiersprache ist eine künstlich geschaffene Sprache (formale Sprache) zur Darstellung von Berechnungen. Programmiersprachen sollen Berechnungen sowohl in einer für einen Computer, als auch in einer für den Menschen lesbaren und verständlichen Form ausdrücken. Sie sind notwendig, da die natürlichen Sprachen für eine genügend detaillierte und präzise Beschreibung von Computerberechnungen zu vieldeutig sind.
Die durch eine Programmiersprache ausgedrückte, von einem Menschen lesbare Beschreibung heißt Quelltext (Beispiel "Hallo Welt!"). Den Arbeitsprozess diese Computerprogramme zu erstellen, nennt man Programmieren. Er wird durch Programmierer vorgenommen. Der entstandene Programmcode muss schließlich in eine Anweisungsfolge für den Computer, die Maschinensprache übersetzt werden. Dies ist vergleichbar mit dem Übersetzen von natürlichen Sprachen, jedoch ist dieser Arbeitsschritt durch die Verwendung von Programmiersprachen mittels eines Übersetzungsprogramms automatisierbar. Das Endprodukt dieser Übersetzung nennt man Computerprogramm. Je nachdem, ob diese Übersetzung vor oder während der Ausführung des Computerprogramms erfolgt, unterscheidet man zwischen kompilierenden oder interpretierenden Übersetzungsprogrammen.
Es existieren verschiedene Meinungen, welche Eigenschaften eine Programmiersprache besitzen sollte. Allgemein wird jedoch akzeptiert, dass zumindest die grundlegende mathematische Arithmetik ausgedrückt werden können sollte. Oft erscheint der von der Programmiersprache vorgegebene Programmierstil und die Zweckgebundenheit der Programmiersprache wichtig. Eine theoretische Erkenntnis ist die notwendige Eigenschaft der Turing-Vollständigkeit, falls sie die volle Funktionalität des Computers ausnutzen soll; dies kann bis hin zum sich selbst verändernden Programm dienen.
Form und Funktion
Programmiersprachen dienen der Informationsverarbeitung und richten sich deshalb in Form und Funktion als Sprache an die Struktur und Bedeutung von Information. Die genauere linguistische Betrachtung dieser Aspekte ist Aufgabe der Semiotik.
Die äußere Form, in der sich eine Programmiersprache dem Programmierer repräsentiert, bezeichnet man als Syntax. Die meisten Programmiersprachen sind textbasiert. Der Quelltext besteht aus Wörtern und Trennzeichen, ganz ähnlich zu geschriebenen natürlichen Sprachen. Es sind jedoch auch andere Repräsentationen von Programmiersprachen denkbar. So werden häufig zur Gestaltung von graphischen Benutzerschnittstellen visuelle Symbole verwendet. Ähnlich zu einem Notenblatt in der Musik ergibt sich aus den einzelnen Symbolen mit ihren individuellen Bedeutungen ein Dokument, das eine Gesamtheit beschreibt.
Die Bedeutung eines speziellen Symbols in einer Programmiersprache nennt man dessen Semantik. Syntax und Semantik kann man der Spezifikation, teilweise auch der Dokumentation der Programmiersprache entnehmen.
Die syntaktische Definition einer Sprache wird meist in der formalen Notation Backus-Naur-Form angegeben. Eine vollständig formal semantische Spezifikation einer Programmiersprache in einem einzigen Kalkül ist gegenwärtig Forschungsgegenstand.
Die Intention des Programmierers über die Gesamtheit des Computerprogramms nennt man Pragmatik. Mit dem Analogon des Notenblatts beschrieben, beabsichtigte der Kompositeur beispielsweise eine Hymne oder einen Popsong zu schaffen. Die Softwaretechnik hilft dabei dem Programmierer diesen Zweck eines Computerprogramms zu realisieren.
Imperative Programmiersprachen
Die derzeit am häufigsten verwendeten, imperativen Programmiersprachen halten eine spezielle Unterscheidung in Form und Funktion für Befehle (oft auch Anweisungen genannt) und Daten und deren Wiederverwendung bereit. Dieser Programmieransatz ist nicht unbedingt notwendig, da ein Computer diese Strukturen prinzipiell nicht unterscheiden kann, hat sich jedoch historisch durchgesetzt.
Befehle
Ein Computer ist keine starre, nur auf eine Aufgabe spezialisierte Rechenmaschine. Vielmehr wird durch Einzelaktion in Mikroebene angegeben, wie der Computer mit welchen Daten zu verfahren hat. Imperative Programmiersprachen bilden dieses Konzept auf Makroebene durch Befehle ab. Durch die Reihenfolge der Befehle ist die zeitliche Abfolge vorgegeben. Um reagierende Programme schreiben zu können, gibt es Sprungbefehle, die die Abfolge der Befehle dynamisch verändern.
Befehle lassen sich semantisch nach dem EVA-Prinzip einteilen.
- Eingabe- oder Ausgabebefehle lesen Daten von der Tastatur, von einer Datei oder aus anderen Quellen ein oder sie geben sie auf den Monitor, auf einen Drucker oder in eine Datei aus.
- Berechnungen verändern Daten oder sie kombinieren Daten neu. Dies können auch mathematische Berechnungen, wie Addition oder Multiplikation sein.
- Kontrollstrukturen entscheiden aufgrund der vorliegenden Daten, welche Befehle als nächstes ausgeführt werden. Insbesondere kann eine Befehlsfolge wiederholt werden.
Daten
Als Daten werden im Allgemeinen alle im Rechner kodierten Zeichen bezeichnet, die keine Befehle darstellen und eine Bedeutung besitzen. Auch der Aufbau der Daten folgt syntaktischen Regeln. Mit so genannten Variablen kann man bequem auf die Daten zugreifen. Um die Zeichenketten der Daten mit ihrer (semantischen) Bedeutung nutzen zu können, muss man diese Bedeutung durch die Angabe eines Datentyps angeben. Zumeist besteht im Rahmen des Typsystems auch die Möglichkeit neue Typen zu vereinbaren.
Deklarative Programmiersprachen
Einen zu den imperativen Programmiersprachen konträren Ansatz verfolgen die deklarativen Programmiersprachen. Dabei beschreibt der Programmierer, welche Bedingungen ein Programm erfüllen muss. Wie etwas zu geschehen hat, ist Aufgabe des Übersetzungsprogramms. Oder anders gesagt: Der Programmierer gibt an, welches Ergebnis gewünscht ist. Die Problemlösung wird dem Computer überlassen.
Die Art der formulierten Bedingungen unterteilen die deklarativen Programmiersprachen in logische Programmiersprachen, die mathematische Logik benutzen und funktionale Programmiersprachen, die dafür mathematische Funktionen einsetzen. Deklarative Programmiersprachen haben keine große Popularität und sind oftmals im akademischen Bereich zu finden.
Geschichte
mathematische Funktion und gilt als "Grandma COBOL"]]
In den 1950er Jahren des letzten Jahrhunderts wurden in den USA die ersten drei weiter verbreiteten, praktisch eingesetzten höheren Programmiersprachen entwickelt. Dabei verfolgten dieses sowohl imperative als auch deklarativ-funktionale Ansätze.
Die Entwicklung von Algol 60 läutete eine fruchtbare Phase vieler neuer Konzepte, wie das der prozedurale Programmierung ein. Der Bedarf an neuen Programmiersprachen wurde durch den schnellen Fortschritt der Computertechnik gesteigert. In dieser Phase entstanden die bis heute populärsten Programmiersprachen: BASIC und C.
In der Nachfolgezeit ab 1980 konnten sich die neu entwickelten logischen Programmiersprachen nicht gegen die Weiterentwicklung traditioneller Konzepte in Form des objektorientierten Programmierens durchsetzen. Das in den 1990er Jahren immer schneller wachsende Internet forderte seinen Tribut beispielsweise in Form von neuen Skriptsprachen für die Entwicklung von Webserver-Anwendungen.
Derzeit schreitet die Integration der Konzepte der letzten Jahrzehnte voran. Größere Beachtung findet so beispielsweise der Aspekt der Codesicherheit in Form von virtuellen Maschinen.
Hauptartikel: Geschichte der Programmiersprachen
Klassifizierungen
Programmiersprachen lassen sich in verschiedener Hinsicht klassifizieren. Häufig ist die Unterteilung nach Programmierparadigmen, nach Sprachgenerationen oder Anwendungsgebieten.
Anwendungsgebiete
- Assemblersprachen erlauben eine hardwarenahe Programmierung.
- CNC-Programmiersprachen dienen der Erzeugung von Steuerungsinformationen für Werkzeugmaschinen.
- Datenbanksprachen sind für den Einsatz in und die Abfrage von Datenbanken gedacht.
- Skriptsprachen dienen zur einfachen Steuerung von Rechnern, wie bei der Stapelverarbeitung.
- Visuelle Programmiersprachen erleichtern die graphische Gestaltung von Benutzeroberflächen.
- Esoterische Programmiersprachen sind als anspruchsvolle Scherze gedacht.
Programmierparadigmen
Ein Programmierparadigma ist das einer Programmiersprache zugrundeliegende Prinzip. Grundlegend sind die Paradigmen der imperativen und der deklarativen Programmierung. Alle weiteren Paradigmen sind Verfeinerungen dieser Prinzipien. Eine Programmiersprache kann mehreren Paradigmen gehorchen.
Hauptartikel: Programmierparadigma
Sprachgenerationen
Programmiersprachen werden in verschiedene Generationen eingeteilt, um damit zum einen die geschichtliche Entwicklung nachzuzeichnen. Andererseits ist dies ein Ansatz, die Sprachgenerationen als semantische Level zu verstehen. Damit wird der Abstraktionsgrad von der zugrunde liegenden Technik mit jeder Generation erhöht. Die 1. Generation erfordert damit genaueste Kenntnis über die Funktionsweise der zu programmierenden Maschine, während in den höheren Generationen die Beschreibung des Problems wichtiger wird. Wie es letztlich zu lösen ist, soll in den Verantwortungsbereich des Rechners überführt werden.
1. Generation: Maschinensprache sind die direkt auf einem Prozessor ausführbaren binäre Zahlencodes, die die Befehle darstellen. Die Eingabe erfolgt direkt in binärer 0-1-Form. Die direkte Programmierung in einer Maschinensprache wird heute kaum noch verwendet.
:Beispiel: Es soll die Addition „3 + 4“ durchgeführt werden. Der Prozessor hat für die Operation „addiere“ den festgelegten Code 00011010. 0011 und 0100 ist die Codierung der Operanden 3 und 4 im Dualsystem. Damit weist die folgende Folge in Maschinensprache den Rechner an, die Addition auszuführen: 00011010 0011 0100.
2. Generation: Assembler ersetzen die Zahlencodes der Maschinensprache durch symbolische Bezeichner (Mnemonics). Eine Assembleranweisung wird in genau einen Maschinenbefehl umgesetzt. Der Anteil der Assemblerprogrammierung ist sehr gering.
:Beispiel: Es soll die Addition „3 + 4“ durchgeführt werden. Der für den Prozessor geeignete Assembler hat den Bezeicher ADD für die Operation „addiere“ festgelegt. R0 und R1 sind die Speicherzellen in der die Operanden 3 und 4 stehen. Damit weist der folgende Befehl im Assembler den Rechner an, die Addition auszuführen: ADD R0 R1.
3. Generation: Höhere Programmiersprachen (High Level Languages) führen Konzepte, wie Variablen ein, um leichter verständlichen Quelltext schreiben zu können. Sprachen der 3. Generation sind weitgehend maschinenunabhängig. Die meisten praktisch eingesetzten Programmiersprachen sind höhere Programmiersprachen.
:Beispiel: Es soll die Addition „3 + 4“ durchgeführt werden. In der höheren Programmiersprache C wird direkt die mathematische Arithmetik für die Operation „addiere“ unterstützt. Es ist dafür eine Variable Summe vom Datentyp int nötig. Damit weist der folgende Programmcode in C den Rechner an, die Addition auszuführen: int Summe; Summe = 3 + 4.
Objektorientierte Sprachen sind ebenfalls Sprachen der 3. Generation. Um jedoch ihre konzeptionelle Sonderrolle zu betonen, werden sie in der Literatur oft als „OO-Generation“ bezeichnet.
4. Generation: Viertgenerationssprachen bieten einfache Sprachmittel zur Auslösung komplexer Operationen. Zumeist sind sie dabei an eine bestimmte Anwendung gebunden.
:Beispiel: Es sollen aus einer Datensammlung alle Kundendaten herausgefunden werden. Falls die Daten in einer geeigneten Datenbankanwendung erfasst sind, kann mit der Sprache SQL die Aktion folgendermaßen erreicht werden: SELECT kunden FROM datenbank. Dasselbe Ergebnis ist mit einer Hochsprache nur durch eine Beschreibung von Einzelaktionen (Öffnen von Dateien etc.) zu erzielen.
5. Generation: (Very High Level Language, VHLL)
Sprachen der 5.Generation gestatten das Beschreiben von Sachverhalten und Problemen. Sie kommen vor allem im Bereich der KI (künstliche Intelligenz) zum Einsatz. Die Wahl des Problemlösungsweges kann (entsprechend dem Sprachkonzept) dem jeweiligen System (weitgehend) überlassen werden. Bekanntestes Beispiel für eine Sprache der 5. Generation ist PROLOG.
Siehe auch
- Liste der Programmiersprachen
- Programmierstil
Literatur
- Kenneth C. Louden: Programmiersprachen: Grundlagen, Konzepte, Entwurf. Internat. Thomson Publ., Bonn, Albany [u.a.] 1994, ISBN 3-929821-03-6
Weblinks
- [http://www.99-bottles-of-beer.net 99 Bottles of Beer]: Ein Programm in 854 Programmiersprachen bzw. Dialekten (Stand: 21. November 2005)
- [http://lambda-the-ultimate.org Lambda the Ultimate] Das Blog zum Thema Programmiersprachen (englisch)
Kategorie:Compilerbau
ja:プログラミング言語
C (Programmiersprache)Die Programmiersprache C wurde von Ken Thompson und Dennis Ritchie in den frühen 70er 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 Laboratories, in denen 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 Sprache C++ ist aus C hervorgegangen und gegenüber C unter anderem um Möglichkeiten zur objektorientierten und generischen Programmierung erweitert.
Überblick
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 Implementierungen auf den verschiedenen Plattformen. In jedem C-System mit Laufzeitumgebung steht auch die genormte Standard C Library zur Verfügung. Dies und die bei geschickter Programmierung hohe Leistung der resultierenden Programme erklärt die weiterhin relativ hohe Popularität der Sprache, sowohl im kommerziellen als auch im Open-Source-Bereich, obwohl
C von seinen Entwicklern mit mehr Rücksicht auf Compilerhersteller als
auf Programmierer konzipiert wurde. Anders als PASCAL wurde mehr Wert
auf Typensicherheit und effiziente Kompilierbarkeit gelegt als darauf, den
Programmierer zu einem guten Stil anzuhalten.
Es gibt Meinungen, C entspreche nicht dem heutigen Stand der Technik; manchmal wird C auch als portierbarer Highlevel-Assembler bezeichnet. Die Kerne fast aller heute verbreiteten Betriebssysteme wurden aber in C implementiert, und dies, obwohl C++ bereits seit Mitte der 80er Jahre zur Verfügung steht, wenn auch in der jetzigen, ISO-genormten Form erst seit 1998.
C eignet sich gut für die Systemprogrammierung. Anders sieht die Sache jedoch bei der Anwendungsentwicklung aus. Dort wird C zunehmend durch die Sprachen C++, Java und C# verdrängt, die gemeinsam haben, dass sie alle über Möglichkeiten zur objektorientierten Programmierung verfügen und C im Bezug auf Wartbarkeit, Entwurfsunterstützung und Abstraktionsniveau erweitern und verbessern.
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 Prozessorplattform ist verglichen mit anderen Sprachen wenig aufwändig, so dass sich dies vom einfachsten Mikrocontroller bis zum Großrechner-Prozessor praktisch immer lohnt. Der GNU C-Compiler gcc ist beispielsweise für eine Vielzahl unterschiedlichster Prozessoren und Betriebssysteme verfügbar. Für den Entwickler bedeutet dies, dass unabhängig von der Zielplattform fast immer auch ein C-Compiler für diese spezifische Plattform existiert. Die prozessorspezifische Programmierung in Assembler bleibt ihm dadurch ganz oder weitgehend erspart, und Quellcode, der für andere Plattformen geschrieben wurde, kann oftmals mit keinen oder nur wenigen Änderungen auf einer neuen Plattform weiterverwendet werden.
Geschichte
Die Sprachbeschreibung wurde 1972 erstmals publiziert. Im Jahre 1989 wurde die Sprache erstmals standardisiert (C89). Dieser Standard wurde überarbeitet und 1999 erschien dann der internationale Standard ISO/IEC 9899:1999, der als C99 bekannt ist.
Hauptartikel: Varianten der Programmiersprache C
Sprachdesign
Ein ausführbares C-Programm wird durch den so genannten Linker oder Binder aus Objektcode erzeugt (gebunden). Dabei können mehrere Objektcodedateien zu einem Programm zusammengefasst werden. Die Objektcodedateien ihrerseits werden durch den Compiler aus Textdateien erzeugt (übersetzt), die eine Anzahl Funktions- und Variablendefinitionen enthalten. Neben Programmen kann man aber auch noch Bibliotheken erstellen. Diese werden ähnlich wie Programme gebunden oder in ein Archiv zusammengefasst. Diese Bibliotheken können dann in einem späteren Bindevorgang wiederum zu einem Programm hinzugebunden werden. Auf diese Weise kann man verhindern, dass für jedes zu erzeugende Programm unzählige (in größeren Systemen durchaus hunderte bis tausende) unveränderliche Objektcodedateien immer wieder erneut gebunden werden müssen.
Das Design der Programmiersprache, die Technik des Linkens und verschiedene zu festen Sprachelementen gewordene Funktionen und Festlegungen sind eng mit dem Design unixartiger Betriebssysteme verbunden, so die Art und Weise der Signalbearbeitung, der Ein- und Ausgabe mit Streams, und das Verfahren des Startens und Beendens eines Programms.
Der folgende Quelltext stellt ein einfaches C-Programm dar, das die Meldung Hallo Welt! und einen Zeilenumbruch auf der Standardausgabe ausgibt.
#include
int main (void)
Erläuterung: In der ersten Zeile wird durch #include <stdio.h> die Verwendung der Ein-/Ausgabe-Bibliothek stdio und damit der Funktion printf ermöglicht. stdio.h ist eine so genannte Headerdatei. Sie enthält u.a. den Prototyp von printf und wird durch den Präprozessor eingefügt. Danach kann der Compiler Aufrufe für printf generieren, ohne ihren tatsächlichen Code zu kennen, der erst beim Linken geliefert wird. Dies gilt für die überwiegende Mehrheit aller C-Systeme.
In der dritten Zeile (die zweite ist eine Leerzeile, von der beliebig viele existieren können) beginnt der eigentliche Programmablauf mit dem Aufruf der Funktion main. Sie ist die Hauptfunktion eines C-Programmes und in diesem kleinen Programm sogar die einzige. main wird immer als erste Funktion aufgerufen und hat wie alle Funktionen einen Anfang (die öffnende geschweifte Klammer) und ein Ende (die schließende geschweifte Klammer).
Die erste Anweisung in der Funktion main ist eine Ausdrucksanweisung welche die Funktion printf aufruft. Diese Funktion ist nicht Teil des Sprachkerns, sondern der Standardbibliothek. Daher muss sie (gemäß C99) vor ihrer Verwendung deklariert werden. Dies geschieht durch die Präprozessordirektive #include <stdio.h>, die in der ersten Zeile angegeben wurde. Die Funktionen der Standardbibliothek werden in aller Regel durch eine Bibliothek mit Hilfe eines Linkers an das Programm gebunden, jedoch kann ein Compiler auch auf einem anderen Weg die Funktion printf zur Verfügung stellen.
Die zweite Anweisung ist die Sprung-Anweisung return 0;. Die return-Anweisung ist Teil des Sprachkerns. Für sie ist ein Header (#include...), wie dies bei printf der Fall war, nicht nötig. Der Rückgabewert 0 soll von dem Aufrufer des Programms als fehlerfreie Ausführung interpretiert werden.
Man kann der Funktion main beim Aufruf Werte übergeben, die dann zwischen den runden Klammern angegeben werden. Man spricht dabei auch von Parameterliste. Wird void zwischen den Klammern angegeben, so ist dies gleichbedeutend mit keine Parameter. Fügt man hingegen den Text int argc, char - argv[] in die Parameterliste ein, lässt sich während des Programmablaufs mittels der Ganzzahlvariable argc die Anzahl der beim Programmstart übergebenen Argumente abfragen:
int main (int argc, char - argv[])
Ein Zugriff auf die Zeichenketten-Reihung argv[] ermöglicht die Abfrage des n-ten Arguments, wobei hierzu eine Ganzzahl zwischen 0 und n-1 in die eckigen Klammern von argv[] einzusetzen ist. Nach der Abarbeitung erhält man von der Funktion main einen Wert zurück. Dieser Wert ist vom Typ int. Typ int bedeutet, dass eine vorzeichenbehaftete Ganzzahl zurückgeliefert wird.
Programmieren in C
Die Programmierung mit der Sprache C kann nach vier Kriterien unterteilt werden:
- Der erste Betrachtungspunkt ist die Sprache selbst. Also der Kern der Sprache, der vom Compiler direkt verstanden wird. Der Sprachkern wird in dem Kapitel zur Beschreibung der Sprache genauer erklärt werden.
- Die Bibliotheksfunktionen, die in jedem ("hosted") C-Compiler zur Verfügung stehen, solange der Compiler den Anspruch hat, ANSI-kompatibel zu sein. Verwendet ein Programm lediglich den Sprachkern gemäß der Sprachdefinition und die Standardbibliothek, so ist es auf jedem System, das einen ANSI-kompatiblen Compiler zur Verfügung stellt, übersetzbar und zeigt auch auf allen Systemen das gleiche Verhalten.
- Die Bibliotheksfunktionen, die von dem (Betriebs-)System zur Verfügung gestellt werden. Diese Bibliotheken stammen also nicht von einem ANSI-kompatiblen Compiler. Daher sind Programme, die diese Bibliotheken verwenden, nur bedingt portabel. Ein Teil dieser Bibliotheken wird in dem Kapitel Weitere C-Bibliotheken beschrieben.
- Die Erweiterungen des Sprachkerns, die von einem Compiler zur Verfügung gestellt werden. Diese Erweiterungen betreffen die Werkzeuge.
Beschreibung der Sprache
Die Beschreibung der Sprache bezieht sich auf das Kapitel 6. Language in C99.
- Konzepte
- Geltungsbereich von Bezeichnern
- Bindung von Bezeichnern
- Speicherdauer von Objekten
- Typen
- lexikalische Elemente
- Schlüsselwörter
- Bezeichner
- Konstanten
- Kommentare
- Deklarationen / Definition
- Ausdrücke
- Anweisungen
- Der Präprozessor
Die Standardbibliothek
Die Standardbibliothek (Standard C Library) beschreibt die Makros und Funktionen, die jedem Compiler zur Verfügung steht.
Weitere C-Bibliotheken
Die nachfolgend beschriebenen Bibliotheken sind nicht Teil der Sprachbeschreibung von C.
Daher stehen sie nur zur Verfügung, wenn die API des Systems sie anbietet.
- POSIX - Programmierung einer UNIX-Umgebung
- pcre - Perl Compatible Regular Expressions
- Zugriff auf eine MySQL-Datenbank
Werkzeuge
- GNU C-Compiler
- GNU Debugger
Bewertung von Sprachmerkmalen
Stärken
- Minimalistischer Sprachumfang: Der kleinste bekannte C-Compiler besteht aus 3742 Bytes C-Code und kann sich selbst kompilieren.
- Keine Felder (ersetzt durch Feldkonstanten und Behandlung von Feldern als Zeigerkonstanten)
- Zeigerarithmetik ermöglicht die effiziente Behandlung von Feldzugriffen, Parametern usw.
- Zeiger auf Unterprogramme (Funktionszeiger) 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
- Präprozessor zur Spracherweiterung und bedingten Übersetzung
- Linker (Binder) (C war eine der ersten Sprachen, die das Einbinden von externen vorübersetzten Routinen in der Sprachdefinition berücksichtigt)
- Viele Optimierungen sind bei Übersetzung möglich
- Ein C-Compiler ist für nahezu jede Prozessorarchitektur vorhanden, seien es "historische" 8-Bit-Prozessoren und einfache Mikrocontroller oder aktuelle 64-Bit-Prozessoren.
Schwächen
- Fehlendes Modulkonzept (wird üblicherweise durch Paare von .c- und .h-Dateien notdürftig nachgebaut)
- Nur eingeschränkt typsicher
- Die Sprachdefinition besitzt Lücken (Verhalten undefiniert)
- Verglichen mit anderen prozeduralen Sprachen wie (das ältere!) Pascal oder Modula-2 zu wenig klare Syntax, was zu sehr komplexen und fehleranfälligen Compilern führt
- "Wilde" Zeiger
- Man kann Zeiger 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.
- 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 während der Laufzeit unabsichtlich oder gezielt (Pufferüberlauf) verändert werden.
- Mehrdimensionale Felder werden in der numerischen Mathematik für Matrizen benötigt. Dafür ist die Struktur der C-Felder jedoch völlig ungeeignet. In Numerical Recipes in C, Kap. 1.2, Seite 20 ff ([http://www.library.cornell.edu/nr/bookcpdf/c1-2.pdf online lesbar!]) wird dieses Problem diskutiert und die in diesem Buch verwendete Lösung erläutert. Natürlich ist es auch eine Stärke von C, dass eine derartige Schwäche überhaupt durch eine Lösung ausgeglichen werden kann, die darüberhinaus auch noch elegant ist.
- Zeichenketten
- C kennt Strings, die nach den Grundsätzen der 60er Jahre durchaus in ein Gesamtkonzept integriert sind. Sie werden als so genannte nullterminierte Strings in Variablen und Konstanten ("Hallo") gespeichert und durch ihre Adressen (Zeiger!) verwendet. Die große Schwäche dieses Konzepts liegt in der großen Programmiererverantwortung, denen reale Programmierer nicht immer gewachsen sind (wilde Zeiger, zu kleine Felder, vergessene Abschlussnull...)
- C hat keine integrierten Zeichenketten ("Strings"). Statt dessen wird ein Zeichenfeld verwendet, das mit einem Nullzeichen abgeschlossen wird. Die Speicherverwaltung von Zeichenketten muss vom Programmierer vorgenommen werden.
- Speicherverwaltung
- Der Programmierer muss den dynamischen Speicher selbst verwalten. Hierzu stehen Bibliotheksfunktionen zur Verfügung.
- niedriger Abstraktionsgrad
- 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, Ausrichtung (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.
- In der Sprachversion C99 sind Datentypen mit expliziten Bit-Längen definiert (int8_t, int16_t, etc.).
Zusammenfassung
Man kann sagen, dass die größte Stärke von C - die uneingeschränkte Freiheit des Programmierers im Umgang mit Zeigern und Speicherstrukturen - gleichzeitig ihre größte Schwäche ist: Was für die Programmierung von
Treibern und Betriebssystemen absolut notwendig ist, das ist für
die Programmierung gewöhnlicher Desktop-Anwendungen eher ein lästiges
Hindernis, wenn nicht sogar ein Sicherheitsrisiko.
Da der freizügige Umgang der Programmiersprache mit dem Speicher in kritischen Umgebungen (Kreditinstituten, Börsen, Versicherungen, Raumfahrt usw.) leicht hohe Schäden nach sich ziehen kann, wird hier mittlerweile ernsthaft erwogen, diese Programmiersprache bei neuen Projekten zu verbieten.
IRC
Einen IRC-Channel, wo man Hilfe bekommen kann, findet man zum Beispiel im IRCNet in #c (irc://random.ircd.de/C)
Literatur
- Brian W. Kernighan, Dennis Ritchie: Programmieren in C, Hanser Fachbuch, ISBN 3-446-15497-3
Weblinks
- [http://www.lysator.liu.se/c/ Programming in C]
- [http://cm.bell-labs.com/cm/cs/who/dmr/primevalC.html Abhandlung über die Urzeiten von C und Compilerversionen von 1972/73 (engl.)]
- [http://faul.dyndns.org/c/ Doku der GLibc, Doku der ANSI-C-Library, Tutorium... (engl.)]
ja:C言語
ko:C 프로그래밍 언어
ms:Bahasa pengaturcaraan C
th:ภาษาซี
C-Plusplus
C++ ist eine der verbreitetsten und industriell bedeutendsten Programmiersprachen. Sie ist als Mehrzwecksprache konzipiert und unterstützt insbesondere effiziente und maschinennahe Programmierung, Datenabstraktion sowie objektorientierte und generische Programmierung.
C++ basiert auf der Programmiersprache C wie in ISO/IEC 9899:1990 beschrieben. Zusätzlich zu den in C vorhandenen Möglichkeiten bietet C++ weitere Datentypen, Klassen mit Vererbung und virtuellen Funktionen, Ausnahmebehandlung, Templates (Schablonen), Namensräume, Inline-Funktionen, Überladen von Operatoren und Funktionsnamen, Referenzen, Operatoren zur Freispeicherverwaltung und mit der C++-Standardbibliothek eine erweiterte Bibliothek.
Entstehungsgeschichte
C++ wurde von Bjarne Stroustrup ab 1979 bei AT&T entwickelt. Die Idee für eine neue Programmiersprache entwickelte er aus den Erfahrungen mit der Programmiersprache Simula im Rahmen seiner Promotion. Stroustrup erschien Simula zwar geeignet für den Einsatz in großen Software-Projekten, die Struktur der Sprache erschwerte aber die für viele praktische Anwendungen erforderliche Erzeugung hocheffizienter Programme. Effiziente Programme ließen sich zwar mit der Sprache BCPL schreiben, für große Projekte war BCPL aber wiederum ungeeignet.
Als Stroustrup in den Bell-Laboratorien zu arbeiten begann, sah er sich mit dem Problem konfrontiert, den UNIX-Betriebssystemkern im Hinblick auf verteilte Programmierung analysieren zu müssen. Mit den Erfahrungen aus seiner Promotion machte er sich daran, die Programmiersprache C um ein Klassenkonzept zu erweitern, für das die Sprache Simula-67 das primäre Vorbild war.
Die Wahl fiel auf die Programmiersprache C, weil C eine Mehrzwecksprache war, schnellen Code produzierte und einfach auf andere Plattformen zu portieren war. Als dem Betriebssystem UNIX beiliegende Sprache hatte C außerdem eine nicht unerhebliche Verbreitung. Zunächst fügte er der Sprache Klassen (mit Datenkapselung) hinzu, dann abgeleitete Klassen, ein strengeres Typsystem, Inline-Funktionen und Standard-Argumente.
Während Stroustrup „C mit Klassen“ („C with Classes“) entwickelte (woraus später C++ wurde), schrieb er auch Cfront, einen Compiler, der aus C mit Klassen zunächst C-Code als Zwischenresultat erzeugte. Die erste kommerzielle Version von Cfront erschien im Oktober 1985.
1982 wurde C mit Klassen in C++ umbenannt. Erweiterungen darin waren: virtuelle Funktionen, Überladen von Funktionsnamen und Operatoren, Referenzen, Konstanten, änderbare Freispeicherverwaltung und eine verbesserte Typüberprüfung. Die Möglichkeit von Kommentaren, die an das Zeilenende gebunden sind, wurde wieder aus BCPL übernommen (//).
1985 erschien die erste Version von C++, die eine wichtige Referenzversion darstellte, da die Sprache damals noch nicht standardisiert war. 1989 erschien die Version 2.0 von C++. Neu darin waren Mehrfachvererbung, abstrakte Klassen, statische Elementfunktionen, konstante Elementfunktionen und die Erweiterung des Schutzmodells um protected. 1990 erschien das Buch The Annotated C++ Reference Manual, das als Grundlage für den darauffolgenden Standardisierungsprozess diente.
Relativ spät wurden der Sprache Templates, Ausnahmen, Namensräume, neuartige Typumwandlungen und boolesche Typen hinzugefügt.
Im Zuge der Weiterentwicklung der Sprache C++ entstand auch eine gegenüber C erweiterte Standardbibliothek. Erste Ergänzung war die Stream-I/O-Bibliothek, die Ersatz für traditionelle C-Funktionen wie zum Beispiel printf und scanf bietet. Eine der wesentlichen Erweiterungen der Standardbibliothek kam später durch die Integration großer Teile der bei HP entwickelten Standard Template Library (STL) hinzu.
Nach jahrelanger Arbeit wurde schließlich 1998 von der ISO die endgültige Fassung der Sprache C++ (ISO/IEC 14882:1998) genormt.
2003 wurde die erste überarbeitete Version von ISO/IEC 14882:1998 verabschiedet (ISO/IEC 14882:2003). Diese Revision ist lediglich eine Nachbesserung der Norm ISO/IEC 14882:1998 und sollte nicht mit der in Arbeit befindlichen Version verwechselt werden. Die nächste Version der Sprache C++ erscheint voraussichtlich noch in dieser Dekade. (s. in der Entwicklung befindliche Version)
Merkmale
C++ unterstützt die folgenden Programmiertechniken:
- Prozedurale Programmierung
- Modulare Programmierung
- Strukturierte Programmierung
- Programmierung mit selbstdefinierten Datentypen (abstrakte Datentypen)
- Objektorientierte Programmierung (siehe auch Polymorphie (Vielgestaltigkeit))
- Generische Programmierung mittels Templates.
C++ ist somit eine so genannte „Multiparadigmen-Sprache“, die dem Programmierer sehr viele Freiheiten lässt (siehe Stärken und Schwächen).
Siehe auch: Programmierparadigma, Entwurfsmuster, RAII
Stärken und Schwächen
Stärken
- Die Erzeugung hocheffizienten Codes ist möglich.
- Sowohl maschinennahe als auch hochabstrakte Programmierung ist möglich.
- Sehr hohe Ausdrucksstärke und Flexibilität - Beispiel: die anpassbare Freispeicherverwaltung, in die sich etwa nahtlos eine automatische Speicherbereinigung (englisch garbage collector) integrieren lässt.
- Für große Projekte geeignet
- Weite Verbreitung
- Die Sprache ist nicht im Besitz einer Organisation (im Unterschied zu beispielsweise Java). Standardisierung durch die ISO
- Weitreichende Möglichkeiten für die Metaprogrammierung
- Kompatibilität mit C - Vorteil: Es steht eine breite Codebasis zur Verfügung.
Schwächen
- Kompatibilität mit C - Nachteil: historischer Ballast muss mitgeschleppt werden, zum Beispiel der von C übernommene Präprozessor, die teilweise unnötig schwer verständliche C-Syntax. Die Kompatibilität zu C hat u.a. zur Folge, dass einige Details der Sprache compilerspezifisch sind, die es aber nicht sein müssten. So ist beispielsweise die Auswertungsreihenfolge von Teilausdrücken je nach Compiler und Plattform unterschiedlich. Dies erschwert die Portierung von C++-Programmen zwischen Rechnertypen, Betriebssystemen und unterschiedlichen Compilern.
- Die aktuellen Compiler (Stand: 2005) sind rückständig bezüglich der Umsetzung der ISO-Norm.
- Die aktuellen Compiler produzieren nicht immer optimalen Code, sowohl in Bezug auf Geschwindigkeit als auch auf Code-Größe.
- Zum Erlernen sind verhältnismäßig lange Einarbeitungszeiten erforderlich.
- Die vorhandene C++-Standardbibliothek deckt viele wichtige Erfordernisse nicht ab, zum Beispiel Threads, TCP/IP, Dateisystem-Verzeichnisse. Deshalb besteht in diesen Bereichen eine eingeschränkte Portabilität über Betriebssystemgrenzen hinweg. Dies führte auch zur Entwicklung zahlreicher externer Bibliotheken (z.B. Boost), die ein teilweise unausgereiftes und uneinheitliches Bild von C++ vermitteln.
Der folgende Quelltext stellt ein einfaches C++-Programm dar, das eine Meldung auf dem Standardausgabemedium ausgibt:
#include
int main()
Erläuterungen:
Bei main handelt es sich um eine Funktion, genauer gesagt ist es die Hauptfunktion des gesamten Programmes. Die Funktion main ist in jedem C++-Programm vorhanden und wird nach dem Start des Programmes aufgerufen.
Die C++-ISO-Norm schreibt vor, dass das Ergebnis von main vom Typ int sein muss. Ein Programm, bei dem das Ergebnis von main nicht vom Typ int ist, ist kein gültiges Programm im Sinne der C++-ISO-Norm (ISO-14882).
Die Funktion main ist die einzige Funktion, die – obwohl sie einen Wert zurückgibt – nicht die Anweisung "return" benötigt. Ohne die explizite Anweisung return gibt main den Wert 0 zurück.
Verwandtschaft mit C
C++ ist eine Erweiterung der Programmiersprache C gemäß dem Stand von 1990 (ISO/IEC 9899:1990, auch kurz C90 genannt). C++ enthält C nach dem Stand C90 fast vollständig. Einige wenige C-Programme lassen sich zwar nicht ohne Weiteres als C++ kompilieren, beziehungsweise haben als C++-Programme eine etwas andere Bedeutung. Dabei handelt es sich aber um Sonderfälle, die in der Praxis keine große Rolle spielen.
Die Kompatibilität mit C war eines der Hauptdesignziele bei der Entwicklung der Programmiersprache C++. Grund dafür war die weite Verbreitung von C. Da C auch heute noch für praktisch jeden Prozessor verfügbar ist, und daher C die verbreitetste Programmiersprache darstellt, wird Kompatibilität mit C immer noch als eine der wichtigsten Eigenschaften von C++ angesehen.
Im Laufe der Entwicklung der beiden Sprachen gab es auch Rückwirkungen von C++ auf C. Beispielsweise wurden in C const sowie die Funktionsprototypen von C++ übernommen.
Die letzten Änderungen an C fanden 1999 statt (ISO/IEC 9899:1999). Gemäß dem Ratifizierungsjahr 1999 spricht man, wenn man sich auf diesen C-Stand bezieht, deshalb auch von C99. Ein Beispiel für darin eingeführte Spracherweiterungen sind die so genannten VLAs (engl. variable length array).
Aufgrund dieser Weiterentwicklung von C gibt es theoretisch mehr Inkompatibilitäten zwischen C und C++. Da es aber nicht viele C-Compiler gibt, die C99 unterstützen, hat dies keine große praktische Bedeutung. Bei der in Arbeit befindlichen C++-Version wird u. a. daran gearbeitet, die neuen C99-Merkmale miteinzuarbeiten. Einige C++-Compiler unterstützen C99-Neuerungen schon jetzt (z. B. der gcc).
Vergleich mit anderen Sprachen
Die Programmiersprachen Java und C# sind nicht mit C++ kompatibel. Sie haben zwar eine ähnliche Syntax wie C++, trotz dieser Ähnlichkeit unterscheiden sie sich aber in ihrer Semantik, also in dem, wofür die Syntaxelemente stehen, von C++ teilweise beträchtlich.
Ein wesentlicher Unterschied zwischen diesen Sprachen und C++ besteht darin, dass C++ über generische Sprachmerkmale (Templates) verfügt. Es gibt mitlerweile in Java und C# generische Typen jedoch geht die Entwicklung dort aber in eine etwas andere Richtung als bei C++.
Gerade die generische Programmierung macht aber C++ zu einem mächtigen Programmierwerkzeug. Während die objektorientierte Programmierung in Java und C# als der Gipfel der vorhandenen Abstraktionsmechanismen angesehen wird, ist diese Art der Programmierung in C++ rückläufig. So werden tiefe Klassenhierarchien vermieden. Zu Gunsten der Effizienz und der Minimierung des Ressourcenverbrauchs verzichtet man in vielen Fällen auf Polymorphie, dem Kernmechanismus der objektorientierten Programmierung. Auch in Punkto Wiederverwertbarkeit einmal kodierter Algorithmen übertreffen generische Techniken nach Meinung vieler Fachleute die objektorientierte Programmierung.
Siehe auch: Simula, Objective-C, Smalltalk, Eiffel
In der Entwicklung befindliche Version
C++0x (manchmal auch C++200x) ist eine inoffizielle Abkürzung für die in der Entwicklung befindliche Version der Programmiersprache C++. Zwar scheint der Name anzudeuten, dass dieser Standard bis spätestens 2009 fertig gestellt wird, es handelt sich aber lediglich um eine grobe Einschätzung des möglichen Erscheinungstermins.
C++-Compiler
Siehe auch: Kommandozeilen-Compiler, Visuelle Programmierumgebung
Siehe auch
- Boost
- C++-Glossar
- C++-Standardbibliothek
- Templates (Schablonen)
- C++-Metaprogrammierung (siehe auch Metaprogrammierung)
- C++/CLI.
- RAII (resource acquisition is initialization)
- Escape-Sequenz
- C (Programmiersprache)
Literatur
- Bjarne Stroustrup: Die C++-Programmiersprache, Addison-Wesley, ISBN 3-8273-1660-X, das Standardwerk zu C++, Grundkenntnisse in C von Vorteil.
- Andrew Koenig, Barbara E. Moo: Intensivkurs C++, Pearson Studium, ISBN 3-8273-7029-9, Anfängerbuch, ein gewisses Grundverständnis der Programmierung ist von Vorteil.
- Scott Meyers: Effektiv C++ programmieren - 50 Wege zur Verbesserung ihrer Programme und Entwürfe, Addison-Wesley, ISBN 3-8273-1305-8, zur Vertiefung bereits vorhandener C++-Kenntnisse.
- Scott Meyers: Mehr Effektiv C++ programmieren - 35 neue Wege zur Verbesserung ihrer Programme und Entwürfe, Addison-Wesley, ISBN 3-8273-1275-2, Vertiefung vorhandener C++-Kenntnisse.
- Herb Sutter: Exceptional C++, ISBN 3-8273-1711-8 (deutsch), Vertiefung vorhandener C++-Kenntnisse.
- Andrei Alexandrescu: Modernes C++ Design - Generische Programmierung und Entwurfsmuster angewendet, ISBN 3-8266-1347-3, ein Standardwerk zur C++-Metaprogrammierung, setzt ein tiefes Verständnis von C++ voraus.
Weblinks
- [http://www.cppreference.com/ C++ Online-Referenz], englisch
- [http://www.fmi.uni-konstanz.de/~kuehl/c++-faq/ Oft gestellte Fragen und Antworten], englisch
- [http://groups.google.de/groups?group=de.comp.lang.iso-c%2B%2B C++-Diskussionsgruppe], deutsch
- [http://www.c-plusplus.de/forum C++-Forum], deutsch
- [http://www.accu.org/ ACCU], internationale Interessengemeinschaft für C und C++
- [http://www.boost.org/ Die C++-Bibliothek] von Boost
- [http://www.hpl.hp.com/personal/Hans_Boehm/gc/ Hans Boehms Garbage-Collector für C++]
- [http://www.wikiservice.at/dse/wiki.cgi?SpracheCpp C++ im Deutschen Software Entwickler Wiki]
- [http://www.cuj.com/ C/C++ Users Journal]
- [http://www.open-std.org/jtc1/sc22/wg21/ Webauftritt des C++-Standardisierungskomitees]
- [http://atlas.web.cern.ch/Atlas/GROUPS/SOFTWARE/OO/tools/java/misc/ACritiqueOfC++.pdf Ian Joyner C++??]
ja:C Plus Plus
ko:C 플러스 플러스
simple:C plus plus
Java (Programmiersprache)
Java [] ist eine objektorientierte Programmiersprache und als solche ein eingetragenes Warenzeichen der Firma Sun Microsystems. Sie ist eine Komponente der Java-Technologie.
Java-Programme werden in einer speziellen Umgebung, der Java-Laufzeitumgebung oder Java-Plattform ausgeführt, deren wichtigster Bestandteil die Java Virtual Machine ist. Dazu werden Java-Programme in Bytecode übersetzt, der von der virtuellen Maschine ausgeführt wird.
Die Programme sind weitestgehend portabel, das heißt der übersetzte Bytecode läuft ohne Anpassungen auf verschiedenen Computern und Betriebssystemen, neben dem UNIX-Derivat Solaris der Firma Sun unter anderem auch unter Linux, Windows oder Mac OS X.
Grundkonzepte der Sprache
Der ursprüngliche Entwurf der Programmiersprache Java strebte im wesentlichen fünf Ziele an.
- Sie soll eine objektorientierte Programmiersprache sein.
- Sie soll es ermöglichen, das gleiche Programm auf unterschiedlichen Computersystemen auszuführen.
- Sie soll eingebaute Unterstützung für die Verwendung von Computernetzen enthalten.
- Sie soll Code aus entfernten Quellen sicher ausführen können. Dieser Punkt wird über das Sicherheitskonzept von Java erreicht, das aus drei Schichten besteht:
- # dem Code-Verifier (deutsch „Code-Überprüfer“), der sicherstellt, dass die VM keinen ungültigen Bytecode ausführen kann.
- # den Class-Loadern (deutsch „Klassenlader“), die die sichere Zuführung von Klasseninformationen zur JVM steuern (diese ist dabei kein Interpreter, siehe unten).
- # den Security-Managern (deutsch „Sicherheitsverwalter“), die sicher stellen, dass nur Zugriff auf Programmobjekte erlaubt wird, für die entsprechende Rechte vorhanden sind.
- Die erfolgreichen Aspekte bereits verbreiteter objektorientierter Programmiersprachen wie C++ sollen auch für Java-Programmierer zur Verfügung stehen.
Objektorientierung
Die Sprache Java gehört zu den objektorientierten Programmiersprachen. Die Grundidee der objektorientierten Programmierung ist die softwaretechnische Abbildung in einer Art und Weise, wie wir Menschen auch Dinge der realen Welt erfahren. Die Absicht dahinter ist, große Softwareprojekte einfacher verwalten zu können, und sowohl die Qualität von Software zu erhöhen als auch Fehler zu minimieren. Ein weiteres Ziel der Objektorientierung ist ein hoher Grad der Wiederverwendbarkeit von Softwaremodulen.
Ein neuer Aspekt von Java gegenüber den zuvor verbreitetsten objektorientierten Programmiersprachen C++ und Smalltalk ist die explizite Unterscheidung zwischen Schnittstellen und Klassen, die auch durch entsprechende Schlüsselwörter interface und class zur Geltung kommt.
Java ist nicht vollständig objektorientiert: Die Grunddatentypen (int, boolean usw.) und Literale sind keine Objekte (siehe auch unter Java-Syntax).
Reflection
Java bietet eine Reflection-API als Bestandteil der Laufzeitumgebung. Damit ist es möglich, zur Laufzeit auf Klassen und Methoden zuzugreifen, deren Existenz oder genaue Ausprägung zur Zeit der Programmerstellung nicht bekannt war.
Annotationen
Seit Java 5.0 gibt es eine Syntax-Erweiterung namens Annotationen. Sinn der Annotationen ist die automatische Erzeugung von Code und anderen in der Software-Entwicklung wichtigen Dateien für wiederkehrende Muster anhand möglichst kurzer Hinweise im Quelltext. Bislang wurden in Java dafür ausschließlich Javadoc-Kommentare mit speziellen JavaDoc-Tags verwendet, die von Doclets wie z. B. dem XDoclet ausgewertet wurden.
Diese Annotationen können auch in den kompilierten Class-Files enthalten sein, der Quelltext wird also für ihre Verwendung nicht benötigt. Insbesondere sind die Annotationen auch über die Reflection-API zugänglich. So können sie zum Beispiel zur Erweiterung des Bean-Konzeptes verwendet werden.
Write Once, Run Anywhere
Java funktioniert nach dem Konzept Write Once, Run Anywhere (deutsch: Schreibe einmal, laufe überall). Das bedeutet, dass man ein Programm, das in Java programmiert wurde, nur einmal zu kompilieren braucht und es auf allen anderen Systemen läuft, die eine Java-Laufzeitumgebung (Java Runtime Environment bzw. JRE) besitzen. Dies wird dadurch erreicht, dass Java zunächst in Bytecode kompiliert wird, dieser wird von der JRE beim Starten des Programmes erst in die Maschinensprache kompiliert (Man spricht hier von einem JIT-Compiler).
Der Bytecode funktioniert also als Zwischencode, zwischen Programmiersprache und Maschinensprache. So ist das Javaprogramm nicht an eine bestimmte Maschine gebunden. Die Java Runtime Environment existiert für weit verbreitete Betriebssysteme wie Microsoft Windows, Linux, Solaris, Mac OS X, AIX und viele andere. Daneben gibt es eine JRE nicht nur für Server- und Desktopbetriebssysteme, sondern auch für viele Embedded Systeme wie Mobiltelefone, PDAs, sowie Smartcards und andere technische Plattformen, wie Auto und TV. Die Plattformunabhängigkeit endet jedoch für solche Systeme, für die keine Java Virtual Machine existiert, zumeist ältere oder sehr exotische Systeme.
Es gibt aber auch Compiler, die Java direkt in Maschinencode übersetzen (Siehe Java: Native Compiler).
Fälschlicherweise wird oft behauptet, dass Java plattformunabhängig sei, dies ist jedoch nicht richtig, da Java von der Java-Plattform abhängt. Diese lässt sich eben nur auf verschiedene Architekturen und Betriebssysteme portieren.
Modulare Ausführung auf fernen Computern
Java bietet die Möglichkeit, Klassen zu schreiben, die in unbekannten Containern ablaufen. Beispielsweise lassen sich Applets in Webbrowsern, die Java unterstützen, ausführen. Das Sicherheitskonzept von Java kann dazu eingesetzt werden, dass unbekannte Klassen dabei keinen Schaden anrichten können, was vor allem bei Applets wichtig ist (siehe auch Sandbox). Beispiele für Java Container-Module sind Applets, Servlets, Portlets, Midlets, Translets, Doclets und Enterprise JavaBeans.
Merkmale der Sprache
Der Objektzugriff in Java ist über Referenzen genannte Zeiger implementiert; aus Sicherheitsgründen ist es nicht möglich, deren Speicheradresse zu modifizieren. So genannte Pointerarithmetik ist mit der Sprache also ausgeschlossen. Per Design können so häufig auftretende Fehler während des Entwicklungsprozesses von vornherein ausgeschlossen werden.
Um große Projekte strukturieren zu können und saubere Schnittstellen zu Bibliotheken zu schaffen, können die Klassen zu Paketen (englisch packages) zusammengefasst werden. Die Zugriffe auf Klassen und Methoden eines fremden Paketes können – ähnlich wie innerhalb einer Klasse unter anderem durch private und public – geregelt werden.
Weiter unterstützt die Sprache Threads (gleichzeitig ablaufende Programmteile) und Ausnahmen (englisch exception) und Java beinhaltet auch eine automatische Speicherbereinigung (englisch garbage collector), die nicht (mehr) referenzierte Objekte aus dem Speicher entfernt.
Bemerkenswert ist auch die explizite Unterscheidung von Schnittstellen und Klassen. Eine Klasse kann beliebig viele Schnittstellen implementieren, hat aber stets genau eine Basisklasse. Java unterstützt keine Mehrfachvererbung, da lediglich Schnittstellen, jedoch keine Klassen „mehrfach“ vererbt werden können. Funktionen (in der Java-Welt „Methoden“) werden nur von der Basisklasse übernommen.
Alle Klassen sind – direkt oder indirekt – von der Wurzelklasse Object abgeleitet.
Zu Java gehört eine umfangreiche Klassenbibliothek. Dem Programmierer wird damit eine einheitliche, vom zugrunde liegenden Betriebssystem unabhängige Schnittstelle (Application programming interface, API) angeboten.
Mit Java 1.1 wurden die Java Foundation Classes (JFC) eingeführt, die u. a. Swing bereitstellen, das zur Erzeugung plattformunabhängiger grafischer Benutzerschnittstellen (GUI) dient und auf AWT basiert.
Syntax
Ein Beispielprogramm, das eine Meldung auf der Konsole ausgibt:
public class HelloWorld
Die Grammatik von Java ist in der Java Language Specification (Java-Sprachspezifikation) von SUN Microsystems dokumentiert.
Unterschiede zu ähnlichen Sprachen
JavaScript
Java ist nicht mit der reinen Skriptsprache JavaScript zu verwechseln, die vornehmlich in HTML-Seiten zur eingebetteten Programmierung verwendet wird. Sie hat eine ähnliche Syntax, unterscheidet sich jedoch in vielerlei Hinsicht und kann insbesondere nicht für die Konstruktion größerer, kompletter Anwendungen verwendet werden.
Objekte werden in JavaScript prototypenbasiert definiert. Es gibt Implementierungen vor allem in Web-Browsern, aber auch unabhängige Ausführungsumgebungen sind vorhanden.
Smalltalk
Smalltalk ist eine der ältesten objektorientierten Programmiersprachen überhaupt und der eigentliche Vater von Java. Sun hat sich jedoch für die C++ Syntax entschieden und gleichzeitig verlauten lassen, Java würde von C++ abstammen. Der Grund für diesen Schachzug war die größte Hürde für eine neue Programmiersprache: Die Akzeptanz der Programmierer zu erlangen. Dies war mit der Anlehnung an eine sehr bekannte Sprache mit geläufiger Syntax einfacher.
Java erbte von Smalltalk die grundsätzliche Konzeption eines Objektbaumes, in den alle Objekte eingehängt werden und von einem einzigen Mutterobjekt abstammen (java.lang.Object). Des weiteren wurde das Konzept der automatischen Speicherbereinigung (garbage collector) und der virtuellen Maschine übernommen sowie eine Vielzahl weiterer Features der Sprache Smalltalk.
Smalltalk kennt jedoch keine primitiven Datentypen wie z. B. int – selbst eine einfache Zahl ist ein Objekt. Dies wurde in Java geändert.
Klassisch für Smalltalk-Systeme ist der Object-Browser, der in modernen integrierten Entwicklungsumgebungen, wie z. B. Eclipse auch für Java existiert.
C++
Java lehnt an die objektorientierte Programmiersprache C++ an. Im Gegensatz zu C++ fanden jedoch komplexe Konstrukte wie Mehrfachvererbung oder die fehleranfällige Zeigerarithmetik keinen Einzug. Die interne Speicherverwaltung wird dem Java-Entwickler weitgehend abgenommen; dies erledigt die automatische Speicherbereinigung. Deshalb ist Java in vielen Fällen leichter zu handhaben als C++. Allerdings garantiert auch dieser Mechanismus nicht den vollständigen Ausschluss von Speicherlecks. Letztlich muss der Programmierer dafür sorgen, dass nicht mehr verwendete Objekte nirgends mehr referenziert werden.
Neben Mehrfachvererbung und Speicherarithmetik wurden bei der Entwicklung von Java noch weitere Konstrukte der Sprache C++ bewusst weggelassen:
Im Gegensatz zu C++ ist es in Java nicht möglich, Operatoren (zum Beispiel arithmetische Operatoren wie + und -, logische Operatoren wie && und ||, oder den Indexoperator []) zu überladen, das heißt in einem bestimmten Kontext mit neuer Bedeutung zu versehen. Dies sorgt einerseits für eine Vereinfachung der Sprache an sich und verhindert, dass Quellcodes mit Operatoren, die mit schwer nachvollziehbarer Semantik überladen werden, unlesbar gemacht werden. Andererseits können benutzerdefinierte Typen mit überladenen Operatoren in C++ eher wie eingebaute Typen erscheinen und vor allem numerischer Code ist mitunter einfacher nachvollziehbar.
Das C++-Konstrukt der „Templates“, die es erlauben, Algorithmen oder sogar ganze Klassen unabhängig von den darin verwendeten Datentypen zu definieren, wurde in Java nicht übernommen. Seit Version 1.5 unterstützt Java sogenannte „Generics“, die zwar keinerlei Metaprogrammierung erlauben, aber ähnlich wie C++-Templates typsichere Container und ähnliches ermöglichen.
C#
C# (gesprochen: engl. "C sharp" bzw. dt. "ßieh Scharp"), entwickelt von Microsoft, kann als Konkurrenzprodukt zu Java gesehen werden. Mit der Spezifikation von C# hat Microsoft im Rahmen seiner .NET-Strategie versucht, den Spagat zwischen dem kompletten Neuanfang einer Sprache und der leichten Integration bisher bestehender Komponenten zu schaffen.
Die Syntax von C# entspricht in großen Teilen der Syntax von Java, konzeptionelle Unterschiede bestehen insbesondere in der Unterstützung von Delegaten (engl. "delegates"), ein Konzept, das mit Funktionszeigern vergleichbar ist, hierbei kommt ein Beobachter-Entwurfsmuster zum Einsatz – Objekte können sich für Ereignisse registrieren bzw. diese delegieren. C# kennt ebenso wie Java eine Unterscheidung zwischen Werttypen (engl. "value types"; z. B. int, struct) und Referenztypen (engl. "reference types", z. B. class), allerdings sind auch die elementaren Datentypen objektbasiert. Des weiteren unterstützt C# so genannte Attribute ("attributes"), die es erlauben, die Funktionalität der Sprache über Metadaten im Code zu erweitern (eine ähnliche Funktionalität gibt es seit Java 5.0). C# enthält auch Bestandteile der Sprachen VisualBasic (z. B. Eigenschaften bzw. properties) sowie C++ (z. B. enums). In C# hingegen ist es nicht notwendig und möglich Ausnahmen (exceptions) zu einer Methode zu deklarieren. In Java müssen einmal deklarierte Ausnahmen auch verarbeitet werden.
Um auch systemnahe Programmierung zu ermöglichen, besteht in .NET die Möglichkeit, auch so genannten unsicheren unmanaged code zu verwenden, ähnlich Javas JNI.
Bislang gibt es Microsofts .NET-Implementierung nur für Microsoft-eigene Betriebssysteme (ab Windows NT 4 SP 6) – abgesehen von einer Referenz-Implementierung für das FreeBSD-Betriebssystem, die aber unter der sogenannten Shared Source-Lizenz (Quellcode-Modifikationen dürfen nicht weitergegeben werden) veröffentlich wurde, weswegen das Mono-Projekt und DotGNU eigene Implementierungen vorantreibt. Dabei werden auch weitere Betriebssysteme unterstützt. Dies wird dadurch vereinfacht, dass C# standardisiert ist.
Entwicklungsumgebungen
DotGNU
Es gibt eine große Vielfalt von Entwicklungsumgebungen für Java, sowohl kommerzielle als auch freie (Open Source). Die meisten Entwicklungsumgebungen für Java sind selbst ebenfalls in Java geschrieben.
In Form von z. B. OSGi finden sich inzwischen auch eigenständige Entwicklungsframeworks, die verschiedene Konzepte von Java unabhängig hiervon weiterentwickeln – Eclipse basiert beispielsweise auf OSGi. OSGi selbst spezifiziert das Bundle-Konzept, einen service-orientierten Ansatz, um dynamische Nachladbarkeit und Versionsmanagement von Java-Klassen zu ermöglichen (z. B. für Embedded Java-Anwendungen). Hierzu gehört auch das Remote Management von Plattformen, um Service Delivery und Wartung (Updates aus der Ferne) zu ermöglichen.
Die bekanntesten Open-Source-Umgebungen sind Eclipse, jEdit und NetBeans.
Unter den kommerziellen Entwicklungsumgebungen sind das auf Netbeans basierende Sun ONE Studio von Sun, IntelliJ IDEA von JetBrains, JBuilder von Borland sowie JCreator am verbreitetsten. Außerdem gibt es noch eine, um einige hundert Plugins erweiterte Version von Eclipse, die von IBM unter dem Namen WebSphere Studio Application Developer ("WSAD") vertrieben wurde und seit Version 6.0 Rational Application Developer ("RAD") heißt.
Apple liefert mit Mac OS X ab Version 10.3 die Entwicklungsumgebung Xcode aus, die verschiedene Programmiersprachen unterstützt und einen Schwerpunkt auf Java setzt. Xcode ist nach Registrierung für jedermann kostenlos erhältlich.
Wer lieber einen Texteditor verwendet findet in Emacs zusammen mit der JDEE (Java Development Environment for Emacs) ein mächtiges Werkzeug. Für andere Editoren wie Vim, Jed oder Textpad gibt es ebenfalls entsprechende Modes.
Siehe auch: Cocoon, Jogl
Compiler
Mit einem Java-Compiler ist es möglich, Java-Sourcecode (Dateiendung .java) in einen ausführbaren Code zu kompilieren. Grundsätzlich unterscheidet man zwischen Bytecode- und Nativecode-Compilern. Des weiteren verwenden einige Java-Laufzeitumgebungen einen JIT-Compiler um Bytecode häufig genutzter Programmteile in nativen Maschinencode zu übersetzen während das Programm läuft.
Bytecode-Compiler
Java-Programme werden im Normalfall in einen nicht direkt ausführbaren Bytecode (Dateiendung .class) übersetzt, den Maschinencode der Java-Plattform, der in der Java Runtime Environment (JRE) ausgeführt wird. Es ist dabei festzuhalten, dass diese Ausführung von Bytecode nichts mit einem Interpreter zu tun hat, wie er z.B. in Basic zum Einsatz kommt. Die aktuelle HotSpot-Technologie kompiliert den Bytecode zur Laufzeit vielmehr in nativen Prozessorcode und optimiert diesen abhängig von der verwendeten Plattform. Diese Optimierung findet dabei sukzessive statt, so dass der Effekt auftritt, dass Programmteile erst nach mehrmaliger Abarbeitung schneller werden. Auf der anderen Seite führt diese Technologie, die ein Nachfolger der Just-In-Time-Compilierung ist, dazu, dass Java-Bytecodes mindestens genau so schnell wie native, kompilierte Programme ausgeführt werden.
Die HotSpot-Technologie ist seit der JRE Version 1.3.x verfügbar und wurde seitdem immer weiter verbessert.
- javac (Teil des JDK) von Sun Microsystems
- Jikes von IBM
Native Compiler
Es existieren auch Compiler für Java, die Java-Quelltexte oder Java-Bytecode in normalen Maschinencode übersetzen können, sogenannte Ahead-Of-Time-Compiler. Nativ kompilierte Programme haben den Vorteil, keine JavaVM mehr zu benötigen, aber auch den Nachteil, nicht mehr plattformunabhängig zu sein. Hier trifft die Bezeichnung "write once, run anywhere" nicht mehr zu.
- GNU Compiler for Java (GCJ)
- MinGW
- Cygwin
- Excelsior JET
Wrapper
Ein Wrapper (in diesem Zusammenhang) ist ein ausführbares Programm, welches als Ersatz für ein Java Archive (Dateiendung .jar) dient. Er sucht selbständig nach einer installierten Java-Laufzeitumgebung, um das Programm zu starten und informiert den Benutzer darüber, wo er eine Laufzeitumgebung herunterladen kann, sofern noch keine installiert ist. Es ist also immer noch eine Laufzeitumgebung nötig, um das Programm starten zu können.
Java Web Start ist ein etwas eleganterer Ansatz für diese Problematik - er ermöglicht die einfache Aktivierung von Anwendungen mit einem einzigen Mausklick und garantiert, dass Sie immer die neueste Version der Anwendung ausführen. Dadurch werden komplizierte Installations- oder Aktualisierungsprozeduren vermieden.
- [http://jsmooth.sourceforge.net/ JSmooth] (Lizenz: GPL)
- [http://launch4j.sourceforge.net/ Launch4J] (Lizenz: GPL)
- JBuilder von Borland und NSIS ([http://nsis.sourceforge.net/wiki/Java_Launcher Java Launcher]) sind ebenfalls in der Lage einen Wrapper für Windows zu erstellen
Literatur
- James Gosling, Bill Joy, Guy Steele, Gilad Bracha: The Java Language Specification. Second Edition.
- David Flanagan: Java in a Nutshell (Deutsche Ausgabe). O'Reilly, 2002, ISBN 3-89721-332-X
- Christian Ullenboom: Java ist auch eine Insel. Galileo Computing, 2004, ISBN 3-89842-526-6 ([http://www.galileocomputing.de/openbook/javainsel5/ Online-Buch])
- Cay Horstmann, Gary Cornell: Core Java 2. Band 1 - Grundlagen Einführung in die objektorientierte Programmierung. ISBN 3-8273-2216-2
- Guido Krüger: Handbuch der Java-Programmierung. Addison-Wesley, 2002, ISBN 3-8273-1949-8 ([http://www.javabuch.de/ Freier Download])
- Friedrich Esser: Java 2 – Designmuster und Zertifizierungswissen, Galileo Computing, 2001, ISBN 3-9343-5866-7 ([http://www.galileocomputing.de/openbook/java2/ Online-Buch])
- Bruce Eckel: Thinking in Java, Prentice-Hall, 2002, ISBN 0-1310-0287-2 ([http://www.mindview.net/Books/TIJ/ Online-Buch], Englisch)
- Joshua Bloch: Effective Java Programming Language, Addison-Wesley, 2001, ISBN 0201310058
- Dietrich Boles, Cornelia Boles: Objektorientierte Programmierung spielend gelernt mit dem Java-Hamster-Modell, Teubner, 2004, ISBN 3-519-00506-9
- Ralph Steyer: Java 2 - M+T Pocket, Das Programmier-Handbuch, Markt & Technik, 2003, ISBN 3-8272-6106-6 ([http://www.rjs.de/index.php?id=javatb.php Online-Buch])
- Ralph Steyer, Java 2 - Magnum, Markt & Technik, ISBN 3-8272-6242-9 ([http://www.rjs.de/index.php?id=magnum.php Online Buch])
- Dirk Louis & Peter Müller: Java 5 Kompendium - Praxis der objektorientierten Programmierung, Markt & Technik, 2005, ISBN 3-8272-6844-3
Siehe auch
Geschichte
Wikipedia-Artikel zur geschichtlichen Entwicklung von Java:
- Star Seven, das erste Gerät mit Java-Interpreter (damals noch Oak)
Programmiersprachen
Programmiersprachen, die sich an Java anlehnen und Bytecode generieren:
- Groovy
- Nice
Java für Embedded Systems
- Embedded Java / OSGi
Java Frameworks
- OSGi
- Jakarta-Projekt
- Java 2 Platform Enterprise Edition
- Struts
Java-basierte Plattformen
- Multimedia Home Platform (MHP)
- MIDP
Weblinks
- [http://java.sun.com Java-Abteilung von Sun Microsystems] (Englisch)
- [http://java.sun.com/j2se/downloads.html Download Java] (Englisch)
- [http://java.seite.net Kaffee & Kuchen] Deutsche Java-Seite mit News & Workshops
- [http://www.ikvm.net/ Entwicklung einer Java-VM für .NET]
- [http://www.kpdus.com/jad.html Decompiler] für Java
Tutorien
- [http://java.sun.com/docs/books/tutorial/ Java Tutorial] von Sun (engl.)
- [http://java.sun.com/j2se/1.5/docs Java-Dokumentation der aktuellen Version J2SE 1.5] (Englisch, inkl. Sprachdefinition und Standard-API)
- [http://www.javabuch.de/ Handbuch der Java-Programmierung] von Guido Krüger (deutsch), freie HTML-Ausgabe des gleichnamigen Buches
- Interaktives [http://gailer-net.de/tutorials/java/java-toc.html Java Tutorial] von Bradley Kjells (dt./engl.), einsteigerfreundliche Einführung in Java
- Erstellen von Spielen und Bewegung mit Java 1.4: [http://www.javacooperation.gmxhome.de javacooperation] (deutsch/englisch/russisch)
Link-Sammlungen
- [http://www.JavaLinkBase.de/ Java Link Base]
- [http://dmoz.org/World/Deutsch/Computer/Programmieren/Sprachen/Java/ Deutscher Eintrag bei Open Directory]
Kategorie:Programmiersprache
ja:Java言語
| | |