Autor Thema: Gemeinschaftsprojekt?  (Gelesen 75652 mal)

0 Mitglieder und 3 Gäste betrachten dieses Thema.

Offline Dennis Schulmeister

  • Moderator
  • *****
  • Beiträge: 535
  • Do be do be do -- Sinatra.
Re: Gemeinschaftsprojekt?
« Antwort #60 am: Mi 29.06.2011, 21:25:11 »
Hallo,

Singemäß wäre das so:

void main(int, char**);
void recursive_function(int, int);

void recursive_function(int amount, int max_depth) {
   int count = amount + 1;

   if (count > max_depth) {
      return;
   }

   printf("%i ", count);
   recursive_function(count, max_depth);
}

void main(int argc, char** argv) {
  recursive_function(0, 10);
  return 0;
}

count ist hier eine lokale Variable, die auf dem Stack liegt und somit nur innerhalb der Funktion existiert. Ruft sich die Funktion selbst nochmal auf, entsteht ein neuer Stack Frame, auf dem dieselbe Variable aber mit anderem Wert liegt. Nach Verlassen der rekursiv aufgerufenen Funktion befindet sich das Programm wieder im urpsünglichen Aufruf, wo die Variable wieder ihren alten Wert besitzt.

Die Ausgabe des Programms (wenn der Formatstring für printf stimmt) ist also: 1 2 3 4 5 6 7 8 9 10

Gruß,
Dennis
Wenn ich mal groß bin, will ich bei Atari arbeiten.

Offline Dennis Schulmeister

  • Moderator
  • *****
  • Beiträge: 535
  • Do be do be do -- Sinatra.
Re: Gemeinschaftsprojekt?
« Antwort #61 am: Mi 29.06.2011, 21:27:20 »
PS: Vertauscht man folgende Zeilen, ist die Ausgabe des Programms 10 9 8 7 6 5 4 3 2 1, was den Sachverhalt noch besser verdeutlicht.

   printf("%i ", count);
   recursive_function(count, max_depth);
Wenn ich mal groß bin, will ich bei Atari arbeiten.

Offline simonsunnyboy

  • Moderator
  • *****
  • Beiträge: 1.808
  • Rock'n'Roll is the thing - Jerry Lee is the king!
Re: Gemeinschaftsprojekt?
« Antwort #62 am: Mi 29.06.2011, 21:54:11 »
Im tos.hyp steht übrigens alles was ihr braucht %)

http://toshyp.atari.org/de/005014.html#DTA
Paradize - ST Offline Tournament
Stay cool, stay Atari!
1x2600jr, 1x1040STFm, 1x1040STE 4MB+TOS2.06+SatanDisk, 1xF030 14MB+FPU+NetUS-Bee

Offline m0n0

  • Benutzer
  • Beiträge: 984
Re: Gemeinschaftsprojekt?
« Antwort #63 am: Mi 29.06.2011, 22:24:16 »
Ok, hier ist Teil 2.

Code:
(Vorsicht, kommentare sind etwas abweichend von denen im Zip Archiv, da fehlt ein kleiner absatz - aber sind ja nur kommentare ;) )

/* funktionen wie memcpy, strcpy... bekannt machen: */
#include <string.h>

/* auch die standard funktionen bekannt machen:     */
#include <stdlib.h>
#include <stdio.h>

/* Standard TOS funktionen bekannt machen:          */

#include <tos.h>
#include <vdi.h>

/* Textbildschirm Funktionen bekannt machen         */
/* Diese Datei enthaelt makros (d.h. nichts anderes */
/* als Aliase fuer bestimmte kommandos, wer         */
/* interesse hat, was ich meine, schut einmal kurz  */
/* die Datei hinein                                 */
#include <screen.h>


/* Ein string konstante definieren:                 */
/* __DATE__ ist standard und wird vom               */
/* Compiler auf das aktuelle Datum gesetzt          */

#define VERSION     "0.1 - (" __DATE__ ")"


/* Neue (eigene) funktion textxy,                   */
/* ------------------------------------------------ */
/* Diese Funktion ist im gegensatz zu main() nicht  */
/* Pflicht. Es ist eine völlig eigens definierte    */
/* Funktion die machen kann was sie will, bzw. was  */
/* wir wollen.                                      */
/* man koennte sich auch anders benennen oder andere*/
/* dinge tun lassen....                             */
/* ------------------------------------------------ */
/* mit dieser Funktion kann man einen text an einer */
/* bestimmten stelle am Bildschirm ausgeben.        */
/* Die ersten beiden Parameter bestimmen die        */
/* Postion, sie sind vom typ short - das heisste    */
/* bei purec: 16 bit maximalwert.                   */
/* der parameter inv bestimmt ob schwarz auf weiss  */
/* oder weiss auf schwarz ausgegeben werden soll    */
/* der letzte parameter beinhaltet eine             */
/* Speicheradresse an die auszugebenden buchstaben  */
/* stehen, das ende der buchstaben wird durch ein   */
/* null byte markiert. (Uebernimmt der compiler     */
/* fuer gewoehnlich                                 */
/* Wichtig ist, das diese Funktion ueber main()     */
/* ausprogrammiert wird, bzw. vor jeder anderen     */
/* funktion in der diese funktin genutzt werden soll*/
/* der compiler kann nur aufrufen was er kennt....  */
/* es gibt auch die moeglichkeit funkt. aufzurufen  */
/* die nach dem aufruf ausprogrammiert sind.        */
/* aber das benoetigt eine vorherige "deklaration"  */
/* - darauf verzichten wir in diesem projekt        */

void textxy(short x, short y, short inv, char * str)
{
    /* wenn parameter inv (invertiert) ungleich 0   */
    /* ist-dann wird der reverse mode eingeschaltet */
    /* d.h. weiss auf schwarze ausgabe              */
    if( inv != 0 ) {
        /* Makro das in screen.h definiert wurde:   */
        Rev_on();
    }
    /* Jetzt wird der cursor an die gewuenschte     */
    /* Stelle gesetzt, diese anweisung ist ebenfalls*/
    /* in screen.h definiert                        */
    Goto_pos( y, x );
    
    /* Diese funktion kennen wir schon:             */
    /* wir merken: Cconws gibt immer an der moment. */
    /* cursor-position den text aus.                */
    Cconws( str );
    
    /* wenn inv ungleich 0 ist, dann wird der       */
    /* modus wieder auf normal gesetzt.             */
    if( inv != 0  ) {
        Rev_off();
    }
}

/* Hauptprogramm, wird aufgerufen nach start des Programms: */
int main(void)
{
    /* Anstatt Cconws rufen wir jetzt   */
    /* unsere eigene Textausgabe routine*/
    /* auf! */
    /* Spalte 2, Zeile 1, Invers, Text */

    textxy( 3, 1, 1,"SimpleBoot Version " VERSION );

    
    /* am ende wird nochmal ein Ruecklauf /         */
    /* Zeilenumbruch ausgegeben, damit die Konsole  */
    /* auf der wir ausgeben "sauber" ist.           */
    /* (testet einfach mal was passiert wenn man es */
    /* weglaesst.                                   */

    Cconws("\r\n");

    
    /* da die funktion main() den rueckgabetyp "int"*/
    /* (je nach compiler einstellung 16 oder        */
    /*  32 bit zahl) hat, muss ein entsprechender   */
    /* wert zurueckgegeben werden - 0 bedeutet: kein*/
    /* fehler.                                      */

    return( 0 );
}


P.S.: Wer unter Magic entwickelt, der kann das Programm mit der mitgelieferten Konsole/Shell laufen lassen ( cmd.prg ? ) .  Unter purem TOS kann ich dieses Programm empfehlen:

http://www.umich.edu/~archive/atari/Cli/ashell.lzh

(Aber eigentlich nur weil ich kein anderes kenne .... )

Unter FreeMiNT kann man das ganze gut mit Conholio oder Toswin2 testen.  

« Letzte Änderung: Mi 29.06.2011, 22:27:54 von m0n0 »

Offline Arthur

  • Benutzer
  • Beiträge: 10.311
  • Mein Atari erinnert mich an die gute alte Zeit..
Re: Gemeinschaftsprojekt?
« Antwort #64 am: Do 30.06.2011, 00:31:36 »
Ich hab die Projektdatei für ahcc selbst angepasst und es kompiliert. Da ich keine Konsole benutze hab ich ein getchar (); hinter die Textausgabe gepackt so dass das Programm erst nach einem Tastendruck beendet wird.

    textxy( 3, 1, 1,"SimpleBoot Version " VERSION );
    getchar();


« Letzte Änderung: Mo 12.05.2014, 22:22:06 von Arthur »

Offline ragnar76

  • Benutzer
  • Beiträge: 527
Re: Gemeinschaftsprojekt?
« Antwort #65 am: Do 30.06.2011, 10:20:31 »
Mal kurz nachgefragt, mit wem muss man eigentlich schlafen damit man qed als ide für purec/ahcc benutzen kann?


Offline simonsunnyboy

  • Moderator
  • *****
  • Beiträge: 1.808
  • Rock'n'Roll is the thing - Jerry Lee is the king!
Re: Gemeinschaftsprojekt?
« Antwort #66 am: Do 30.06.2011, 17:17:12 »
Mit keinem - bei AHCC einfach den TTP-Compiler benutzen, das ist dann nur noch nicht voll integriert.

Wie man eine volle Integration in qed reinkonfigurieren kann, würde mich allerdings auch sehr interessieren.
Paradize - ST Offline Tournament
Stay cool, stay Atari!
1x2600jr, 1x1040STFm, 1x1040STE 4MB+TOS2.06+SatanDisk, 1xF030 14MB+FPU+NetUS-Bee

Offline m0n0

  • Benutzer
  • Beiträge: 984
Re: Gemeinschaftsprojekt?
« Antwort #67 am: Mo 04.07.2011, 19:47:16 »
Ich bin mir sicher das der geneigte Leser noch nicht alles verstanden hat - z.b. diese Deklaration:

void textxy(short x, short y, short inv, char * str);

das interessante hieran ist der letzte Parameter - hier wird dem Compiler mitgeteilt das es sich hierbei um einen Zeiger handelt ( markierung: * ) und ausserdem auch noch auf was für daten der Zeiger zeigt. Nämlich auf char.

Für den letzten Parameter wird der Funktion also mitgeteilt wo eine bestimmte Zeichenkette liegt.

Anders bei den vorherigen Parametern, hierbei handelt es sich nicht um Zeichenketten und auch nicht um Zeiger. Es sind einfach Werte die der Funktion übergeben werden.

Ein entscheidender Unterschied ist...: wenn wir die short paramter innerhalb der Funktion verändern (z.b.: x=x+10), dann hat das keine Auswirkungen auf das nachfolgende Programm .... die Parameter wurden der Funktion als Kopie übergeben. Anders die Zeichenkette - diese Existiert nur einmal - und anstatt das eine Kopie der Zeichenkette an die Funktion übergeben wird ( geht auch...) wird der Funktion nur mitgeteilt wo sich im Speicher eine bestimmte Zeichenkette befindet. Die funktion könnte nun nach belieben diese Zeichenkette verändern - und nachfolgende Funktionen würden dann mit der veränderten Zeichenkette (das nennt man übrigens String ;) ) arbeiten.

sonst noch fragen ?



 

Offline Arthur

  • Benutzer
  • Beiträge: 10.311
  • Mein Atari erinnert mich an die gute alte Zeit..
Re: Gemeinschaftsprojekt?
« Antwort #68 am: Mo 04.07.2011, 22:36:36 »
Ich bin mir sicher das der geneigte Leser noch nicht alles verstanden hat - z.b. diese Deklaration:

void textxy(short x, short y, short inv, char * str);

Ich frag einfach mal so. Also mit void textxy wird die Funktion textxy deklariert oder definiert....

short x ist bedeutet das die Funktion einen Parameter "x" vom Typ short beim Aufruf erwartet....genau so auch bei y und inv

char ist eine Anzahl von Zeichen und der * besagt das str ein Zeiger auf char ist?

Ist denn str ein reservierter Begriff oder kann das ein belibieger Name sein?

Offline m0n0

  • Benutzer
  • Beiträge: 984
Re: Gemeinschaftsprojekt?
« Antwort #69 am: Mo 04.07.2011, 23:21:55 »
Zitat
Ist denn str ein reservierter Begriff oder kann das ein belibieger Name sein?

str ist nicht reserviert, man koennte es auch text nennen - es ist dann halt der name des parameters - folglich muss man dann aber natuerlich alle vorkommen von "str" mit "text" - denn sonst wird der kompiler sage das man eine variable verwenden will die nirgendwo deklariert / definiert etc. ist.   

Genauso koennen auch x und y ubennannt werden, z.b. in xpos, ypos oder so....

Offline m0n0

  • Benutzer
  • Beiträge: 984
Re: Gemeinschaftsprojekt?
« Antwort #70 am: Mo 04.07.2011, 23:26:06 »
Zitat
char ist eine Anzahl von Zeichen und der * besagt das str ein Zeiger auf char ist?

Nicht ganz richtig... char ist eigentlich nur ein zeichen.
es handelt sich hierbei also um einen zeiger auf ein zeichen. daraf folgen aber noch mehrere... der string wird durch 0 terminiert...

Cconws gibt also ein zeichen aus, erhoert den zeiger um 1 ( char = 1 byte) und wenn der speicherinhalt dort keine 0 ist wird das zeichen ausgegeben - wenn es eine 0 ist, beendet die funktion sich....

Offline Arthur

  • Benutzer
  • Beiträge: 10.311
  • Mein Atari erinnert mich an die gute alte Zeit..
Re: Gemeinschaftsprojekt?
« Antwort #71 am: Mo 04.07.2011, 23:53:06 »
Wo hatten wir denn str schon definiert? Oder reichte es aus das es in der Funktion als Parameter declariert wurde?
« Letzte Änderung: Mo 04.07.2011, 23:57:06 von Arthur »

Offline m0n0

  • Benutzer
  • Beiträge: 984
Re: Gemeinschaftsprojekt?
« Antwort #72 am: Di 05.07.2011, 09:52:13 »
ja, genau. das reicht aus - jedenfalls für parameter.

Offline Arthur

  • Benutzer
  • Beiträge: 10.311
  • Mein Atari erinnert mich an die gute alte Zeit..
Re: Gemeinschaftsprojekt?
« Antwort #73 am: Di 05.07.2011, 20:30:08 »
Ok, wir haben jetzt schon ein Programm das die Versionsnummer und das Compilierungsdatum ausgibt und zwar über unsere Funktion textxy.

In welcher Bildschirmauflösung soll das Programm eigentlich später laufen...oder in welcher besser nicht? Macht es Sinn für textxy die Auflösung vorher abzufragen?

Offline m0n0

  • Benutzer
  • Beiträge: 984
Re: Gemeinschaftsprojekt?
« Antwort #74 am: Di 05.07.2011, 21:23:38 »
Zitat
In welcher Bildschirmauflösung soll das Programm eigentlich später laufen...oder in welcher besser nicht? Macht es Sinn für textxy die Auflösung vorher abzufragen?

genau das ist ja das Problem das von Simon angesprochen wurde, und was ich auch bei der Firebee bemerkt habe...

Auf den meisten Systemen kann man beim Autostart die Auflösung abfragen. VDI funktioniert und LineA wohl auch... - Simon meint jedoch VDI darf man nicht bzw. das würde nicht gehen. bei der FireBee ist es zur Zeit wirklich nicht möglich.  Aber Didier hat da letztens einen Bug gefixt der es evt. doch möglich macht - nicht über VDI, aber evt. doch über lineA.

Unbedingt notwendig ist das Abfragen der Auflösung nicht. Wenn man jedoch etwas in der letztens Zeile/Spalte Ausgeben will,.... dann sollte man das schon wissen.

Wir werden uns erstmal nicht um die Auflösung kümmern. Im schlimmsten fall - also wenn man x,y koordinaten angibt die zu gross für die Momentane Ausgabefläche sind, dann werden Bereiche Überschrieben, d.h. wenn es nur 20 Zeilen gibt, aber man schreibt auf Zeile 21, dann wird Zeile 20 Überschrieben.

Die x,y koordinaten sind übrigens keine Pixelkoordinaten sondern zeilen/spalten.

« Letzte Änderung: Di 05.07.2011, 21:25:59 von m0n0 »

Offline m0n0

  • Benutzer
  • Beiträge: 984
Re: Gemeinschaftsprojekt?
« Antwort #75 am: Di 05.07.2011, 21:36:36 »
Der nächste Schritt wird sein, in einer Endlosschleife alle Benutzereingaben abzufragen und wenn der Benutzer den Buchstaben Q eingibt dann beendet sich das Programm.

Offline m0n0

  • Benutzer
  • Beiträge: 984
Re: Gemeinschaftsprojekt?
« Antwort #76 am: Di 05.07.2011, 23:22:55 »
Ok, aufgrund der grossen nachfrage - hier ist ist step3.  ;D

#include <string.h>


#include <stdlib.h>

#include <stdio.h>


#include <tos.h>

#include <vdi.h>

#include <screen.h>




#define VERSION     "0.1 - (" __DATE__ ")"





/* Diese Variable vom typ short (16 Bit bei PureC)  */

/* ist neu im Programm!                             */

/* ------------------------------------------------ */

/* Da sie ausserhalb von einer Funktion deklariert  */

/* wird - ist sie berall in dieser Datei erreichbar*/

/* also in jeder Funktion. Variablen die innerhalb  */

/* einer funktion deklariert werden, sind nur so    */

/* lange "am leben" wie die funktion l„uft...,      */

/* solche Variablen nennt man dann "Lokale" Variabl.*/

/* Aber dies hier ist eine "Globale" Variable       */

/* Alle globalen Variablen werden mit 0             */

/* initialisiert - zumindest bei C                  */

/* Das heisst "short quit;" ist gleichbedeutend mit */

/* "short quit = 0;"                                */

/* Das gillt aber nur fr Globale Variablen!!!      */

/* Lokale Variablen enthalten Speicher Schrott -bis */

/* ihnen das erste mal ein Wert zugewiesen wird.    */

/* D.h. - Lokale Variable immer anfangs mit einem   */

/* Startwert versehen!                              */

/* Wir benutzen diese Variable um das Programm      */

/* von verschiedenen Stellen aus beenden zu koennen */

/* aber seht selbst... */

short quit;





/* ------------------------------------------------ */

/* mit dieser Funktion kann man einen text an einer */

/* bestimmten stelle am Bildschirm ausgeben.        */

/* Die ersten beiden Parameter bestimmen die        */

/* Postion (X = Spalte, Y=Zeile)                    */

/* der parameter inv bestimmt ob schwarz auf weiss  */

/* oder weiss auf schwarz ausgegeben werden soll    */

/* der letzte parameter beinhaltet eine             */

/* Speicheradresse an der die auszugebenden         */

/* buchstaben stehen                                */



void textxy(short x, short y, short inv, char * str)

{

    /* wenn parameter inv (invertiert) ungleich 0   */

    /* ist-dann wird der reverse mode eingeschaltet */

    /* d.h. weiss auf schwarze ausgabe              */

    if( inv != 0 ) {

        /* Makro das in screen.h definiert wurde:   */

        Rev_on();

    }

    /* Jetzt wird der cursor an die gewuenschte     */

    /* Stelle gesetzt, diese anweisung ist ebenfalls*/

    /* in screen.h definiert                        */

    Goto_pos( y, x );



    /* Diese funktion kennen wir schon:             */

    /* wir merken: Cconws gibt immer an der moment. */

    /* cursor-position den text aus.                */

    Cconws( str );



    /* wenn inv ungleich 0 ist, dann wird der       */

    /* modus wieder auf normal gesetzt.             */

    if( inv != 0  ) {

        Rev_off();

    }

}







/* Neue Funktion "input()"                          */

/* ------------------------------------------------ */

/* Diese Funktion liest ein Zeichen und reagiert    */

/* darauf...                                        */

void input( void )

{

    /* Zeichen in eine 32 Bit Variable einlesen:    */

    /* hierbei ist wichtig:                         */

    /* sobald GEM geladen wurde, hat diese Funktion */

    /* ein bisschen andere Rueckgabewerte           */

    /* fuer einige Tasten - z.B. Funktionstasten    */

    /* unter GEM bekommen wir immer einen ASCII     */

    /* Wert ...                                     */

    /* Will man also die Funktionstasten abfragen   */

    /* im autostart - dann muss das anders erfolgen */

    /* als unter GEM... aber dazu mehr in den       */

    /* naechsten folgen. Jetzt wird erstmal nur ein */

    /* Buchstabe eingelesen!                        */

    long key = Cnecin();



    /* momentan interessiert uns nur der Ascii wert */

    /* der Taste....                                */

    /* Es gibt auch Tasten bei denen der ASCII Wert */

    /* 0 ist.... da interessiert uns dann ein       */

    /* anderer Bereich der Zahl....                 */

    /* Hier wird jetzt das Ascii Byte des Tasten    */

    /* codes durch eine Bin„re Und verknpfung      */

    /* extrahiert... bzw. alles andere ausgeblendet */

    /* Der Ascii wert befined sich am ersten byte   */

    /* der 4 byte variable ( 4 byte = 32 bit):      */



    char ascii = (key & 0xFF);



    /* Darauf achten das die Buchstaben - anders    */

    /* als Zeichenketten - in einzelne anfhrungs-  */

    /* gesetzt sind!!!                              */

    /* der buchstabe wird daraufhin vom compiler    */

    /* in den "(Atari)-Ascii" Wert gewandelt.       */

    /* anstatt 'Q' koennte man auch die Zahl        */

    /* 81 nehmen - der Ascii wert fuer Q. Aber so   */

    /* ist es besser zu lesen!                      */

/* Hier wird jetzt abgefragt ob der Buchstabe */

/* das Kommando zum beenden enthaelt... */

    if( ascii == 'Q' || ascii == 'q' ){

        quit = 1;

    } else {

        /* hier wird der wert der variablen ausgegeben  */

        /* nur fuer informationszwecke                  */

        /* ich gehe nicht naeher darauf ein             */

        /* es ist nur fuer info zwecke gedacht          */

        /* wer mehr wissen will schaut in andere        */

        /* dokumente....                                */

        printf("ascii: %d - keycode: %lu\n", ascii, key );

    }



}



/* Hauptprogramm, wird aufgerufen nach start des Programms: */

int main(void)

{

    /* Anstatt Cconws rufen wir        */

    /* unsere eigene Textausgabe routine*/

    /* auf! */

    /* Spalte 2, Zeile 10, Invers, Text */



    textxy( 3, 1, 1,"SimpleBoot Version " VERSION );



    /* Hier haben wir ein neues Programm-konstrukt  */

    /* eine schleife! Diese wird solange wiederholt */

    /* bis die bedingung innerhalb der klammern     */

    /* nicht mehr zutrifft                          */

    /* konkret wird hier immer wieder ein Buchstabe */

    /* eingelesen - es sei denn die Variable quit   */

    /* enthaelt den Wert 1 - dann wird nicht weiter */

    /* gemacht...                                   */



    while( quit != 1 ) {

        input();

    }





    /* da die funktion main() den rueckgabetyp "int"*/

    /* (je nach compiler einstellung 16 oder        */

    /*  32 bit zahl) hat, muss ein entsprechender   */

    /* wert zurueckgegeben werden - 0 bedeutet: kein*/

    /* fehler.                                      */



    return( 0 );

}


[code]

[/code]

Offline Arthur

  • Benutzer
  • Beiträge: 10.311
  • Mein Atari erinnert mich an die gute alte Zeit..
Re: Gemeinschaftsprojekt?
« Antwort #77 am: Mi 06.07.2011, 02:36:26 »
Die ahcc.prj im STEP3.ZIP.PDF Anhang mag funktionieren aber für den AHCCST muß in der ahcc.prj statt der AHCCSTD.LIB die AHCCSTDI.LIB benutzt werden da erstere dort nicht vorhanden ist und sich der Linker sonst beschwert.

Offline m0n0

  • Benutzer
  • Beiträge: 984
Re: Gemeinschaftsprojekt?
« Antwort #78 am: Mi 06.07.2011, 11:10:21 »
Ich teste vorher alle mit der AHCC020 Version.

Offline m0n0

  • Benutzer
  • Beiträge: 984
Re: Gemeinschaftsprojekt?
« Antwort #79 am: Mo 11.07.2011, 17:10:03 »
Ok, jetzt gibt es anstatt einer neuen version eine Haus-Aufgabe ;)

Schreibt das Programm so um - das bei Taste 'A' eine Meldung auf dem Bildschirm erscheint ... z.b.: "Taste A gedrueckt.".

Dafür rufe ich nochmal das if-else if-else konstrukt ins Gedächtnis:

Zitat
if( key == 'Q' ){
 // beenden
}
else if( key == 'A' ) {
 // ausgabe machen
}
else {
 // nix...
}