Huber's Welt

Willkommen in meiner Welt

Programmierer aus Leidenschaft - Teil 2: Meine Lieblingssprachen

18.12.2020

Zum Programmieren braucht man heute immer noch meistens eine Programmiersprache. Hier ist meine persönliche Favoritenliste, angereichert mit ein paar einfachen Beispielen.

Platz 1: Object Pascal

Richtig programmieren habe ich erst mit dieser Programmiersprache gelernt. Mit BASIC konnte ich mir zwar die Grundlagen aneignen, die Sprache hat mich aber auch immer ziemlich frustriert, weil es praktisch unmöglich war, ein Programm nachträglich zu erweitern ohne sämtliche Zeilennummern anpassen zu müssen. Object Pascal bot mir dagegen die Möglichkeit ein Programm mit Funktionen und Prozeduren (also Funktionen ohne Rückgabewert) zu strukturieren und diese zudem in Module (sogenannte Units in Turbo Pascal, Free Pascal oder Delphi) auszulagern, die ich dann auch für andere Programme wiederverwenden konnte - nach dem Motto einmal geschrieben, tausendmal genutzt. Und es gab keine Zeilennummern!

Das gefällt mir an Object Pascal:

  • Die Syntax der Sprache lehnt sich stark an natürlicher Sprache (in diesem Fall Englisch) an. Dadurch ist sie besonders für Programmieranfänger leichter zu verstehen.
  • Die Sprache unterstützt (erzwingt) strukturierte Programmierung. Programme, deren Funktionen und Prozeduren, sowie die Units sind strukturell immer nach dem gleichen Schema aufgebaut (siehe Beispiel). Funktionen und Prozeduren können ineinander verschachtelt werden und haben dann nur lokale Sichtbarkeit.
  • Variablen unterliegen einer strengen Typprüfung. Das heißt einerseits, dass alle Variablen einen Typ haben müssen und andererseits, dass der Typ einer Variablen nachträglich nicht mehr geändert werden kann. Dadurch lassen sich viele Fehler schon während der Übersetzung in Maschinensprache erkennen.
  • Die Sprache unterstützt abstrakte Datentypen (sogenannte Records) und Objektorientierung.
  • Sie ist universell einsetzbar und auf allen großen Betriebssystemen (Linux, Mac OS/iOS, Windows), sowie für viele Prozessorarchitekturen verfügbar (siehe Free Pascal).

Das gefällt mir nicht:

  • Es gibt kein Konzept für generische Klassen (Templates).
  • Es gibt keine Garbage Collection. Dynamisch erzeugte Objekte müssen immer explizit gelöscht werden. Vergisst man das, gibt es Speicherlecks.

Folgendes simple Programm soll einige der genannten Spracheigenschaften demonstrieren:

program Hello;
  uses crt;          (* Einbinden einer Unit *)
  var i,n : integer; (* Deklaration globaler Variablen *)

  (* Deklaration einer Funktion *)
  function input(text : string) : integer;
  var value : integer; (* Deklaration lokaler Variablen *)
  begin
    writeln(text);
    readln(value);
    input := value;
  end;

(* Hauptprogramm, hier beginnt die Ausführung *)
begin
  clrscr();
  n := input('Wie oft soll ''Hallo Welt'' ausgegeben werden?');
  for i := 1 to n do begin
    writeln('Hallo Welt ', i);
  end;
end.

Das Programm nimmt eine Eingabe vom Benutzer (hier eine Ganzzahl) entgegen und gibt dann den Text "Hallo Welt" der Eingabe entsprechend oft auf der Kommandozeile aus. Dieses zugegebenermaßen sehr simple Programm zeigt die grundsätzliche Struktur eines Programms, einer Funktion oder Prozedur, sowie einer Unit:

  1. Jedes Programm, jede Funktion und Prozedur, sowie jede Unit hat einen Namen. Prozeduren und Funktionen haben optional zusätzlich eine Parameterliste (in Klammern), Funktionen zusätzlich einen Rückgabetyp.
  2. Nach dem Namen (und der optionalen Parameterliste) folgt ein Bereich (Block) in dem Konstanten, Datentypen und Variablen deklariert werden. Diese werden mit den Schlüsselwörtern const, type und var eingeleitet.
  3. Erst dann folgt der Block mit der eigentlichen Funktionalität. Dieser wird mit dem Schlüsselwort begin eingeleitet und mit end beendet.

Platz 2: C/C++

Mit C++ habe ich vor rund 20 Jahren begonnnen zu programmieren. Zuvor hatte ich mich mehr mit dem C++-ähnlichen Java beschäftigt. Anfangs war ich entsetzt über die nur rudimentär vorhandene Unterstützung von Zeichenketten (strings). Hier war ich von Object Pascal und Java, wo es native Datentypen für Zeichenketten gibt, besseres gewohnt. Nachdem sich inzwischen aber die Standard Template Library (STL), eine Klassenbibliothek für C++, weithin durchgesetzt hat, ist dieses Manko behoben. Seither schreibe ich die meisten Programme in dieser Sprache.

Was mir an C/C++ gefällt:

  • Durch die im Vergleich zu Object Pascal reduzierte Syntax kann man sehr kompakten Code schreiben - was allerdings zuweilen auch zu Lasten der Lesbarkeit geht.
  • Das Konzept für generische Klassen ist sehr ausgereift und mächtig. Damit lässt sich sehr gut optimierter Code schreiben, weil es zum Beispiel nicht nötig ist, Typumwandlungen durchzuführen.
  • Die meisten Operatoren (+, -, *, /, Funktionsoperator...) lassen sich überschreiben. Damit ist es möglich, eigene Datentypen zu schreiben, die sich wie die eingebauten verhalten.
  • Praktisch jedes moderne Betriebssystem ist in C oder C++ geschrieben. Damit stehen überall C/C++-Compiler und entsprechende Werkzeuge zur Verfügung.

Was mir nicht gefällt:

  • Die Teilung des Codes in Header- und Implementierungs-Dateien. Dies zwingt mich immer dazu, zwei Dateien zu schreiben und aktuell zu halten (zum Beispiel, wenn sich die Schnittstelle einer Klasse ändert). Das soll sich aber mit dem ab C++20 verfügbaren Modulkonzept endlich erledigen.
  • Es gibt keine Garbage Collection. Der Speicher muss daher sehr sorgsam behandelt werden, sonst bleiben Speicherlecks übrig.

In C/C++ sieht das obige Beispiel folgendermaßen aus:

#include <stdio.h> /* Einbinden einer Header-Datei */

/* Definition einer Funktion */
int input(std::string text) {
  std::cout << text << std::endl;
  int result = 0;
  std::cin >> result;
  return result;
}

/* Hauptfunktion, hier beginnt die Ausführung. */
void main() {
  int n = input("Wie oft soll \"Hallo Welt\" ausgegeben werden?");
  for (int i = 1; i < n; ++i) {
    std::cout << "Hallo Welt " << i << std::endl;
  }
}

Platz 3: C#

Mit C# programmiere ich seit ungefähr 9 Jahren. Was mir an dieser stark an C++ angelehnten Programmiersprache besonders gefällt ist, dass ich sehr schnell zu einem Ergebnis komme. Dies liegt speziell daran, dass ich von den Entwicklungsumgebungen für C# (Visual Studio, MonoDevelop) in Form von Fehlerhinweisen, die mir bereits beim Schreiben angezeit werden, gut unterstützt werde. Außerdem steht schon in der Grundkonfiguration eine mächtige Klassenbibliothek zur Verfügung, die praktisch alles enthält, was man zum Erstellen von Programmen heute so braucht.

Das gefällt mir an C#:

  • Es gibt keine Zeiger, dafür aber Garbage Collection. Damit entfällt die Notwendigkeit dynamisch erzeugte Objekte explizit zu löschen.
  • Die Syntax ist weitgehend an C++ angepasst, allerdings um die komplexen Teile erleichtert. Es gibt zum Beispiel keine Möglichkeit Funktionen inline zu deklarieren. Eventuelle Optimierungen übernimmt der Compiler und ich muss mich nicht selbst darum kümmern.
  • Sie ist rein Objektorientiert. Funktionen müssen immer einer Klasse zugeordnet sein. Sollen die Funktionen unabhängig von der Existenz eines Objekts der Klasse, in der sie implementiert sind, verwendet werden können, müssen sie statisch deklariert sein.

Das gefällt mir an C# nicht:

  • Sie ist von Microsoft (Monopolist!).

Mein kleines Beispiel von oben liest sich in C# so:

using System;

namespace Hello 
{
  // In C# muss alles in einer Klasse untergebracht werden. 
  public sealed class Program 
  {
    // Konstruktor der Klasse.
    private Program()
    {}
    
    // Hauptmethode, hier beginnt die Ausführung.
    public static void Main(string[] args) 
    {
      var prg = new Program();
      prg.Run();
    }
    
    // Definition einer Methode (Funktion).
    private void Run() 
    {
      int n = Input("Wie oft soll \"Hallo Welt\" ausgegeben werden?");
      for (int i = 1; i < n; ++i) 
      {
        Console.WriteLine("Hallo Welt {0}", i);
      }
    }
    
    // Definition einer weiteren Methode.
    private int Input(string text) 
    {
      Console.WriteLine(text);
      var line = Console.ReadLine();
      if (int.TryParse(line, out int result))
      {
        return result;
      }
      
      return 0;
    }
  }
}

Platz 4: Python

Mit Python programmiere ich erst seit ungefähr 2 Jahren, finde die Sprache aber sehr interessant. Trotz der Tatsache, dass es eine interpretierte Sprache ist, kann man mit ihr so ziemlich alles programmieren: von einfachen Konsolenapplikationen über Spiele bis zu Content Management Systemen, KI-Anwendungen oder 3D-Grafik. Viele nicht in Python geschriebene Programme lassen sich zudem mithilfe von Python "skripten", das heißt um zusätzliche Funktionalität erweitern ohne das Programm selbst neu kompilieren zu müssen.