Login
Newsletter
Werbung

Mi, 27. April 2011, 15:00

Eine Einführung in die Programmiersprache Pike

Umwandlung von Typen und gemischte Variablentypen

Es ist wichtig zu wissen, dass alle drei Variablentypen grundsätzlich inkompatibel zueinander sind. Daher gibt es die Möglichkeit, Typen umzuwandeln:

string s;
float f = 42.23;
/*der Wert 42.23 von f wird in die Ganzzahl 42 umgewandelt und uebergeben*/
int i = (int) f;
//42 wird zum String "42"
s = (string) i+" ist die Antwort auf alle Fragen.";

Wenn man sich nicht sicher ist, welcher Typ einer Variablen zugewiesen wird, hat man zwei Möglichkeiten:

/*jeder Typ kann m zugewiesen werden*/
mixed m = 123;
m = "abc";
/*is kann Integer-Werte oder Strings speichern*/
int|string is = 123;
is = "abc";

Dies funktioniert übrigens auch mit dem Rückgabetyp und den Parametern einer Funktion, wie folgendes komplexere Beispiel verdeutlicht:

void main()
{
    write("Hier gibt die Funktion fast "+rueckgabe()+" zurueck.\n");
    write("Mit Parameter ist die Funktion nicht so geizig und gibt "+(string)rueckgabe(42)+" zurueck.\n");
    //"\n" steht uebrigens fuer einen Zeilenumbruch
}

int|string rueckgabe(int|void parameter)
{
    //ist parameter void, also null, ...
    if(!parameter)
    {
        //...gibt die Funktion einen String "nix" zurueck...
        return "nix";
    }
    //Andernfalls...
    else
    {
        //...gibt die Funktion den Wert von parameter zurueck.
        return parameter;
    }
}

Listing: pike_parameter.pike

Das Ausrufezeichen in den runden Klammern ist einer der logischen Operatoren. Um den logischen Wert »falsch« zu repräsentieren, benutzt Pike den Integer-Wert Null; alles andere wird als »wahr« gewertet. Der Operator ! prüft, ob der Ausdruck falsch, also null ist. Deshalb muss man aufpassen, dass man möglichst nur komplexe Datentypen mit diesem Operator auf ihr Vorhandensein prüft, denn rueckgabe(0) gibt ebenfalls »nix« zurück.

Zum ersten Mal ist übrigens die if-Kontrollstruktur von Pike zu sehen, die sich genauso wie in C verhält. Hier noch einmal die Syntax:

if (Bedingung 1)
{
    //Aktionen bei erfuellter Bedingung 1
}
//optional, darf mit verschiedenen Bedingungen mehrmals vorkommen
else if (Bedingung 2)
{
    //Aktionen bei erfuellter Bedingung 2
}
else  //optional
{
    //alternative Aktion
}

Für größere Bedingungsabfragen benutzt man lieber die switch-Anweisung.

Konstanten, Schleifen und Arrays

Äpfel-und-Birnen-Vergleiche werden in der Welt der Programmiersprachen oft gemacht, deshalb sollte man sich daran ein Beispiel nehmen. Da man sich bei dieser Tätigkeit auf starre Meinungen verlassen können muss, benötigt man für ein solches Beispiel von Anfang an festgelegte, gleichbleibende Werte, also Konstanten.

Konstanten lassen sich in Pike auf zwei Arten festlegen: Der erste Weg ist per Präprozessor.

#define apfel 1

Der Präprozessor ersetzt hier in diesem Beispiel vor dem Ausführen des Codeabschnittes apfel mit 1. Die Dokumentation auf der Webseite rät allerdings davon ab und empfiehlt stattdessen, vom Schlüsselwort constant Gebrauch zu machen:

constant apfel = 1;
constant birne = 2;
if (birne > apfel)
{
    write("Birnen sind ganz klar besser als Aepfel!!\n");
}

Natürlich kann es auch vorkommen, dass man mehrere Werte parallel vergleichen möchte, wozu man zwei Arrays und eine Schleife benötigt.

array (int) aepfel = ({1,2,1,1,1});
array (int) birnen = ({3,4,3,3,2});
for (int i = 0; i < 5; i++)
{
    if (birnen[i] > aepfel[i])
    {
        write("Birne "+(string)(i+1)+" ist besser als Apfel"+(string)(i+1)+".\n");
    }
}

Listing: pike_vergleich.pike

Zuerst einmal erkennt man, dass for-Schleifen genauso aussehen wie in C.

for (int i = 0; i < n; i++)
{...}

Auffälliger sind die beiden Arrays, welche am Anfang deklariert und mit Werten gefüllt werden. Das sieht schematisch so aus:

array (Typ) name = ({Wert1,Wert2,Wert3,...,Wertn});

Einen Wert in einem Array erhält man durch name[Stelle], wobei man aufpassen muss, weil die erste Stelle in einem Array immer 0 und nicht 1 ist. Um ein einzelnes Array zu durchlaufen, bietet es sich an, die foreach-Schleife zu benutzen, welche automatisch eine Kopie des jeweiligen Speicherinhalts im Array anlegt. Beispiel:

void main()
{
    array (string) beispiel = ({"Hallo ","Welt ","!\n"});
    string beispielvariable;
    foreach(beispiel, beispielvariable)
    {
        write(beispielvariable);
    }
}

Listing: pike_array.pike

Arrays besitzen feste Größen, man kann also die Werte nur bearbeiten, ohne Weiteres jedoch keinen neuen Wert hinzufügen. Allerdings kann man mehrere Arrays zusammenfassen.

arrayC = arrayA + arrayB;

Achtung: Arrays gehören – neben Mappings (in Perl auch als Hashes bezeichnet) – zu den durch Zeiger realisierten Typen. Bezogen auf das vorherige Beispiel bedeutet dies: Weist man arrayC[0] einen neuen Wert zu, betrifft diese Änderung auch arrayA[0].

array (int) arrayC;
//unzugewiesenes Array C
array (int) arrayA = ({1,2,3});
array (int) arrayB = ({4,5,6});
arrayC = arrayA + arrayB;
//arrayC enthaelt ({1,2,3,4,5,6})
arrayC[0] = 42;
//arrayC enthaelt ({42,2,3,4,5,6})
//arrayA enthaelt ({42,2,3})

Mehrdimensionale Arrays, also Arrays bestehend aus Arrays, sind ebenfalls möglich. Das folgende, komplette Beispiel gibt den String »b« aus:

void main()
{
    array(array(mixed)) c;
    c = ({({"a","b","c"}),({1,2,3})});
    write(c[0][1]);
}

Um die eine oder andere Unflexibilität von Arrays auszugleichen, stellt Pike zur Bearbeitung von Arrays eine Menge an Funktionen zur Verfügung. Darunter befinden sich Funktionen zur Neuberechnung, zur Rückgabe der Größe, zum Kopieren der Inhalte sowie zur Sortierung. Leider würde es den Rahmen sprengen, alle in dieser kleinen Einführung vorzustellen. Ebenso müssen weitere komplexe Datentypen – wie Mappings oder Multisets – unerwähnt bleiben.

Zwei Schleifentypen, die eins zu eins aus C übernommen worden sind, sind die while-Schleife und die do...while-Schleife. Das folgende Schema zeigt das Funktionsprinzip der Schleifen:

while(Bedingung)
{
    // Funktionen, die ausgefuehrt werden, wenn die Bedingung erfuellt ist
}

do
{
    // Funktionen
}
while (Bedingung, die fuer den naechsten Durchlauf geprueft wird);

Achtung: Das Semikolon hinter der letzten Klammer ist sehr einfach zu vergessen und zu übersehen.

Neben dem regulären Durchlaufen der Schleife und dem Verlassen der Funktion mittels return wert gibt es noch zwei weitere Möglichkeiten, eine Schleife zu verlassen:

  • break: Dieser Befehl beendet die Schleife komplett.
  • continue: Der aktuelle Lauf wird beendet und der nächste startet sofort.

Kommentare (Insgesamt: 6 || Alle anzeigen )
gibt doch C-Interpreter? (Kanuba, Mi, 4. Mai 2011)
Re[4]: Warum? (sauer2, Sa, 30. April 2011)
Re[3]: Warum? (eMBee, Fr, 29. April 2011)
Re[2]: Warum? (sauer2, Do, 28. April 2011)
Re: Warum? (eMBee, Do, 28. April 2011)
Pro-Linux
Pro-Linux @Facebook
Neue Nachrichten
Werbung