Laden...

Operator checked / checked Anweisungsblock

Erstellt von RafaelVogt vor 4 Jahren Letzter Beitrag vor 4 Jahren 1.115 Views
R
RafaelVogt Themenstarter:in
27 Beiträge seit 2019
vor 4 Jahren
Operator checked / checked Anweisungsblock

Hallo zusammen, dies ist die 2te Frage im Zusammenhang mit meinem Wunsch C# von grundauf zu lernen. Mittlerweile bin ich am Ende des Kapitels "Variablen und Datentypen" angekommen. Hier geht es um den Operator >>checked<<. Ich weiß, das er einen Laufzeitabbruch verursacht und vor einem "Überlauf" schützt. Hier mein bisheriges Wissen:


namespace _04_elementare_Datentypen
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Die Operatoren >>checked<< und >>unchecked<<:");
            
            Console.WriteLine("Geben Sie eine Zahl im Bereich von ");
            Console.WriteLine($"0...{Int16.MaxValue} ein:");
            
            short value20 = Convert.ToInt16(Console.ReadLine());
            
            byte value21 = checked((byte)value20);
           
            Console.WriteLine(value21);

            Console.ReadKey();
        }
    }
}

Bis hier her komme ich mit. Gibt man z.B. einn Wert 256 ein, würde das zu einem Überlauf führen und der >>checked<< Operator bricht die Laufzeit ab. Nun steht in dem Buch einfach folgender Satz.

"Falls nich nur ein einzelner Ausdruck, sondern mehrere Ausdrücke innerhalb eines Anweisungsblocks auf einen möglichen Überlauf hin kontrolliert werden, können sie hinter >>checked<< einen Anweisungsblock angeben. Folgendes Beispiel dazu wird dann im Buch geliefert.


namespace _04_elementare_Datentypen_8
{
    class Program
    {
        static void Main(string[] args)
        {
            checked
            {
                short shortValue = 436;
                int integerValue = 1236555;
                byte byteValue = (byte)shtVar;
                shortValue = (short)integerValue;
                Console.WriteLine(byteValue);
                Console.ReadLine();
            }
        }
    }
}

Erstens verstehe ich nicht wie ich diesen Anweisungsblock in zum Beispiel den obigen Code einfügen soll, und zweitens ist die Variable


shtVar

gar nicht definiert. Was also versucht man mir hier zu sagen?

Vielen Dank im Voraus.

O
79 Beiträge seit 2011
vor 4 Jahren

Das ist doch total simpel 😁

Dein Code müsste, würde er den checked-operator konsequent nutzen, so aussehen:


short value20 = checked(Convert.ToInt16(Console.ReadLine()));
byte value21 = checked((byte)value20);

Wenn das jetzt nicht nur 2 Zeilen sind, sondern 132 Zeilen mit solchem Code, wird es echt mühsam, immer wieder checked() einzutippen. Also machen wir n Block draus:


checked
{
     short value20 = Convert.ToInt16(Console.ReadLine());
     byte value21 = (byte)value20;
}

Alle checked-operatoren sind nun weg, nur der eine um den Block herum ist noch da. Aber der umfasst eben ALLE Zeilen im Block. That simple 😁

Die fehlende Variable im Buch ist ein Fehler des Lektorats. Lektoren können toll Rechtschreibung und Grammatik, aber nicht programmieren. Die wissen nicht, das shtVar auch mit shortValue ersetzt werden muss, wie es der Autor vorher getan hat 😉

6.911 Beiträge seit 2009
vor 4 Jahren

Hallo RafaelVogt,

anstatt der checked Blöcke kann das auch "global" eingestellt werden.
Projekteigenschaften -> Build -> Advanced -> Checkbox "Check for arithmetic overflow/underflow"
Wobei ich jedoch die expliziten checked Blöcke und Anweisungen bevorzugen, da es eben sofort ersichtlich ist worum es geht.

Siehe zum Thema auch CA2233: Operations should not overflow

Da du gerade beim Lernen bist, noch ein Hinweis:

  
short value20 = Convert.ToInt16(Console.ReadLine());  
  

erzeugt einen Laufzeitfehler, falls Console.ReadLine keine Zahl (in Text-Form) liefert. Wenn du z.B. "abc" eingegeben hast anstatt einer erwarteten Zahl, so stürzt das Programm ab.
Abhilfe schafft entweder den Fehler mittels try catch zu fangen und behandeln od. noch besser


if (short.TryParse(Console.ReadLine(), out short value20))
{
    // Zahl konnte erfolgreich geparst werden
}
else
{
    // Zahl konnte nicht geparst werden
}

zu verwenden. Ob und wie auf das "nicht parsen" reagiert wird, hängt von der Anwendung ab.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

R
RafaelVogt Themenstarter:in
27 Beiträge seit 2019
vor 4 Jahren

Dein Code müsste, würde er den checked-operator konsequent nutzen, so aussehen:

  
short value20 = checked(Convert.ToInt16(Console.ReadLine()));  
byte value21 = checked((byte)value20);  
  

Mit ...


short value20 = checked(Convert.ToInt16(Console.ReadLine()));

... machst du genau was?

Sorry... es ist echt verwirrend.

R
RafaelVogt Themenstarter:in
27 Beiträge seit 2019
vor 4 Jahren

Ach um gleich zu checken ob der eingegebene Wert nicht den short überläuft?

6.911 Beiträge seit 2009
vor 4 Jahren

Hallo RafaelVogt,

Das ist doch total simpel 😄
Mit ...

  
short value20 = checked(Convert.ToInt16(Console.ReadLine()));  
  

... machst du genau was?

Sorry... es ist echt verwirrend.

Hier macht das checked nicht viel Sinn, da Int16 der Typ des Schlüsselworts short ist. Da kannst du es weglassen.

Anders wäre es z.B. bei


short s0 = checked(Convert.ToUInt16(Console.ReadLine()));

da bei der Konvertierung* ein ushort zurückgegeben wird, das könnte bei der Zuweisung zu short überlaufen.
Od. beim Beispiel von oben mit der Zuweisung zu byte.

Generell ist auf (arithmetischem) Über-/Unterlauf zu achten, wenn verschiedene Wertebereiche im Spiel sind. Entweder wird explizit im Code geprüft ob es passt (z.B. per if) od. mit checked od. gar nicht, falls Überlauf akzeptabel ist.

* bitte unbedingt meinen obigen Hinweis zu den TryParse-Methoden beachten.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

R
RafaelVogt Themenstarter:in
27 Beiträge seit 2019
vor 4 Jahren

Vielen, vielen Dank.