Die Suche ergab 233 Treffer

von bbock
03.07.2023, 20:48
Forum: Programmierung
Thema: HP-GL Interpreter
Antworten: 48
Zugriffe: 99169

Re: HP-GL Interpreter

pbmread V3.2 kann jetzt auch eine Diashow anzeigen. Dazu gibt es die neue Kommandozeilenoption -diashow, die mit einer Laufwerksangabe ergänzt werden kann. Wird kein Laufwerk angegeben, dann wird das aktuelle Laufwerk verwendet.

Die Option zum Invertieren des Bildes beim Laden hat nun auch ein Minus-Zeichen vorangestellt bekommen: -invert.

Beispiele:

pbmread
Zeigt das Menü zur Eingabe eines Dateinamens an. Dem Dateinamen kann auch ein Laufwerksbuchstabe - z.B. B: - vorangestellt werden.

pbmread dodo1.pbm
Lädt die Datei vom aktuellen Laufwerk und zeigt sie an.

pbmread dodo1.pbm -invert
Lädt die Datei vom aktuellen Laufwerk und zeigt sie invertiert an.

pbmread -diashow
Zeigt eine Diashow aller PBM-Dateien des aktuellen Laufwerks an.

pbmread -diashow b:
Zeigt eine Diashow aller PBM-Dateien des Laufwerks B: an.

Hinweise:
  • Keine Diashow: Mit der Taste "I" wird das Bild invertiert. Eine beliebige andere Taste beendet das Programm.
  • Die Diashow kann mit einer beliebigen Taste abgebrochen werden; das begonnene Bild wird noch zuende gezeichnet.
Download
von bbock
30.06.2023, 20:27
Forum: Programmierung
Thema: Übungen zu "Programmieren in C mit dem z88dk"
Antworten: 11
Zugriffe: 5743

Re: Übungen zu "Programmieren in C mit dem z88dk"

Dann schreibe doch mal als kleine Übungsaufgabe das Programm in Java unter Verwendung von BigInteger. ;)

Übrigens: Mein Taschenrechner und meine Tabellenkalkulation kommen auch auf 1085 Jahre.
von bbock
30.06.2023, 20:02
Forum: Programmierung
Thema: Übungen zu "Programmieren in C mit dem z88dk"
Antworten: 11
Zugriffe: 5743

Re: Übungen zu "Programmieren in C mit dem z88dk"

Deswegen float - damit geht's ganz einfach. Die Grundrechenarten mit langen Ganzzahlen zu implementieren wäre zwar auch möglich, ist aber wesentlich aufwändiger.
von bbock
30.06.2023, 19:04
Forum: Programmierung
Thema: Übungen zu "Programmieren in C mit dem z88dk"
Antworten: 11
Zugriffe: 5743

Re: Übungen zu "Programmieren in C mit dem z88dk"

Übung 2

Der Kaiser von China und der Reis

Der Kaiser von China spielt mit einem Bauern Schach. Nachdem er das Spiel verloren hat, ist der Kaiser großzügig und will dem Bauern jeden Wunsch erfüllen. Der Bauer gibt sich bescheiden und verlangt für das erste Schachfeld ein Reiskorn, für das zweite zwei Reiskörner, für das dritte vier Reiskörner usw. Er verlangt also für jedes Schachfeld doppelt so viele Reiskörner wie für das vorhergehende.

Das C-Programm soll das Schachfeld als zweidimensionalen float-Array abbilden. Jedes Element, also jeder float-Wert, soll die Anzahl der Reiskörner enthalten. Am Ende sollen die Reiskörner aller Felder aufsummiert und die Summe ausgegeben werden.

Nehmen wir ferner an, dass ein Reiskorn ca. 30 Milligramm wiegt, also 0,03 Gramm. Das Programm soll das Gesamtgewicht aller Reiskörner in Tonnen ausgeben.

Die Erntemenge an Reis weltweit beträgt heutzutage ca. 510 Millionen Tonnen. Das Programm soll auch die Anzahl Jahre ausgeben, die auf der ganzen Welt Reis geerntet werden muss, um den Wunsch des Bauern zu erfüllen.

Hinweis: Da wir float-Werte verwenden, benötigen wir die zcc-Option -lm.
von bbock
30.06.2023, 12:16
Forum: Programmierung
Thema: Programmieren in C mit dem z88dk
Antworten: 20
Zugriffe: 9467

17. Mehrdimensionale Arrays

Wir sind bereits in Kapitel 10.2 mit Arrays in Berührung gekommen. Die dort behandelten Beispiele waren eindimensionale Arrays, auch Vektoren genannt. Deren Elemente werden durch einen Index adressiert. Es gibt in C auch mehrdimensionale Arrays, deren Elemente mit zwei oder mehr Indizes adressiert werden; dementsprechend spricht man von zwei-, drei- oder mehrdimensionalen Arrays.
Ein zweidimensionaler Array mit zwei Zeilen und vier Spalten könnte z.B. so deklariert werden:

Code: Alles auswählen

int zweidim[2][4];
Möchte man ihn bei der Deklaration bereits initialisieren, dann geht das wie folgt:

Code: Alles auswählen

int zweidim[2][4] = {
                      {1, 2, 3, 4},
                      {5, 6, 7, 8}
                    };
Das veranschaulicht die zweidimensionale Struktur. Die Initialisierung ist aber auch folgendermaßen möglich:

Code: Alles auswählen

int zweidim[2][4] = {1, 2, 3, 4, 5, 6, 7, 8};
Werden nicht für alle Elemente Werte bei der Initialisierung angegeben, dann werden die übrigen Elemente automatisch mit 0 initialisiert. Fehlt die Initialisierung, dann sind die Elemente mit zufälligen Werten belegt, es sei denn, es handelt sich bei dem Array um eine globale oder um eine static-Variable: dann werden alle Elemente mit 0 initialisiert.

Wie man oben sieht, ist die Anzahl der Elemente eines mehrdimensionalen Arrays gleich dem Produkt der Dimensionen, in obigem Beispiel also 2 * 4 = 8 Elemente. Man beachte, dass mehrdimensionale Arrays schnell sehr groß werden können. So hat der vierdimensionale Array int vierdim[14][14][14][14] bereits 14*14*14*14 = 38.416 Elemente und belegt auf einem 8-Bit-System (int = 2 Bytes) 76.832 Bytes. Das sprengt bereits das 64k-Limit.

Als praktisches Beispiel wollen wir eine Quartalsabrechnung erstellen, ähnlich wie in einer Tabellenkalkulation:

Code: Alles auswählen

      Artikel1   Artikel2   Artikel3   Gesamt
Q1       15         98         35        148
Q2       23         47         52        122
Q3       48         32         14         94
Q4       47         56         76        179
Gesamt  133        233        177        543
Dazu verwenden wir einen zweidimensionalen Array:

Code: Alles auswählen

    int matrix[5][4] = {
        // Zeile: Artikel 1, Artikel 2, Artikel 3, Gesamt
        {15, 98, 35, 0}, // Q1
        {23, 47, 52, 0}, // Q2
        {48, 32, 14, 0}, // Q3
        {47, 56, 76, 0}, // Q4
        { 0,  0,  0, 0}  // Gesamt
    };
Die Zeilen- und Spaltensummen sind mit 0 initialisiert; wir werden die Werte im Programm berechnen.

Code: Alles auswählen

#include <stdio.h>

int main(void)
{
    int matrix[5][4] = {
        // Zeile: Artikel 1, Artikel 2, Artikel 3, Gesamt
        {15, 98, 35, 0}, // Q1
        {23, 47, 52, 0}, // Q2
        {48, 32, 14, 0}, // Q3
        {47, 56, 76, 0}, // Q4
        { 0,  0,  0, 0}  // Gesamt
    };
    unsigned char zeile, spalte;
    int sum;

    // Spaltensummen
    for (spalte = 0; spalte < 3; spalte++) {
        sum = 0;
        for (zeile = 0; zeile < 4; zeile++) {
            sum += matrix[zeile][spalte];
        }
        matrix[4][spalte] = sum;
    }

    // Zeilensummen
    for (zeile = 0; zeile < 5; zeile++) {
        sum = 0;
        for (spalte = 0; spalte < 3; spalte++) {
            sum += matrix[zeile][spalte];
        }
        matrix[zeile][3] = sum;
    }
    
    // Ausgabe
    printf("\tArt1\tArt2\tArt3\tGesamt\n");
    
    for (zeile = 0; zeile < 5; zeile++) {
        if (zeile < 4) {
            printf("Q%d\t", zeile + 1);
        }
        else {
            printf("Gesamt\t");
        }
        
        for (spalte = 0; spalte < 4; spalte++) {
            printf("%d\t", matrix[zeile][spalte]);
        }
        printf("\n");
    }
    
    return 0;
}
Hier ist das ganze Programm in der main-Funktion realisiert, was nicht besonders schön ist. Besser wäre es, das Programm in meherere Funktionen aufzuteilen; dabei lernen wir, wie man ein Array an eine Funktion übergibt:

Code: Alles auswählen

#include <stdio.h>

/* Calculates the sum for each column of the matrix. */
void calcColumnSums(int m[5][4]) {
    unsigned char zeile, spalte;
    int sum;

    for (spalte = 0; spalte < 3; spalte++) {
        sum = 0;
        for (zeile = 0; zeile < 4; zeile++) {
            sum += m[zeile][spalte];
        }
        m[4][spalte] = sum;
    }
}

/* Calculates the sum for each row of the matrix. */
void calcRowSums(int m[5][4]) {
    unsigned char zeile, spalte;
    int sum;

    for (zeile = 0; zeile < 5; zeile++) {
        sum = 0;
        for (spalte = 0; spalte < 3; spalte++) {
            sum += m[zeile][spalte];
        }
        m[zeile][3] = sum;
    }
}

/* Prints the quarterly statement. */
void printQuarterlyStatement(int m[5][4]) {
    unsigned char zeile, spalte;
    
    printf("\tArt1\tArt2\tArt3\tGesamt\n");
    
    for (zeile = 0; zeile < 5; zeile++) {
        if (zeile < 4) {
            printf("Q%d\t", zeile + 1);
        }
        else {
            printf("Gesamt\t");
        }
        
        for (spalte = 0; spalte < 4; spalte++) {
            printf("%d\t", m[zeile][spalte]);
        }
        printf("\n");
    }
}

/* The main function. */
int main(void)
{
    int matrix[5][4] = {
        // Zeile: Artikel 1, Artikel 2, Artikel 3, Gesamt
        {15, 98, 35, 0}, // Q1
        {23, 47, 52, 0}, // Q2
        {48, 32, 14, 0}, // Q3
        {47, 56, 76, 0}, // Q4
        { 0,  0,  0, 0}  // Gesamt
    };

    calcColumnSums(matrix);
    calcRowSums(matrix);
    printQuarterlyStatement(matrix);
    
    return 0;
}
Normalerweise verwenden alle Funktionsaufrufe call-by-value bei der Parameterübergabe. Die Ausnahme sind Arrays: hier wird nicht etwa eine Kopie des gesamten Arrays an die Funktion übergeben, sondern lediglich die Adresse des ersten Elements des Arrays. So kann eine Funktion wie calcColumnSums() die Inhalte der Variablen matrix in main() verändern ohne dabei besonders mit Pointern arbeiten zu müssen. Wir erinnern uns: Der Name eines Arrays ist ein Zeiger auf das erste Element.
von bbock
26.06.2023, 20:53
Forum: Programmierung
Thema: Fragen und Antworten zum C-Kurs
Antworten: 108
Zugriffe: 33931

Re: Fragen und Antworten zum C-Kurs

Paul hat geschrieben: 25.06.2023, 13:16 ...
Auch wenn der Kurs derzeit eingeschlafen ist.
...
Das mag am schönen Wetter liegen, der Kurs wird aber definitiv fortgesetzt. Es gibt noch mehrere Themen, die ich vorstellen möchte.
von bbock
26.06.2023, 20:48
Forum: Programmierung
Thema: Übungen zu "Programmieren in C mit dem z88dk"
Antworten: 11
Zugriffe: 5743

Re: Übungen zu "Programmieren in C mit dem z88dk"

Immerhin eine Lösung; die Verwendung der forms3-Bibliothek ist schon etwas für Fortgeschrittene.

Hier nun die Musterlösung mit der o.g. Eingabefunktion inputString:
lesson01.zip
(1.31 KiB) 242-mal heruntergeladen

Kompiliert wird mit

Code: Alles auswählen

zcc +cpm -subtype=pcw80 lesson01.c -o lesson01.com
von bbock
23.06.2023, 17:45
Forum: Programmierung
Thema: HP-GL Interpreter
Antworten: 48
Zugriffe: 99169

Re: noch neun Bilder

ein Thüringer hat geschrieben: 23.06.2023, 09:22 ...
Bernd, wird es eine Diashow-Funktion wie für VECREAD auch für PBMREAD geben?
...
Das lässt sich schon machen, denke ich. Vielleicht auch noch weitere Optionen; es ist wohl vor allem eine Frage der Zeit. ;)
von bbock
27.05.2023, 19:54
Forum: Programmierung
Thema: Übungen zu "Programmieren in C mit dem z88dk"
Antworten: 11
Zugriffe: 5743

Re: Übungen zu "Programmieren in C mit dem z88dk"

Solltet ihr Schwierigkeiten haben die Eingabe benutzerfreundlich hinzubekommen, dann hilft euch vmtl. folgende Eingaberoutine:

Code: Alles auswählen

#include <stdio.h>
#include <conio.h>

#define CH_BEEP        7
#define CH_BACKSPACE   8
#define CH_RETURN     10
#define CH_AT         22
#define CH_SZ        126
#define CH_DEL_LEFT  127


/* Input a string with up to maxlen characters via keyboard.
   Parameters: cp      pointer to character buffer
               maxlen  maximum input length allowed
 */
void inputString(char *cp, int maxlen) {
    char key;
    char *ptrBuf;
    int numChars;
    
    ptrBuf = cp;
    *ptrBuf = '\0'; // we start with an empty string
    numChars = 0;
    
    for (;;) {
        key = getch();
        
        if (key == CH_RETURN) { // finish input if <return> pressed
            putchar('\n');
            break;
        }
        
        if (numChars < maxlen) {
            if (key >  31 && key < 126 || // regular characters
                key >  90 && key <  94 || // uppercase Umlaut
                key > 122 && key < 126 || // lowercase Umlaut
//              key == CH_AT ||
                key == CH_SZ)
            {
                putchar(key);    // print character on screen
                *ptrBuf++ = key; // write key to buffer
                *ptrBuf = '\0';  // finalise string and point to the '\0' character
                ++numChars;
            }
            else {
                if (key == CH_DEL_LEFT && *cp != '\0') { // delete left and characters available
                    putchar(CH_BACKSPACE); // move left
                    putchar(' ');          // overwrite with blank
                    putchar(CH_BACKSPACE); // move left again
                    *--ptrBuf = '\0';      // shortens the string by 1 char
                    --numChars;
                }
                else {
                    putchar(CH_BEEP); // invalid key typed => beep
                }
            }
        }
        else {
            putchar(CH_BEEP); // maximum number of characters reached => beep
        }
    }
}
von bbock
06.05.2023, 18:07
Forum: Programmierung
Thema: Fragen und Antworten zum C-Kurs
Antworten: 108
Zugriffe: 33931

Re: Fragen und Antworten zum C-Kurs

Die Übungen zum C-Kurs werden in diesem Thema gesammelt. Auch eure Fragen und Lösungen sollen dort eingetragen werden. Nach einer gewissen Zeit werde ich eine Musterlösung anhängen.

Ich bin gespannt auf eure Mitarbeit! :)