📄 chapter 7.mht
字号:
<P class=3DCprg>System.Console.WriteLine(k + " " + l + " " + =
m);<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCoutput><U>Compiler Error</U><o:p></o:p></P>
<P class=3DCoutput>a.cs(5,11): error CS0221: Constant value '256' cannot =
be=20
converted to a 'byte' (use 'unchecked' syntax to =
override)<o:p></o:p></P>
<P class=3DCoutput>a.cs(6,11): error CS0221: Constant value '257' cannot =
be=20
converted to a 'byte' (use 'unchecked' syntax to =
override)<o:p></o:p></P>
<P class=3DCoutput>a.cs(7,11): error CS0221: Constant value '514' cannot =
be=20
converted to a 'byte' (use 'unchecked' syntax to =
override)<o:p></o:p></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext">However, one way out =
is by using=20
a cast. A cast is some data type within () brackets. The object on the =
right=20
temporarily is converted to the data type within the cast. It is not =
like an=20
operation where you get a permanent scar. This conversion is forgotten =
when you=20
leave the statement. No permanent damage or change is carried out on the =
object.=20
<o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext">By casting, we are =
commanding the=20
compiler to break or overlook its own rules. C# realizes that 256 is =
larger than=20
255, so it will keep subtracting the number from 256. The resultant =
value is the=20
number assigned to the byte variables.<o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext">To place it more =
accurately, the=20
compiler divides the number by 256 and the remainder is the assigned =
value to=20
the variable. Pure mathematics in school revealed that when any number =
is=20
divided by another number lets say 100, the remainder is always less =
than 100=20
(the divisor). This remainder is now a byte that can be equated to the =
byte=20
variables on the left.<o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext">The error demands an =
unchecked=20
modifier while casting. <o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCprg><U>a.cs</U><o:p></o:p></P>
<P class=3DCprg>class zzz<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>public static void Main() <o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>byte k =3D unchecked((byte)256);<o:p></o:p></P>
<P class=3DCprg>byte l =3D unchecked((byte)257);<o:p></o:p></P>
<P class=3DCprg>byte m =3D unchecked((byte)514);<o:p></o:p></P>
<P class=3DCprg>System.Console.WriteLine(k + " " + l + " " + =
m);<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg><SPAN=20
style=3D"COLOR: blue"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCprg><U><SPAN style=3D"COLOR: =
black">Output</SPAN><o:p></o:p></U></P>
<P class=3DCprg>0 1 2<o:p></o:p></P>
<P class=3DCprg><U><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></U></P>
<P class=3DCprg><U>a.cs</U><o:p></o:p></P>
<P class=3DCprg>class zzz {<o:p></o:p></P>
<P class=3DCprg>int b =3D 1000000;<o:p></o:p></P>
<P class=3DCprg>int c =3D 1000000;<o:p></o:p></P>
<P class=3DCprg>public static void Main() <o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>int j;<o:p></o:p></P>
<P class=3DCprg>zzz a =3D new zzz();<o:p></o:p></P>
<P class=3DCprg>j =3D a.abc(a.b,a.c);<o:p></o:p></P>
<P class=3DCprg>System.Console.WriteLine(j);<o:p></o:p></P>
<P class=3DCprg>j =3D a.pqr(a.b,a.c);<o:p></o:p></P>
<P class=3DCprg>System.Console.WriteLine(j);<o:p></o:p></P>
<P class=3DCprg>a.xyz(a.b,a.c);<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>int abc( int x, int y)<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>return x*y;<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>int pqr( int x, int y)<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>return unchecked(x*y);<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>int xyz( int x, int y)<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>return checked(x*y);<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCoutput><U>Output</U><o:p></o:p></P>
<P class=3DCoutput>-727379968<o:p></o:p></P>
<P class=3DCoutput>-727379968<o:p></o:p></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCoutput>Exception occurred: System.OverflowException: An =
exception of=20
type System.OverflowException was thrown.<o:p></o:p></P>
<P class=3DCoutput><SPAN style=3D"mso-spacerun: yes"> =
</SPAN>at=20
zzz.Main()<o:p></o:p></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext">There are two =
operators in the C#=20
programming language called checked and unchecked. They deal with =
problems of=20
overflow or underflow in values. In the above examples, the compiler is =
aware of=20
the problem at compile time. A vast majority of us believe that =
computers are=20
highly intelligent. The same people also believe in the tooth fairy. =
What we=20
would like to say very emphatically is that the compilers do not go far =
enough=20
in understanding what our program is up to. They apply a simple set of =
rules and=20
if our program fails them, an error is flagged. <o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext">By default, C# writes =
the=20
operator unchecked before all our expressions. Thus the functions abc =
and pqr=20
behave in the same way. <o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext">The compiler adds a =
lot of its=20
code to the code we write as well as rewrites a major part of it too. In =
the=20
function abc or pqr, the compiler does not actually replace the =
variables with=20
their values while compiling. If it did so, it would come back and =
inform us=20
about an overflow. The unchecked operator behaves like our parents. They =
normally let us do what we want as they believe we are old enough to =
decide our=20
fate. In this case the compiler does assume you know what you are doing =
and=20
simply gives you the wrong answer of overflow results. =
<o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext">Remember the compiler =
does not=20
hand run your code. If we use the checked operator, the compiler will =
now behave=20
in a different way at run time but not at compile time. It will now =
generate an=20
exception if an overflow occurs. Thus, it keeps a watchful eye on your =
program=20
at runtime. It is advisable to use the checked operator, as we do not =
know what=20
values our variables may hold. Also, please catch the exception thrown =
to=20
prevent the error message box showing up as it will scare the shits of =
the=20
user.<o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCprg><U>a.cs</U><o:p></o:p></P>
<P class=3DCprg>class zzz<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>const int x =3D 1000000;<o:p></o:p></P>
<P class=3DCprg>const int y =3D 1000000;<o:p></o:p></P>
<P class=3DCprg>static int abc() {<o:p></o:p></P>
<P class=3DCprg>return checked(x * y);<SPAN=20
style=3D"mso-tab-count: =
2"> &nbs=
p; =20
</SPAN><o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>static int pqr() {<o:p></o:p></P>
<P class=3DCprg>return unchecked(x * y);<SPAN style=3D"mso-tab-count: =
1">=20
</SPAN><o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>static int xyz() {<o:p></o:p></P>
<P class=3DCprg>return x * y;<SPAN=20
style=3D"mso-tab-count: =
4"> &nbs=
p;  =
; =
=20
</SPAN><o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>int aaa() {<o:p></o:p></P>
<P class=3DCprg>return x * y;<SPAN=20
style=3D"mso-tab-count: =
4"> &nbs=
p;  =
; =
=20
</SPAN><o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>static void Main()<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCoutput><U>Compiler Error</U><o:p></o:p></P>
<P class=3DCoutput>a.cs(6,16): error CS0220: The operation overflows at =
compile=20
time in checked mode<o:p></o:p></P>
<P class=3DCoutput>a.cs(12,8): error CS0220: The operation overflows at =
compile=20
time in checked mode<o:p></o:p></P>
<P class=3DCoutput>a.cs(15,8): error CS0220: The operation overflows at =
compile=20
time in checked mode<o:p></o:p></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext">C# treats a const =
variable very=20
differently from a normal one. In the case of a const, the compiler is =
cent=20
percent sure that the value will never change. <o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext">Now C# hits the =
ceiling as in the=20
function abc, it detects an overflow. It gives an error about the =
impending=20
danger. In the case of function pqr, using unchecked, we have informed =
the=20
compiler not to bother us as we are old enough to understand what we are =
doing;=20
even though it is blatantly obvious that we are not in this case. C# =
bows to our=20
wishes and issues no error message.<o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext">Under normal =
circumstances, when=20
one of these operators is not specified for compile time checks, by=20
default,<SPAN style=3D"mso-spacerun: yes"> </SPAN>the reverse of =
it is=20
applicable for the run time checks. At compile time, the checked =
operator is on=20
for const variables by default, irrespective of the modifier static. =
This=20
explains the last two errors. Thus for compile time checks the default =
is=20
checked for const variables and the compiler will try as hard as =
possible to=20
check for overflows. However, it will never replace variables with=20
values.<o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCprg><U>a.cs</U><o:p></o:p></P>
<P class=3DCprg>class zzz<o:p></o:p></P>
<P class=3DCprg>{<o:p></o:p></P>
<P class=3DCprg>public const int i =3D =
checked((int)2147483648);<o:p></o:p></P>
<P class=3DCprg>public const int j =3D =
unchecked((int)2147483648);<o:p></o:p></P>
<P class=3DCprg>}<o:p></o:p></P>
<P class=3DCbase><SPAN style=3D"COLOR: windowtext"><![if =
!supportEmptyParas]><![endif]> <o:p></o:p></SPAN></P>
<P class=3DCoutput><U>Compiler Error</U><o:p></o:p></P>
<P class=3DCoutput>a.cs(3,31): error CS0221: Constant value '2147483648' =
cannot be=20
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -