Previous Next Contents

Programmierung von Computern

"Kosten-Nutzen-Analyse": Sinnvoll bei häufig wiederkehrenden Aufgabenstellungen, die den Programmieraufwand rechtfertigen.

Allgemeines / Historie

Ausführbare Computerprogramme müssen in Maschinensprache vorliegen, d.h., als Abfolge von Bytes (Zahlen), letzten Endes Nullen und Einsen 00011011100001... .

Etwas leichter und übersichtlicher wird die Programmierung, wenn man einen Assembler verwendet, bei dem man anstelle der Bytes die Befehle in Textform (als mnemonische Codes) eingibt, z.B. MOV, ADD, SUB, JMP, JSR, RET. Doch erlauben die Assembler-Befehle nur sehr primitive Operationen wie das Verschieben von Daten (MOV), das Addieren bzw. Subtrahieren ganzer Zahlen (ADD, SUB), Sprünge (JMP) und Verzweigungen in Unterroutinen (Subroutines, JSR, RET).

Effizienter ist die Verwendung problemorientierter höherer Programmiersprachen, die wesentlich mächtigere Funktionen bereitstellen (z.B. sqrt, exp, sin). Man kann sie nach verschiedenen Kriterien einteilen (z.B. deklarativ, prozedural (imperativ), objektorientiert). Der Programmierer erstellt zunächst den Quellcode im menschenlesbaren (ASCII- oder Unicode-) Klartext. Für die Umsetzung dieses Quellcodes in Maschinencode gibt es drei Möglichkeiten:

  1. Verwendung eines Interpreters (z.B. für BASIC oder eine "Skriptsprache" wie Perl), d.h., die Liste der Befehle wird jedesmal Schritt für Schritt eingelesen und in Maschinenbefehle umgesetzt. Dieses Verfahren ist relativ langsam, aber Änderungen des Quellcodes lassen sich schnell umsetzen.
  2. Verwendung eines Compilers, der aus dem Quellcode (über Zwischenstufen) den binären, ausführbaren Maschinencode erstellt. Diese Binärprogramme laufen rascher ab als die interpretierten, aber nach jeder Änderung des Quellcodes ist eine neue Compilation erforderlich.
  3. Bei der Sprache Java wird intermediär ein maschinenunabhängiger Bytecode erzeugt. Dieses Verfahren ist schneller als das Interpretieren, es wird aber eine spezielle Laufzeitumgebung (run-time environment) benötigt.

Klassifizierungen von Programmiersprachen

Fünf Phasen der Programmierung

  1. Produktdefinition (Problemanalyse, Pflichtenheft) - "was"
  2. Programmentwurf (Algorithmus, Programmablaufplan) - "wie"
  3. Implementierung (Codierung in einer Programmiersprache) → Erstellung des Quelltexts und ggf. Compilierung
  4. Systemtest (Prüfung auf syntaktische und logische Fehler, Benutzerfreundlichkeit)
  5. Einsatz und Wartung (Aktualisierung)

Programmablaufsteuerung

(bei imperativen/prozeduralen und objektorientierten Sprachen)

Trivialerweise wird eine Anweisung nach der anderen der Reihe nach abgearbeitet (im alten Interpreter-BASIC geordnet nach Zeilennummern). Eine "intelligentere" Programmierung benötigt Möglichkeiten, um davon abzuweichen; die wichtigsten Konstrukte sind bedingte Anweisungen (IF ... THEN ... ELSE ...) und Schleifen (Zählschleifen: FOR ...; WHILE ...; DO ... WHILE ...).

Im folgenden Kurs soll auf eine systematische Behandlung der Programmierung verzichtet werden - siehe dazu z.B.

Statt dessen sollen einige Programmiersprachen kurz vorgestellt und anhand von Beispielen diskutiert werden. Kleine eigene Programme sollen in BASIC erstellt werden, weil Anfänger damit am schnellsten zum Ziel kommen.

Das Miniprogramm "Hello world"

soll diesen Text auf dem Bildschirm ausgeben. Es gibt einen ersten Eindruck vom "Flair" der Programmiersprache und zeigt, ob der Compiler (bzw. Interpreter) korrekt installiert wurde.

BASIC alt (mit Zeilennummern): hello.bas

Auf den Pool-PCs sollte BASIC (gwbasic bzw. tb) über den DOS-Emulator dosbox verwendet werden.
dosbox
mount c c:\tb
c:

hello.bas:

100 PRINT "Hello world"
110 END

Aufruf über einen BASIC-Interpreter (z.B. basic, gwbasic, bwbasic) - der Bywater BASIC Interpreter (bwbasic) steht auf den SGI-Workstations zur Verfügung:

bwbasic hello.bas
system

BASIC neu (ohne Zeilennummern): hello2.bas

hello2.bas:
PRINT "Hello world"
END

Aufruf z.B. mit dem Bywater BASIC Interpreter (bwbasic) oder über Turbo-Basic (TB, in C:\TB):

bwbasic hello2.bas
system

FORTRAN: hello.f

FORTRAN (FORmula TRANslator) ist eine der ältesten Programmiersprachen, besonders geeignet für komplizierte mathematische Berechnungen. FORTRAN wird auch heutzutage noch für quantenchemische Programme benutzt (z.B. Gaussian). Es weist Ähnlichkeiten zu BASIC auf, erfordert aber einen Compiler.

Fortran 77 (f77) zeigt noch seine Abstammung aus dem Lochkarten-Zeitalter: Der eigentliche Programmcode muss in den Spalten 7 - 72 stehen. Die neuere Version Fortran 90 (f90) ist in dieser Hinsicht ggf. flexibler, außerdem werden Elemente der objektorientierten Programmierung unterstützt. (Pool-PCs: gfortran = f95)

hello.f:

       PROGRAM hello
       PRINT *, 'Hello world'
       END

Compilation und Aufruf (unter Unix, auf SGI-Workstations oder unter SuSE-Linux):

f77 -o hello hello.f
hello

Pascal

war insbesondere in der Variante "Turbo Pascal" in den 1980er/1990er-Jahren eine populäre Programmiersprache: strukturiert und schnell (eine modernere Variante wäre "Delphi"). Frei erhältlich ist "Free Pascal" (FPC) für MS Windows oder Linux.

hello.p:

program hello;
begin
  writeln('Hello world');
end.

C: hello.c

Die Programmiersprache C ist insbesondere mit dem Betriebssystem Unix "verbandelt". Sie ist etwas maschinennäher und "kryptischer" als die verwandte Sprache Pascal. C++ ist eine "objektorientierte" Variante.

hello.c:

#include <stdio.h>
void main()
{
  printf("Hello world\n");
}

Compilation und Aufruf (unter Unix, auf SGI-Workstations oder unter SuSE-Linux):

cc -o hello hello.c
hello

Java: hello.java

Die moderne Programmiersprache Java (nicht zu verwechseln mit der Web-Scriptsprache "JavaScript"!) wurde/wird von der Firma SUN Microsystems entwickelt. Interessant ist, dass hierbei aus dem Quellcode ein maschinenunabhängiger Bytecode erzeugt wird, der unter allen Betriebssystemen lauffähig ist (z.B. MS Windows, Unix bzw. Linux), sofern die "Java Runtime Environment" installiert wurde. Bemerkenswert ist, dass Java wahlweise als "normale" Applikation benutzt oder als "Applet" in Webseiten integriert werden kann.

Java wurde ausgehend von C++ entwickelt und hat daher große Ähnlichkeiten damit.

hello.java:

/** 
          * The hello class implements an application that
          * simply displays "Hello World!" to the standard output.
          */
         class hello {
             public static void main(String[] args) {
                 System.out.println("Hello World!"); //Display the string.
             }
         }

Compilation und Aufruf (unter Unix, auf SGI-Workstations oder unter SuSE-Linux):

(SGI-Workstations: setenv PATH {$PATH}:/usr/java/bin.)

javac hello.java
java hello

Java als Applet: hellojav.html mit Hello2.java (bzw. Hello2.class)

Perl: hello.pl

Perl (Practical Extraction and Report Language) ist eine Scriptsprache mit C-ähnlicher Syntax.

hello.pl:

#!/usr/local/bin/perl

print "Hello world\n";

Ein Programm mit verschachtelten Schleifen: Pascalsches Dreieck

Die Berechnung eines Pascalschen Dreiecks (Binomialkoeffizienten, Anwendung z.B. bei Intensitäten von Multipletts in der NMR) soll am Beispiel der Programmiersprachen BASIC, FORTRAN, Pascal und C gezeigt werden.

pascal.bas:

100 REM Comments start with "REM"
110 REM Pascal triangle
120 OPTION BASE 1     :REM arrays start with element 1 (default: 0)
130 DIM basis(13)      :REM array "basis" with 13 elements (1..13)
140 spaces = 23
150 REM Now initialize the array elements with 1 (loop: FOR .. TO .. NEXT):
160 FOR i=1 TO 13
170   basis(i) = 1
180 NEXT i
190 REM Now print first three elements:
200 PRINT USING "     Pascal triangle     #####"; basis(13)
210 PRINT USING "                       ##### ####"; basis(12), basis(13)
220 REM three nested loops follow (FOR .. TO .. NEXT):
230 FOR i=12 TO 2 STEP -1      :REM step downward from 12 to 2
240   FOR j=i TO 12            :REM step 1
250    basis(j) = basis(j) + basis(j+1)
260  NEXT j
270  spaces = spaces - 2
280  REM prepend proper number of spaces:
290  PRINT SPACE$(spaces);
300  FOR k=i-1 TO 13
310    PRINT USING "#####"; basis(k);
320  NEXT k
330  PRINT                       :REM end of line (line feed)
340 NEXT i
350 END

Ohne Zeilennummern: pascal2.bas.

pascal.f:

C Comments start with "C" (or "*") in the first column
C     fixed-form style: statements are written in columns 7 - 72
C     columns 1-5: label, column 6: continuation line if non-blank
C00000000111111111122222222223333333333444444444455555555556666666666777
C23456789012345678901234567890123456789012345678901234567890123456789012
      PROGRAM pascalt
      INTEGER basis(13), spaces
      CHARACTER*10 fmt
      DATA basis /13*1/, spaces /23/

      WRITE (*, 1111) basis(13), basis(12), basis(13)
C     output of first three elements
 1111 FORMAT (5X,'Pascal triangle',4X,I6/22X,I6,I5)
      DO 20 i=12,2,-1
        DO j=i,12
          basis(j) = basis(j) + basis(j+1)
        END DO
      spaces = spaces - 2
      WRITE (fmt, 22) spaces
   22 FORMAT ('(',I2,'X,13I5)')
      WRITE (*, fmt) (basis(k), k=i-1,13)
   20 CONTINUE
      END

pascal.p:

{ This is a comment }
{ Pascal triangle }
program pascalt;
var i,j,k,spaces : integer;        { declaration of integer varables }
    basis : array [1..13] of integer;   { array with elements 1..13 }

begin
  spaces := 23;    { initialization }
  { initialize the array elements: loop (for .. to .. do) }
  for i:=1 to 13 do basis[i] := 1;
  { Now print first three elements: writeln = write line (with line feed) }
  writeln('     Pascal triangle    ', basis[13]:6);
  writeln('                      ', basis[12]:6, basis[13]:5);
  { three nested "for"-loops follow }
  for i:=12 downto 2 do        { step: -1 ! }
  begin
    for j:=i to 12 do
      basis[j] := basis[j] + basis[j+1];
    spaces := spaces - 2;
    { prepend proper number of spaces: }
    write(' ':spaces);
    for k:=i-1 to 13 do
      write(basis[k]:5);
    writeln;    { end of line (line feed) }
  end;
end.

pascal.c:

/* This is a comment */
/* Pascal triangle */
#include <stdio.h>    /* "header" with definitions for standard input/output */
/* each C program must have one function "main" */
int main()
{                    /* '{' means "BEGIN", '}' means "END" */
  int i,j,k;         /* declaration of integer varables */
  int spaces=23;
  int basis[14];     /* array with elements 0..13 (!) */
  
  /* initialize the array elements: loop for(initialization; condition; step) */
  for(i=1; i<=13; i++)       /* "i++" means i = i+1 */
  {
    basis[i] = 1;
  }
  /* Now print first three elements: */
     /* "%6d" means "decimal integer, width 6", "\n" means "line feed" */
  printf("     Pascal triangle    %6d\n", basis[13]);
  printf("                      %6d%5d\n", basis[12], basis[13]);
  /* three nested "for"-loops follow */
  for(i=12; i>=2; i--)    /* i-- means: i = i-1 */
  {
    for(j=i; j<=12; j++)
    {
      basis[j] += basis[j+1];     /* means: basis[j] = basis[j] + basis[i]; */
    }
    spaces -= 2;       /* means: spaces = spaces - 2 */
    /* prepend proper number of spaces: */
    printf("%*s", spaces, " ");        /* yields "%21s" etc. */
    for(k=i-1; k<=13; k++)
    {
      printf("%5d", basis[k]);
    }
    printf("\n");     /* end of line (line feed) */
  }
  return 0;
}                    /* '}' means "END" */

Weitere Programmbeispiele

Vorgestellt werden einige C++-Programme (Unix) und Turbo-BASIC (MS DOS).

Kleine Programmieraufgabe: 10! (10 Fakultät) mit Turbo-BASIC berechnen.


Previous Next Contents