Hallo Besucher, der Thread wurde 18k mal aufgerufen und enthält 50 Antworten

letzter Beitrag von logan am

C-Kurs, Abend 2

  • So, ich versuche mich mal auch am CC65, ich bin bei Abend 2. Habe in diesem Thread leider keine Lösungen zu Aufgabe 1 und 2 gesehen. ?(


    Aufgabe 1:

    Code
    1. #include <stdio.h>
    2. int main(void)
    3. {
    4. int result;
    5. result=puts("Wurstbrot");
    6. printf("result ist %d\n", result);
    7. }


    Warum wird hier eigentlich beim ausführen das Wort "Wurstbrot" ausgegeben ?
    int result //definition der Variablen "result"
    result=puts("Wurstbrot") //Definition der Funktion "result"
    printf... //Ausgabe des Textes "result ist..."
    Wo genau kommt denn hier der Text "Wurstbrot" zur Ausgabe ? (s.Bild)


    Aufgabe 2:

    Code
    1. #include <stdio.h>
    2. int main(void)
    3. {
    4. int result;
    5. int a=365;
    6. result=puts(a);
    7. printf("result ist %d\n", result);
    8. }


    Hier fehlt mir noch die Erklärung, warum dieser Fehler auftritt, und warum diese Grafikzeichen ausgegeben werden.

  • Warum wird hier eigentlich beim ausführen das Wort "Wurstbrot" ausgegeben ?


    Code
    1. int result //definition der Variablen "result"
    2. result=puts("Wurstbrot") //Definition der Funktion "result"
    3. printf... //Ausgabe des Textes "result ist..."


    Wo genau kommt denn hier der Text "Wurstbrot" zur Ausgabe ?


    die zweite zeile ist keine definition. dort wird die funktion puts() *aufgerufen*, welche "wurstbrot" ausgibt. und der von der funktion zurückgelieferte wert wird der variablen result zugewiesen ...

  • Aufgabe 1:

    Code
    1. #include <stdio.h>
    2. int main(void)
    3. {
    4. int result;
    5. result=puts("Wurstbrot");
    6. printf("result ist %d\n", result);
    7. }

    Warum wird hier eigentlich beim ausführen das Wort "Wurstbrot" ausgegeben?

    Du rufst die Funktion puts auf. Die gibt den String auf den Bildschirm aus (genau wie bei Abend 1). Dass ihr Rückgabewert jetzt einer Variablen zugewiesen wird, ändert daran nichts.


    Das ist in C übrigens mit allen Funktionen so. Sie werden immer gleich ausgeführt, egal ob ihr Rückgabewert weiter verwendet wird oder nicht.


    Aufgabe 2:

    Code
    1. #include <stdio.h>
    2. int main(void)
    3. {
    4. int result;
    5. int a=365;
    6. result=puts(a);
    7. printf("result ist %d\n", result);
    8. }

    Hier fehlt mir noch die Erklärung, warum dieser Fehler auftritt, und warum diese Grafikzeichen ausgegeben werden.

    Die Funktion puts erwartet einen String, also eine Zeichenkette, wir übergeben ihr aber einen Integer-Wert, also eine Zahl. In C werden Zeichenketten übergeben, indem man einen Zeiger (Pointer) auf die Speicherstelle, an der er beginnt, herumreicht. Die Zeichenkette geht dann bis zum ersten Auftreten des Wertes 0 in einer der folgenden Speicherstellen (0-terminated).


    Die Fehlermeldung „Converting integer to pointer without a cast“ bedeutet, dass 365 als Zeiger (Pointer) interpretiert wird, obwohl eigentlich nicht dazu aufgefordert wurde („without a cast“). Die komischen Grafikzeichen kommen dann zustande, weil die Werte, die im Speicher ab Zelle 365 stehen, ausgegeben werden.


    Reicht das als Erklärung?


  • die zweite zeile ist keine definition. dort wird die funktion puts() *aufgerufen*, welche "wurstbrot" ausgibt. und der von der funktion zurückgelieferte wert wird der variablen result zugewiesen ...


    Hm, wie würde ich denn eine reine Zuordnung erreichen, ohne die Funktion "puts" auszuführen ??? Meist verstehe ich das dann besser, wenn ich den Unterschied kenne.



    Die Funktion puts erwartet einen String, also eine Zeichenkette, wir übergeben ihr aber einen Integer-Wert, also eine Zahl. In C werden Zeichenketten übergeben, indem man einen Zeiger (Pointer) auf die Speicherstelle, an der er beginnt, herumreicht. Die Zeichenkette geht dann bis zum ersten Auftreten des Wertes 0 in einer der folgenden Speicherstellen (0-terminated).


    Die Fehlermeldung „Converting integer to pointer without a cast“ bedeutet, dass 365 als Zeiger (Pointer) interpretiert wird, obwohl eigentlich nicht dazu aufgefordert wurde („without a cast“). Die komischen Grafikzeichen kommen dann zustande, weil die Werte, die im Speicher ab Zelle 365 stehen, ausgegeben werden.


    Reicht das als Erklärung?


    Also würde auch bei einem String, der Funktion puts immer nur ein Pointer übergeben werden. So wie ich es in meinem Quellcode getan habe, nur dass die manuelle Übergabe eines Pointers nicht vorgesehen ist, und von daher vom Compiler bemängelt wird ???

  • Hm, wie würde ich denn eine reine Zuordnung erreichen, ohne die Funktion "puts" auszuführen ??? Meist verstehe ich das dann besser, wenn ich den Unterschied kenne.

    Warum solltest Du das tun wollen? Wenn Du result = 666 schreibst, wird natürlich nichts ausgeführt, sondern nur der Wert zugewiesen, da auf der rechten Seite keine Funktion steht. Wenn auf der rechten Seite eine Funktion steht, wird sie inklusive aller Seiteneffekte (die bei puts und vielen anderen Funktionen eher der eigentliche Sinn sind) ausgeführt.


    Also würde auch bei einem String, der Funktion puts immer nur ein Pointer übergeben werden. So wie ich es in meinem Quellcode getan habe, nur dass die manuelle Übergabe eines Pointers nicht vorgesehen ist, und von daher vom Compiler bemängelt wird ???

    Der Compiler bemängelt, dass es nicht so aussieht, als wolltest Du bewusst 365 als Pointer verwenden (dann sollte sie einen anderen Typ als int haben, aber das kommt später im Kurs bestimmt noch genauer ...). Die manuelle Übergabe eines Pointers ist also durchaus möglich, aber wie genau das funktioniert, würde so früh wirklich zu weit führen.


    Wenn Du etwas wie puts("Hallo Welt!"); schreibst, setzt der Compiler das so um, dass er den String "Hallo Welt!" in einen bestimmten Speicherbereich (abgeschlossen mit einer 0) schreiben lässt. Die Anfangsadresse dieses Bereichs wird dann puts übergeben.


    In Abend 4 und 5 wird erklärt, wie Du Dir das Assembler-Zwischenergebnis angucken kannst. Wenn Du Assembler kannst, wird das dann vielleicht ein wenig klarer.

  • Hm, wie würde ich denn eine reine Zuordnung erreichen, ohne die Funktion "puts" auszuführen ??? Meist verstehe ich das dann besser, wenn ich den Unterschied kenne.


    damit hast du "den wunden punkt" von c berührt: auch wenn oft von strings gesprochen wird, gibt es in c keine "echten" strings. der compiler packt die (unveränderlichen) zeichen irgendwohin und operiert nur mit der anfangsadresse (pointer) des stringliterals ...


    Also würde auch bei einem String, der Funktion puts immer nur ein Pointer übergeben werden. So wie ich es in meinem Quellcode getan habe, nur dass die manuelle Übergabe eines Pointers nicht vorgesehen ist, und von daher vom Compiler bemängelt wird ???


    ... genau, siehe oben : )

  • Sehr schöner Kurs. :zustimm: Da kann ich endlich mal was neues lernen.


    Bei der letzten Aufgabe ist mir folgendes aufgefallen:



    Das \n in puts("=====\n"); erzeugt bei mir eine zusätzliche Leerzeile, also genau anders rum wie in den Posts 29-30 beschrieben. Ist das ein Bug im aktuellen Source von CC65 oder hab ich da was verpasst?

  • Das \n in puts("=====\n"); erzeugt bei mir eine zusätzliche Leerzeile, also genau anders rum wie in den Posts 29-30 beschrieben. Ist das ein Bug im aktuellen Source von CC65 oder hab ich da was verpasst?


    In Post 30 ist schon die korrigierte Version des dort beschriebenen Problems. Dort wurde ursprünglich printf benutzt, aber ohne '\n', also wurde kein Zeilenumbruch ausgegeben. In der korrigierten Version wurde das angehängt.


    In dem Listing von Dir wird puts benutzt. Diese Funktion gibt von sich aus schon einen Zeilenumbruch aus. Ist außerdem im String einer enthalten, wird der zusätzlich ausgegeben. Das führt zu einer Leerzeile (zweimal Zeilenumbruch).

  • Das hab ich übersehen, dass da ein printf benutzt wurde. Problem gelöst. :)


    Edit:
    Mein prg mit puts ist 2,9kb und das mit nur printf-Anweisungen ist nur 2,7kb groß. Also sollte man schon überlegen welche Befehle benutzt.


    Und noch eine Auffälligkeit: Wenn ich das prg ausführe wird auf Kleinschrift umgeschaltet.