C#支持我们在孩提时代就学过的常规算术操作符:加号(+)用于加法,减号(-)用于减法,星号(*)用于乘法,正斜杠(/)则用于除法。这些符号(+,–,*和/)称为操作符(operator),因为它们用于对值进行“操作”以生成新值。在下例中,变量moneyPaidToConsultant最终容纳的是值750(每天的费用)和值20(天数)的乘积,结果就是要支付给专家的钱。
long moneyPaidToConsultant;
moneyPaidToConsultant = 750 * 20;
注意:操作符操作的值称为操作数(operand)。在表达式750 * 20中,*是操作符,750和20都是操作数。
2.5.1 操作符和数据类型并不是所有操作符都适用于所有数据类型。能不能对一个值应用一个操作符,要取决于该值的类型。例如,可以对char,int,long,float,double或者decimal类型的值使用任何算术操作符。但是,除了加法操作符(+)之外,不能对string或者bool类型的值使用其他任何算术操作符。所以,以下语句是不允许的,因为string类型不支持减法操作符(从一个字符串中减去另一个字符串是无意义的):
// 编译时错误
Console.WriteLine("Gillingham" -"Forest Green Rovers");
+操作符可用于连接字符串值。使用时要小心,因为可能造成出乎意料的结果。例如,以下语句会在控制台中写入"431"(而不是"44"):
Console.WriteLine("43" + "1");
提示 .NET Framework提供了一个名为Int32.Parse的方法,在需要对作为字符串存储的值执行算术运算时,可以先用Int32.Parse方法将字符串值转换成整数值。
还应注意到,一次算术运算的结果的类型要取决于操作数的类型。例如,表达式5.0/2.0的值是2.5;两个操作数的类型均为double。在C#中,带小数点的文字常量数字6肯定是double值,而不是float值,目的是保留尽可能高的精度。所以,结果的类型也是double。然而,表达式5 / 2的结果值是2。在这种情况下,两个操作数的类型均为int,所以结果类型也为int。C#在这种情况下总是对值进行向下取整。另外,假如混用不同的操作数类型,那么情况会变得更加复杂。例如,表达式5/ 2.0中包含一个int值和一个double值。C#编译器将检测到这种不一致的情况,并自动生成代码将int转换成double,然后才执行计算。所以,以上表达式的结果是一个double值(2.5)。然而,虽然这是一种有效的写法,但通常不建议像这样混用数据类型。
数值类型和无穷大C#语言中的数字,还有另外两个特性是我们必须了解的。例如,任何数除以0所得的结果是无穷大,不在int,long和decimal类型的范围内。所以,计算5 / 0之类的表达式会出错。但是,double和float类型实际上有一个可以表示无穷大的特殊值,因此表达式5.0 / 0.0的值是Infinity(无穷大)。这个规则的唯一例外是表达式0.0 / 0.0的值。通常,如果0除以任何数,结果都为0,但如果用任何数除以0,结果就为无穷大。表达式0.0 / 0.0会陷入一种自相矛盾的境地:值既为0,又无穷大。针对这种情况,C#语言提供了另一个值NaN,即“not a number”。所以,如果计算表达式0.0 / 0.0,则结果为NaN。NaN和Infinity可以在表达式中使用。如果计算10 + NaN,结果将为NaN。如果计算10 + Infinity,结果将为Infinity。这个规则的唯一例外是表达式Infinity * 0,其结果为0,而表达式NaN * 0的结果为NaN。
C#还支持大家或许不太熟悉的一个算术操作符,即取模(余数)操作符。它用百分号(%)来表示。x % y的结果就是用x除以y所得的余数。例如,9%2的结果是1,因为9除以2,结果是4余1。
注意:如果熟悉C和C++,肯定知道不能在这两种语言中对float和double类型的值使用取模操作符。但在C#中是允许这样做的。取模操作符适用于所有数值类型,而且结果不一定为整数。例如,表达式7.0 % 2.4的结果是2.2。
2.5.2 深入了解算术操作符以下练习演示了如何使用已经写好的一个名为MathsOperators的C#程序,对int类型的值使用算术操作符。
使用算术操作符1.打开MathsOperators项目。该项目位于“文档”文件夹下的\Microsoft Press\Visual CSharp Step by Step\Chapter 2\MathsOperators子文件夹中。
2.在“调试”菜单中选择“开始执行(不调试)”命令。 随后,屏幕上会显示一个WPF窗体。
3.在left operand(左操作数)文本框中输入54。
4.在right operand(右操作数)文本框中输入13。 随后,可以向两个文本框中的值应用任意操作符。
5.单击–Subtraction(减),再单击Calculate(计算)按钮。 Expression(表达式)框中的文本将变成54-13,Result(结果)框则会显示41。如下图所示。
6.单击/ Division(除),再单击Calculate(计算)按钮。 Expression文本框中的文本将变成54 / 13,Result文本框则会显示4。在现实生活中,54 / 13的结果应该是4.153846?(如此重复)。但这不是现实生活;这是C# !正如前面解释的那样,在C#中,一个整数除以另一个整数,结果也是一个整数。
7.单击% Remainder(取模)按钮,再单击Calculate(计算)按钮。Expression文本框中的文本将变成54 % 13,Result框则会显示2。这是因为54除以13,余数是2,即54–((54/13) * 13) = 2——在每一步,都注意是向下取整的。如果我告诉我的数学老师,说(54 / 13) * 13不等于54,他肯定会提起菜刀来追杀我!
8.试验其他数字和操作符组合。完成后,单击Quit按钮返回Visual Studio 2010编程环境。
现在来研究一下MathsOperators程序的代码。
研究MathsOperators程序代码1. 在设计视图窗口中显示MainWindow.xaml窗体(如有必要,请在解决方案资源管理器中双击“MainWindow.xaml”)。
2. 选择“视图”|“其他窗口”|“文档大纲”。 随后会打开“文档大纲”窗口,其中列出了窗体上的各个控件的名称和类型。“文档大纲”窗口提供了一个简单的方式在一个复杂的WPF窗体上定位并选择控件。控件以一个层次结构的形式排列,从构成WPF窗体的Windows开始。如上一章所述,WPF窗体实际包含一个Grid控件,其他控件都是放在这个Grid中的。在“文档大纲”窗口中展开Grid节点,其他控件就会出现。单击窗体上的每一个控件,控件名都会在“文档大纲”窗口中突出显示。类似地,在“文档大纲”窗口中选择一个控件,对应的控件也会在设计视图中被选中。将鼠标对准“文档大纲”窗口中的一个控件,会显示控件(及其包含的任何子控件)的一幅图像。
3. 在窗体上,单击供用户输入数字的两个TextBox控件。在“文档大纲”窗口中,确认它们分别被命名为lhsOperand和rhsOperand(控件右侧的圆括号中显示的就是控件的名称)。 在窗体运行时,每个控件的Text属性都容纳了用户输入的数值。
4. 在窗体底部,确认用于显示表达式的那个TextBox控件被命名为expression,用于显示计算结果的TextBox控件命名为result。
5. 关闭“文档大纲”窗口。
6. 在“代码和文本编辑器”窗口中显示MainWindow.xaml.cs文件的代码。
7. 在“代码和文本编辑器”窗口中找到subtractValues方法,如下所示:
private void subtractValues()
{
int lhs = int.Parse(lhsOperand.Text);
int rhs = int.Parse(rhsOperand.Text);
int outcome;
outcome = lhs -rhs;
expression.Text = lhsOperand.Text + " –" + rhsOperand.Text;
result.Text = outcome.ToString();
}
第一个语句声明了一个名为lhs的int变量,并将其初始化为一个整数,该整数对应于用户在lhsOperand文本框中输入的值。记住,文本框控件的Text属性包含的是字符串,所以必须将字符串转换为整数,之后才能将其赋值给一个int变量。int数据类型提供了int.Parse方法来执行这个转换。
第二个语句声明了一个名为rhs的int变量。rhsOperand文本框中的值转换为int之后,会赋给这个变量。
第三个语句声明了一个名为outcome的int变量。
第四个语句从lhs变量的值中减去rhs变量的值,并将结果赋给outcome。
第五个语句使用+操作符,将构成表达式的3个字符串连接起来,并将结果赋给expression.Text属性。这将导致连接好的字符串出现在窗体的expression文本框中。
第六个语句将计算结果赋给result文本框的Text属性,从而在这个文本框中显示结果。记住,Text属性是一个字符串,而计算结果是一个int,所以在将其赋给Text属性之前,必须先将int转换为字符串。这正是int类型的ToString方法的用处。
ToString方法.NET Framework中的每个类都有一个ToString方法。ToString方法的用途是将一个对象转换为相应的字符串形式。在前一个例子中,我们使用int对象outcome的ToString方法将outcome的整数值转换成对应的字符串值。这个转换是必要的,因为需要在result文本框的Text属性中显示该值,而Text属性只能包含字符串。创建自己的类时,还可以自己实现ToString方法,指定类应该如何表示成一个字符串。要想进一步了解如何创建自己的类,请参见第7章。