C# 程序中的可执行部分由各种表达式组成,因此也被称为表达式语言。表达式主要由变量、常量和运算符组成。C#中的表达式主要包括以下几种:
算术表达式:用算术运算符连接,结果是数值类型
关系表达式:用关系运算符连接,结果是布尔类型
逻辑表达式:用逻辑运算符连接,结果是布尔类型
赋值表达式:用赋值运算符连接,运算结果的类型取决于赋值运算符左侧的运算结果。
函数(方法)调用表达式:函数也称方法,是可以完成特定功能的程序单位,通过函数调用表达式可以执行函数的特定功能,运算的结果类型取决于函数的返回值类型。
算数表达式用于计算数值型数据的基本四则运算。C#中支持的算术运算符包括:+(加)、-(减)、(乘)、/(除)、% (取余数)。对于+和-运算符,还可以用于符号位,代表数值型常量或变量的正负号。
算术表达式示例:3+4*5 5*(6+7) +a*(-b)
C#按照四则运算的规则进行加减乘除,也支持用括号改变运算的优先级。不同类型的数据在进行算术时,按照以下数据类型转换的优先级进行转换(从左到右依次递增):Byte--short--int--long--float--double--decimal。
关系表达式用来进行数值或字符之间的比较运算,由相关数据和关系运算符组成,运算的结果为逻辑真值(true)或逻辑假值(false)。C#中的关系运算符包括:> < >= <= !==(等于) !=(不等于)。
关系表达式示例:a>b 5<8 7!=3 c==d ‘a’>’b’
逻辑表达式直接表示逻辑真或逻辑假值,这种表达式一般由多个关系表达式加上逻辑运算符构成,C#中主要的逻辑运算符包括:&&(逻辑与)、 ||(逻辑或)、 !(逻辑否)、 ?: 。
逻辑与和逻辑或主要用于连接多个关系表达式。例如:a>3&&a<5,表示3
逻辑否用于否定一个运算值为true的逻辑表达式。例如: 假设变量a值为true,则!a返回false。
?:运算符的使用格式为:表达式A?表达式B:表达式C。
该运算符计算表达式A的值,如果该值位逻辑真,则返回表达式B的值,如果为逻辑假,则返回表达式C的值。示例:a>b?"welcome”:”no thanks”
赋值表达式利用”=”对变量进行赋值,变量名要处于“=”左侧,称之为“左值”;而赋值的具体表达式要处于“=”的右侧,称之为“右值”。赋值过程中,左值的类型要和右值的类型项匹配,否则会执行类型转换。赋值中的类型转换可以隐式进行,也可以显式进行转换。
假设变量a为长整型数(long),对a赋值示例如下:
a=3L 正确赋值
a=3.2 非法赋值,因为3.2是双精型,赋给a会造成精度丢失
a=(long)3.2 正确赋值,会将3.2的整数部分赋给a
a=3 正确赋值,会将整型3隐式转换为长整型3L
从上面的表达式中,已经介绍了算术运算符、关系运算符、逻辑运算符和赋值运算符。除去这些运算符,C#还支持下列运算符:自增、自减运算符;复合赋值运算符;位运算符;类型转换及判定运算符。
C#支持数值型变量的自增和自减运算符(++和--),这种运算符放在变量的前面或后面,可以让变量的值加1或减1。示例:M++ ++n a-- --a 。
自增或自减运算符规则如下:
如果运算符位于变量之前,则执行变量自增或自减1,再执行其他运算。
如果运算符位于变量之后,则先行其他运算再执行自增或自减1运算。
示例:设m初始值为3,则表达式(m++)*3的值为9,运算之后m为4,而表达式(++m)*3的值为12,运算之后m我4。
示例:a+=3 等效于 a=a+3。
a+的意思就是本身的值加3再赋值给本身,简化了书写,提高了运行效率,减等/乘等/除等同理。从目前学习过的运算符当中,和赋值号构成的复合赋值运算符包括:-= += *= /= 。
位运算符主要用于对数据按照其二进制位进行运算。主要包括:>>右移:如果是有符号数,左侧空出位全用符号位填充;如果是无符号数,则左侧空出位用0填充;<< 左移:高位被挤掉。例如下图所示:
| 按位或:按照数的二进制表示形式,进行按位的逻辑或运算
& 按位与:按照数的二进制表示形式,进行按位的逻辑与运算
^按位异或:按照数的二进制表示形式,进行按位的XOR运算
~按位反:按照数的二进制表示形式,进行按位取反的工作
示例如下图所示:
如果把一个代码块记为checked,CLR就会执行溢出检查,如果发生溢出,就抛出异常。如果要禁止溢出检查,可以把代码标记为unchecked。unchecked是默认值。
//运行下面这段代码,就会抛出异常
byte b=255;
checked
{
b++;
}
Console.WriteLine(b.ToString());
//运行下面这段代码,则不会抛出异常
byte b=255;
unchecked
{
b++;
}
Console.WriteLine(b.ToString());
as运算符用于执行引用类型的显示类型转换,如果转换类型与指定的类型兼容,转换成功;反之,返回null。is运算符可以检查对象是否与特定的类型兼容。运算符type,返回一个表示特定类型的Type对象,例如:type of (string)返回表示System.String类型的Type对象。在使用反射动态查找对象信息时,这个运算符很有效。
object o1 = "some string";
object o2 = 5;
string s1 = o1 as string; //s1="some string"
string s2 = o2 as string; //s2=null
int i = 10;
if(i is object)
{
Console.WriteLine("i is an object");
}
数据类型转换分为隐式转换和显式转换两种。
只能从较小的整数类型隐式转换为较大的整数类型,不能从较大的整数类型隐式转换为较小地整数类型。无符号的变量可以转换为有符号的变量,只要无符号的变量值得大小在有符号的变量的范围之内即可。例如:
byte v1 = 10;
byte v2 = 23;
long total;
total = v1 + v2;//v1、v2均隐式转换为long类型
在不能隐式转换的时候,可以显式执行这些转换。格式如下:
long val = 3000000000;
int i = (int)val;//编译不会报错
在C#中,比较常见的类型转换多用于赋值运算符。在值类型变量的赋值运算中,比如整型/浮点型等变量的赋值中,如果复制运算符右侧的精度大于赋值号左侧的边来给你所属类型的精度,就需要进行显示的类型转换。
例如: int a = (int ) 5.0
运算符的优先级是指在表达式中,如果同时存在多个不同的运算符,哪一个运算符被优先执行运算。下表按优先级由高到低的次序列出了所有C#运算符:
程序员可以根据程序自身的需要重新定义运算符的运算特性,这种特性称之为运算符的重载。C#中不是所有的运算都支持重载,可重载的一元运算符有:+ - ! ~ ++ -- true false 。可重载的二元运算符有:+ - * / % & | ^ << >> == != > < >= <= 。