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.
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 😉
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!"
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.
Ach um gleich zu checken ob der eingegebene Wert nicht den short überläuft?
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!"