Teil 2 „Telling the computer what to do“

Der C-Kurs
Antworten
Benutzeravatar
bodo
User
Beiträge: 319
Registriert: 14.02.2007, 17:21
Kontaktdaten:

Teil 2 „Telling the computer what to do“

Beitrag von bodo » 26.07.2008, 14:55

C für BASIC-Programmierer

Arbeiten mit dem z88dk Cross-Compiler

von Jens Sommerfeld und Bodo Wenzel

Teil 2

Im ersten Teil haben wir euch erklärt, wie ihr unter Micro$oft Windows das z88dk zum Laufen bekommt. Hier kommt als Nachtrag noch die Kurzanleitung für alle Linux-Benutzer.

Anstelle der Datei „z88dk-1.8.0-setup.exe“ holt ihr euch die Datei „z88dk-src-1.8.tgz“ über die Projektseite http://www.z88dk.org und packt sie an einem euch genehmen Ort aus. Dann ruft ihr entsprechend der Anleitung in dem entstandenen Verzeichnis „z88dk“ das Skript „build.sh“ auf. Es gibt ein paar Warnungen, aber endlich sind alle nötigen Programme und Bibliotheken erzeugt. Ich persönlich wollte keine systemweite Installation, daher war ich hier schon fertig, außer dass ich mir ein kleines Skript namens prep.sh gebastelt habe, das die Umgebungsvariablen erweitert:

Code: Alles auswählen

#!/bin/sh
export PATH=$PATH:/home/bodo/ZX81/ZX-C/z88dkv1.8/z88dk/bin
export Z80_OZFILES=/home/bodo/ZX81/ZX-C/z88dkv1.8/z88dk/lib/
export ZCCCFG=/home/bodo/ZX81/ZX-C/z88dkv1.8/z88dk/lib/config/
Dort, wo „/home/bodo/ZX81/ZX-C/z88dkv1.8/“ steht, tragt ihr natürlich euren Pfad ein.

Unsere Empfehlung für zukünftige Compileraufrufe ist übrigens:

Code: Alles auswählen

zcc +zx81 -vn -Wall -create-app beispiel.c -o beispiel.bin
Vier neue Optionen sind hier dazugekommen:
  • „-vn“ schaltet die Ausgabe der internen Programmaufrufe aus. Diese Option könnt ihr weglassen, wenn ihr die einzelnen Stufen der Übersetzung sehen möchtet, aber mit der Option fallen die eventuellen Fehlermeldungen viel mehr auf.
  • „-Wall“ schaltet alle Warnungen ein. Das ist sinnvoll, denn solange sogar der Compiler etwas anmäkelt, kann euer Programm nicht ganz korrekt sein.
  • „-create-app“ ruft als letztes das Tool appmake auf, das uns automatisch eine P-Datei erzeugt. Diese hat übrigens ein großes 'P', aber das stört ja nicht.
  • „-o beispiel.bin“ sorgt dafür, dass die entstehende Binärdatei einen anderen Namen als „a.bin“ hat. Dies ist auch die Voraussetzung dafür, dass die P-Datei anders als „a.P“ heißt. Im Beispiel wäre dies „beispiel.P“.
Das war es. Bevor ihr jetzt den Compiler aufruft, lasst ihr das oben genannte Skript einmalig pro Session laufen (in einer Bash mit „. prep.sh“), sonst wird er nicht gefunden.

Damit haben wir quasi das Kapitel 1 des Vickers-Handbuchs („Setting up the ZX81“)hinter uns und kommen zum Kapitel 2 mit dem schönen Titel „Telling the computer what to do“. Dort wird u.a. auf die Benutzung der Eingabezeile eingegangen, aber ihr wisst ja, wie man einen Editor verwendet, deshalb lassen wir das hier aus.

Im Gegensatz zu BASIC gibt es bei C keinen Unterschied zwischen einem Programm und einer direkt ausgeführten Zeile. In C gibt es nur ein Programm, dafür brauchen wir aber keine Zeilennummern. Das liegt u.a. daran, dass ein C-Programm compiliert wird und dann erst als Ganzes lauffähig ist (Zumindest ist das normalerweise so. Es gibt keinen technischen Grund, warum man nicht auch einzelne Statements in einem Interpreter ausführen könnte – außer, dass der ANSI-C-Standard das nicht enthält. Aber offenbar interessiert das kaum jemanden, daher kenne ich (Bodo) nur einen C-Interpreter für den Atari-ST.).

C ist eine sogenannte formatfreie Sprache, bei der die Anordnung der einzelnen Sprachelemente im Quelltext weitgehend freigestellt ist, daher könnt ihr das Beispiel aus Teil 1 auch so schreiben (probiert das ruhig aus, es geht!):

Code: Alles auswählen

#include <stdio.h>
int main(void){printf("Hallo Welt!\n");return 0;}
Oder auch:

Code: Alles auswählen

#include <stdio.h>
int
main
(
void
)
{
printf
(
"Hallo Welt!\n"
)
;
return
0
;
}
Es gibt natürlich verschiedene Stile, wieviele Leerzeichen und Zeilenumbrüche wo gesetzt werden, und innerhalb der C-Welt gibt es Religionskriege um den „richtigen“ Stil. Lasst euch davon nicht stören, wählt einen Stil und bleibt eine Weile dabei.

Wie in BASIC, gibt es auch hier Statements. Jedes Statement wird mit einem Semikolon ';' abgeschlossen. Ebenso gibt es einige Schlüsselwörter, es sind nicht allzu viele:

Code: Alles auswählen

auto break case char const continue default do double else enum extern float for goto if int long register return short signed sizeof static struct switch typedef union unsigned void volatile while
Wir werden im Rahmen dieses Kurses sicher nicht auf alle eingehen, aber die meisten werden vorkommen. Was euch aber sofort auffällt: ein paar Worte aus dem ersten Programm stehen dort gar nicht. OK, „dat kriejen wir spähter“.

Was passiert aber, wenn ihr im Programmtext einen Fehler habt? Nun, probiert es einfach aus!

Ein paar Beispiele für fehlerhafte Quelltexte:

Beispiel 1:

Code: Alles auswählen

include <stdio.h>

int main(void) {
    printf("Hallo Welt!\n");
    return 0;
}
Der Fehler ist hier das fehlende Zeichen '#' vor include. Und der Compiler meckert auch daran herum:

Code: Alles auswählen

sccz80:"CfBASIC_2-2.c" L:2 Warning:#7:Return type defaults to int
sccz80:"CfBASIC_2-2.c" L:2 Error:#27:Missing Open Parenthesis
Compilation aborted
Die Zeile 2 wird deshalb gemeldet, weil er wohl hoffte, dort noch etwas Richtiges zu finden. Zunächst mögen die Fehlermeldungen euch seltsam erscheinen, aber er hat eigentlich Recht. Warum, würde hier noch zu weit führen. Ihr könnt euch merken, dass eine Fehlermeldung ab und zu eine Zeile zu tief referenziert, und dass ein Fehler häufig weitere Meldungen nach sich zieht.

Beispiel 2:

Code: Alles auswählen

#include <stdio.h>

main() {
    printf("Hallo Welt!\n");
    return 0;
}
Hier haben wir zwar die Schlüsselworte int und void weggelassen, aber der Compiler hat es akzeptiert und nur ein bisschen gemeckert:

Code: Alles auswählen

sccz80:"CfBASIC_2-3.c" L:3 Warning:#7:Return type defaults to int
Beispiel 3:

Code: Alles auswählen

#include <stdio.h>

int haupt(void) {
    printf("Hallo Welt!\n");
    return 0;
}
Das Umbenennen von main in haupt provoziert folgende Fehlermeldung:

Code: Alles auswählen

1 errors occurred during assembly
Key to filenames:
/tmp/tmpXXtjuA1z.o = CfBASIC_2-4.c
File '/tmp/tmpXXSbQeOO.asm', Module 'ZX81_CRT0', Symbol not defined
Error in expression _MAIN
Der eigentliche Compiler hat den Quelltext akzeptiert, aber im späteren Verlauf (beim Linken, aber das kriegen wir erst demnächst) wird das Fehlen des Symbols _MAIN entdeckt. Offenbar muss das Wort also main heißen!

Beispiel 4:

Code: Alles auswählen

#include <stdio.h>

integer main(void) {
    printf("Hallo Welt!\n");
    return 0;
}
Wenn wir das Wort int ganz als integer ausschreiben, erhalten wir diese Meldung:

Code: Alles auswählen

sccz80:"CfBASIC_2-5.c" L:3 Warning:#7:Return type defaults to int
sccz80:"CfBASIC_2-5.c" L:3 Error:#27:Missing Open Parenthesis
Compilation aborted
Die Zeilennummer stimmt, und in kurzer Zeit ergibt der Text auch für euch Sinn.

Beispiel 5:

Code: Alles auswählen

#include <stdio.h>

int main(void) {
    printf("Hallo Welt!\n")
    return 0;
}
Das ist ein interessanter Fall: wir haben das Semikolon des ersten Statements weggelassen. Der Compiler merkt das zwar:

Code: Alles auswählen

sccz80:"CfBASIC_2-6.c" L:5 Warning:#17:Expected ';'
Aber er denkt es sich einfach und macht weiter. Das Ergebnis: ein fehlerfrei erzeugtes Programm. Ihr habt sicher schon bemerkt, dass die Zeilennummer eine Zeile zu tief ist. Das liegt daran, dass der Compiler erst in dieser Zeile bemerkt hat, dass das Semikolon fehlt, als er das Schlüsselwort return fand.

Beispiel 6:

Code: Alles auswählen

#include <stdio.h>

int main(void) {
    print("Hallo Welt!\n")
    return 0;
}
Dieser Fehler könnte bei BASIC-Programmierern häufiger auftreten: die übliche Ausgabefunktion heißt printf mit 'f' am Ende. Die dazugehörige Meldung zeigt, dass print nicht bekannt ist:

Code: Alles auswählen

sccz80:"CfBASIC_2-7.c" L:4 Warning:#33:Call to function without prototype
1 errors occurred during assembly
Key to filenames:
/tmp/tmpXXmGnYzP.o = CfBASIC_2-7.c
File '/tmp/tmpXXcsKoEE.asm', Module 'CFBASIC_2', Symbol not defined
Error in expression _PRINT
Zusammenfassung:
  • Auch ein Linux-Rechner kann C-Programme für den ZX81 erzeugen.
  • Es gibt nur „das Programm“, C kennt keine direkte Befehlseingabe.
  • C braucht keine Zeilennummern und es ist egal, wie man die einzelnen Worte im Quelltext anordnet.
  • C hat Statements; jedes wird mit einem Semikolon abgeschlossen.
  • Fehler im Quelltext werden (für Anfänger) als teilweise krytische Meldungen angemeckert. Mit wachsender Erfahrung werdet ihr merken, dass der ausgegebene Meldungstext fast immer sinnvoll ist.
Zuletzt geändert von bodo am 10.11.2008, 19:28, insgesamt 1-mal geändert.


Zuletzt als neu markiert von bodo am 26.07.2008, 14:55.
B0D0: Real programmers do it in hex.

Antworten