DAS Buch/S.339

  • DAS Buch/S.339

    Hallo mal wieder,
    die Methode (IBAction)slide: ist vermurkst.

    Es steht dort :

    Quellcode

    1. - (IBAction)slide:(id)sender
    2. {
    3. float kurs, gkurs;
    4. kurs = [sender floatValue];
    5. [kTextField setIntValue:kurs];
    6. if (kurs == NORD && kurs < SUED) {
    7. gkurs = kurs + SUED;
    8. } else if (kurs == SUED && kurs <= NORD2) {
    9. gkurs = kurs - SUED;
    10. }
    11. [gkTextField setIntValue:gkurs];
    12. }
    Alles anzeigen

    Die if Schleife sollte lauten:

    Quellcode

    1. if (kurs == NORD || kurs < SUED) {
    2. gkurs = kurs + SUED;
    3. } else if (kurs == SUED || kurs <= NORD2) {
    4. gkurs = kurs - SUED;
    5. }


    Also Logisch oder, statt logisch und.

    Weiter oben im Code wird an den NSSlider(sender) eine floatValue-Botschaft gesendet.
    Das funktioniert genauso gut wie eine intValue-Botschaft.
    Wandelt (castet) der Compiler das von selbst?
    Offensichtlich ja. Sonst müsste da ja irgendein Käse rauskommen.
    Das heisst wir haben eine implizite Wandlung. Kann sowas auch schief gehen?
  • nein es wird kein typ umgewandelt
    der NSSlider versteht aber verschiedene Messages

    wie eben floatValue oder intValue und noch ein paar mehr
    schau einfach mal in die klassendoku und da vor allem auch in die der Klassen von denen abgeleitet wird NSControl zb etc pp

    btw: was zur hölle ist eine if schleife?!
    snafu
    :() { :|: &};:
    sometimes i dream in hex
    Obey gravity! Because its a law!
  • OK. Zwei Sachen habe ich verbumsfidelt.
    1) If-Schleife gibt es nicht. Das ist ein If-Block.
    2) Ich habe die Variablen als float deklariert. Im Original heisst es int.

    Das macht aber keinen Unterschied. Sobald ich den if-Block korrigiere und || statt && in den Original-Code einfüge, funktioniert es wie erwartet. Wenn ich in der letzten Zeile setFloatValue verwende, dann sieht das entsprechend unhübsch aus. An allen anderen Stellen scheint es aber egal zu sein, ob ich float oder int verwende.
    Also z.B.:

    Quellcode

    1. [kTextField setFloatValue:kurs];

    statt:

    Quellcode

    1. [kTextField setIntValue:kurs];

    Auch bei der deklaration

    Quellcode

    1. int kurs, gkurs;

    kann ich

    Quellcode

    1. float kurs, gkurs;

    verwenden.

    Das irritiert mich. Jetz probiere ich nochmal aus alles auf float zu setzen, bis auf den letzten Methoden-Aufruf....

    Aha! Jetzt wird auch (erstmals) im ersten NSTextfield (Kompasskurs) eine Zahl mit Nachkommastellen angezeigt. Im zweiten NSTextField (Gegenkurs) dagegen nicht. Dabei wird jetzt ein float (gKurs) an setIntValue übergeben.

    D.h. Wenn die Variablen als int deklariert sind, gibt es keine Nachkommastelle; ein setFloatValue erzeugt wohl ein float aus dem int und übergibt es an das NSTextfield, es sieht aber wie ein int aus, da das NSTextfield kein "Komma Null" anhängt.
    So passt es langsam. Dennoch muss seine implizite Konvertierung statt finden.
  • RE: DAS Buch/S.339

    Ich glaube nicht, dass der Code verwurschtelt ist. Er stammt zwar nicht von mir, sondern von Klaus. Damit stammt er allerdings aus der ersten Auflage, wurde also schon ein paar tausend Male getestet. Aber vllt maildet er sich ja, sonst schreibe ihm eine Mail.

    Du kannst ohne Not eine float übergeben, wo ein int gefordert wird. Ich neige dazu, dass zu explizieren, also ((int)floatVar) zu schreiben. In diesem Falle ist aber schon der Methodenname explizit.

    Es geht dannn in die Hose, wenn der Float einen Wert enthält, den man als Int nicht darstellen kann, gewiss also nicht in diesem Falle.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Die Mail an den Klaus ist raus.

    Du kannst ohne Not eine float übergeben, wo ein int gefordert wird. Ich neige dazu, dass zu explizieren, also ((int)floatVar) zu schreiben. In diesem Falle ist aber schon der Methodenname explizit.

    Bei den Methoden zaubert die ObjC-Runtime ja auch wieder.

    Aber in der Zeile

    Quellcode

    1. kurs = [sender floatValue];

    ist kurs ein int und "=" ist nunmal "=" und da kommt mir die ObjC-Runtime doch garnicht dazwischen?!
    Wenn hier per floatValue ein float geliefert und dieser fälschlicher Weise ( den Compiler stört es nicht) in ein int geschrieben wird, dann sind das erst mal nur 32 Bit (uninterpretiert). Wenn ich die aus der Verpackung mit der Aufschrift int wieder rausnehme und als float benutze, stimmt es immer noch; nur wenn ich diese 32 Bit an setIntValue übergebe, woher weiss dann die Methode, dass eine Typwandlung nötig ist?
    Deswegen meine ich müsste der Compiler ohne Warning und ohne explizites Casting [Du schreibst ((in)flaotVar)] eine implizite Typwandlung durchführen, und das wundert mich an dieser Stelle. Zumindest eine Warnung hätte ich erwartet.

    Noch ein Nachtrag: Im Original-Code Seite 339 steht für den If-Klausel
    "kurs =" statt "kurs ==" was bei einem #define von 0 für NORD immer unwahr und 180 für SUED immer wahr ist.

    Idiotischerweise liefert das NSTextField für den Gegekurs immer -179 für den Original Code, und das verstehe ich Typwandlung hin oder her garnicht mehr. Da müsste doch 0 (Null) bei rauskommen!?