Typumwandlung



  • Hmm nee, mit sicher und unsicher hat das nichts zu tun. Ob nun explizit oder implizit gecastet wird ist egal, es kommt dasselbe raus. Es ist nur entscheidend wenn es keinen impliziten cast gibt.
    Wenn du einem int ein float zuweist wird das float in ein int gecastet, egal ob du es explizit hinschreibst oder nicht. Wenn du hingegen printf benutzt, dann weiß keiner dass eigentlich gecastet werden muss und dann wird einfach nicht gecastet und es kommt Müll raus.
    Oder ein anderes Beispiel, du willst aus einem struct bla pointer ein struct blub pointer machen. Es gibt keine implizite Regel wie man aus bla blup macht, also musst du wirklich (struct blup) vor bla schreiben.



  • nwp2 schrieb:

    Hmm nee, mit sicher und unsicher hat das nichts zu tun. Ob nun explizit oder implizit gecastet wird ist egal, es kommt dasselbe raus. Es ist nur entscheidend wenn es keinen impliziten cast gibt.

    wenn implizit gecastet wird hat sich der programmierer in 99,9999% der fälle keinen gedanken darüber gemacht wie und wo warum gecastet wird, dadurch entstehen fehler... man castet ja auch nicht ständig x nach y sondern macht das eher selten und dann schreibt man das dazu.



  • Ich denke, dass ich es jetzt verstanden habe.

    Innerhlab von "printf" ist "(int)" notwendig damit am Ende "2" herauskommt. Ansonsten kommt ein falscher Wert heraus; hier "0".

    #include <stdio.h>
    
    int main()
    {
    float a = 2.5;
    printf("Zahl (expliziter Cast): %d\n", (int)a);
    printf("Zahl (impliziter Cast): %d\n", a);
    return 0;
    }
    

    Aber bei einem Cast außerhalb von "printf" ist es egal, ob man die Variable explizit castet. Der Wert wird nicht verfälscht. Das Ergebnis ist "2".

    #include <stdio.h>
    
    int main()
    {
    int b;    
    float a = 2.5;
    b=a; //einfache Zuordnung; das ist doch weder implizit noch explizit
    printf("Zahl: %d\n",b);
    return 0;
    }
    

    Falls auch dieser Ansatz falsch sein sollte bitte ich um Geduld.
    Bei weiteren Versuchen mir dieses Thema zu erklären wäre ich für Beispiele dankbar.

    Ich bedanke mich für die schnellen und hilfreichen Antworten, die bisher geleistet worden sind und bzw. noch folgen werden.



  • nwp2 schrieb:

    Es gibt aber auch Fälle wo das nicht so ist.

    Sowas hier zum Beispiel:

    char c = 'a';
    printf("'a' hat die Zahl %d\n", (int)a);
    

    Wenn du hier das (int) weg lässt kommt Blödsinn raus, weil printf ein int erwartet, das hat zum Beispiel 4 Byte, a hat aber nur 1 Byte.

    Ich glaube du verwechselst das gerade mit scanf()



  • Dein b=a enthält einen impliziten Cast von float nach int.
    Du kennst doch bestimmt malloc.
    malloc gibt einen void * zurück. Unter C gibt es eine implizite Regel die es erlaubt einen void * in jeden anderen Pointer umzuwandeln. Deshalb kannst du sowas schreiben:

    int *i = malloc(sizeof(int));
    

    Unter C++ gibt es diese Regel nicht. Deshalb funktioniert obiger Code nicht, dort musst du explizit casten:

    int *i = (int *)malloc(sizeof(int));
    

    Hier noch ein etwas gemeines Beispiel:

    #include <stdio.h>
    
    struct test{
        int x;
        int y;
    };
    
    int main(){
    	printf("sizeof(test): %d, 4-sizeof(test): %d\n", sizeof(test), 4-sizeof(test));
    	if (4-sizeof(test)<0) printf("4-sizeof(test) ist kleiner als 0\n");
    	else printf("4-sizeof(test) ist nicht kleiner als 0\n");
    	return 0;
    });
    

    Die überraschende Ausgabe:
    ^sizeof(test): 8, 4-sizeof(test): -4
    4-sizeof(test) ist nicht kleiner als 0^

    Das liegt daran, dass sizeof(test) ein unsigned int ist und 4 ein signed int. Die implizite Regel sagt, dass wenn signed und unsigned ints zusammengerechnet werden dass signed int in unsigned int umgecastet wird. Und ein unsigned int wird niemals kleiner als 0. printf weiß das nicht, ich habe ihm %d gesagt, das ist ein signed int, deswegen gibt er -4 aus. Der Ausdruck in der if-Klammer tut allerdings Blödsinn, weil 4-sizeof(test) 4294967292 ist und nicht -4, weil (unsigned int)-4 4294967292 ist.
    Wenn man in die if-Klammer ein 4-(int)sizeof(test) schreibt funktioniert alles wie erwartet.

    Also halte dich an noobLolo Rat und caste möglichst immer explizit wenn du verschiedene Datentypen mischst, die impliziten Regeln tun manchmal nicht was man meint.

    @Tim: Nö. scanf hat dasselbe Problem, aber ich meine schon printf.



  • nwp2 schrieb:

    @Tim: Nö. scanf hat dasselbe Problem, aber ich meine schon printf.

    Mit welchem Compiler auf welchem System und welcher Mondstellung kommt also bei diesem Code:

    char c = 'a';
    printf("'a' hat die Zahl %d\n", a);
    

    nicht das offensichtliche heraus?



  • Hmm, komisch, irgendwie kriege ich ihn nicht dazu Blödsinn zu printen. Wahrscheinlich packt er immer 4 Bytes als Parameter auf den Stack, deswegen wirkt sich das nicht aus.
    Aber das Prinzip ist klar, man gibt ihm ein Byte und er soll das als 4 Byte interpretieren, wodurch 3 undefiniert Bytes entstehen. Aber irgendwie sind die immer 0, deswegen klappts nicht.

    Edit: Nee, das ist es auch nicht. Er legt die Bytes einzeln auf den Stack. Ist mir gerade ein Rätsel warum das keine Probleme macht.



  • "integer promotions" klingelt da was?



  • Hmm nee, ist mir nicht klar.
    Er promotet die chars nicht zu ints bis sie in printf drin sind, und danach weiß er nicht mehr dass es chars sind. Ich werde mal noch etwas rumexperimentieren.

    Edit: irgendwie erwarte ich, dass printf("%d", a) identisch zu printf("%d", *(int *)&a) ist, aber das ist nicht der Fall. Woher weiß der in printf dass a ein char und kein int ist, obwohl er nur ein char auf den Stack legt? Zumindest bei printf("%d %d", (char)'a', (int)5); sollte er durcheinander kommen.
    Ich vermute fast der Compiler schummelt bei printf und übergibt Parameter bei printf anders als normal.



  • Du kennst doch bestimmt malloc.
    malloc gibt einen void * zurück.

    Also "malloc" sagt mir nichts. Habe erst vor kurzem mit C angefangen und bin deshalb nicht so weit.

    Mit welchem Compiler auf welchem System

    Ich verwende Bloodshed Dev-C++ und Windows.
    Bei mir laufen die Programme bzw. das Kompilieren problemlos, d.h. keine Fehlermeldungen.

    Ist mein Ansatz zum Verständnis der Typumwandlung in meinem vorherigen Post richtig?


Anmelden zum Antworten