一、算术运算符
以下运算符对数值类型的操作数执行算术运算:
一元:++(增量)、--(减量)、+(加)和 -(减)运算符
二元:*(乘法)、/(除法)、%(余数)、+(加法)和 -(减法)运算符
所有整型和浮点数值类型都支持这些运算符。
增量运算符以两种形式进行支持:后缀增量运算符 x++ 和前缀增量运算符 ++x
减量运算符以两种形式进行支持:后缀减量运算符x-- 和前缀减量运算符 --x
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApp4
{
class Program
{
static void Main(string[] args)
{
int a = 10;
int b = a++ + ++a * 3 + --a + a++;
Console.WriteLine(b);
Console.ReadKey();
}
}
}
//输出结果为68
二、比较运算符
较运算符是在条件判断中经常使用的一类运算符,包括大于、小于、不等于、大于等于、小于等于等。
使用比较运算符运算得到的结果是布尔型的值,因此经常将使用比较运算符的表达式用到逻辑运算符的运算中。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApp4
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("88是否为偶数:" + (88 % 2 == 0));
Console.ReadKey();
}
}
}
//输出结果:88是否为偶数:True
三、逻辑运算符
逻辑运算符主要包括与、或、非等,它主要用于多个布尔型表达式之间的运算。
在使用逻辑运算符时需要注意逻辑运算符两边的表达式返回的结果都必须是布尔型的。
运算符 | 含义 | 说明 |
---|---|---|
&& | 逻辑与 | 如果运算符两边都为 True,则整个表达式为 True,否则为 False; 如果左边操作数为 False,则不对右边表达式进行计算,相当于“且”的含义 |
|| | 逻辑或 | 如果运算符两边有一个或两个为 True,整个表达式为 True,否则为 False; 如果左边为 True,则不对右边表达式进行计算,相当于“或”的含义 |
! | 逻辑非 | 表示和原来的逻辑相反的逻辑 |
四、赋值运算符
赋值运算符中最常见的是等号,除了等号以外还有很多赋值运算符,它们通常都是与其他运算符连用起到简化操作的作用。
运算符 | 说 明 |
---|---|
= | x=y,等号右边的值给等号左边的变量,即把变量 y 的值赋给变量 x |
+= | x+=y,等同于 x=x+y |
-= | x-=y,等同于 x=x-y |
*= | x*=y,等同于 x=x*y |
/= | x/=y,等同于 x=x/y |
%= | x%=y,等同于 x=x%y,表示求 x 除以 y 的余数 |
++ | x++ 或 ++x,等同于 x=x+1 |
-- | x-- 或 --x,等同于 x=x-1 |
需要注意的是,++ 和 -- 运算符放在操作数前和操作数后是有区别的,如果放在操作数前,需要先将操作数加 1 或减 1,然后再与其他操作数进行运算;如果放在操作数后,需要先与其他操作数进行运算,然后操作数自身再加 1。
五、位运算符
所谓的位运算,通常是指将数值型的值从十进制转换成二进制后的运算,由于是对二进制数进行运算,所以使用位运算符对操作数进行运算的速度稍快。
运算符 | 说 明 |
---|---|
& | 按位与。两个运算数都为 1,则整个表达式为 1,否则为 0;也可以对布尔型的值进行比较,相当于“与”运算,但不是短路运算 |
| | 按位或。两个运算数都为 0,则整个表达式为 0,否则为 1;也可以对布尔型的值进行比较,相当于“或”运算,但不是短路运算 |
~ | 按位非。当被运算的值为 1 时,运算结果为 0;当被运算的值为 0 时,运算结果为 1。该操作符不能用于布尔型。对正整数取反,则在原来的数上加 1,然后取负数;对负整数取反,则在原来的数上加 1,然后取绝对值 |
^ | 按位异或。只有运算的两位不同结果才为 1,否则为 0 |
<< | 左移。把运算符左边的操作数向左移动运算符右边指定的位数,右边因移动空出的部分 补 0 |
>> | 有符号右移。把运算符左边的操作数向右移动运算符右边指定的位数。如果是正值,左侧因移动空出的部分补 0;如果是负值,左侧因移动空出的部分补 1 |
>>> | 无符号右移。和 >> 的移动方式一样,只是不管正负,因移动空出的部分都补 0 |
在上面列出的运算符中比较常用的是左移运算符和右移运算符,左移 1 位相当于将操作数乘 2,右移 1 位相当于将操作数除 2。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApp4
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("2的立方为:" + (2 << 3));
Console.ReadKey();
}
}
}
//结果:
//2的4次方为:16
六、三元运算符
三元运算符也被称为条件运算符,与后面要学习的 if 条件语句非常类似。
在C#语言中三元运算符只有一个,具体的语法形式如下。
布尔表达式 ? 表达式 1: 表达式 2
其中:
- 布尔表达式:判断条件,它是一个结果为布尔型值的表达式。
- 表达式 1:如果布尔表达式的值为 True,该三元运算符得到的结果就是表达式 1 的运算结果。
- 表达式 2:如果布尔表达式的值为 False,该三元运算符得到的结果就是表达式 2 的运算结果。
需要注意的是,在三元运算符中表达式 1 和表达式 2 的结果的数据类型要兼容。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApp4
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("10为:" + (10 % 2 == 0 ? "偶数" : "奇数"));
Console.ReadKey();
}
}
}
//结果:
//10为偶数
七、运算符的优先级
前面介绍了 C# 中基本的运算符,在表达式中使用多个运算符进行计算时,运算符的运算有先后顺序。
如果想改变运算符的运算顺序必须依靠括号。运算符的优先级如下表所示,表中显示的内容是按优先级从高到低排序的。
运算符 | 结合性 |
---|---|
.(点)、()(小括号)、[](中括号) | 从左到右 |
+ (正)、-(负)、++ (自增)、--(自减)、~(按位非)、!(逻辑非) | 从右到左 |
* (乘)、/ (除)、% (取余) | 从左向右 |
+ (加)、-(减) | 从左向右 |
<<、>>、>>> | 从左向右 |
<、<=、>、>= | 从左向右 |
==、!= | 从左向右 |
& | 从左向右 |
| | 从左向右 |
^ | 从左向右 |
&& | 从左向右 |
|| | 从左向右 |
?: | 从右到左 |
=、+=、-=、*=、/=、%=、&=、|=、^=、~=、<<=、>>=、>>>= | 从右到左 |
尽管运算符本身已经有了优先级,但在实际应用中还是建议读者尽量在复杂的表达式中多用括号来控制优先级,以增强代码的可读性。
八、类型转换
由于 C# 是在编译时静态类型化的,因此变量在声明后就无法再次声明,或无法分配另一种类型的值,除非该类型可以隐式转换为变量的类型。 例如,string 无法隐式转换为 int。 因此,在将 i 声明为 int 后,无法将字符串“Hello”分配给它,如以下代码所示:
int i;
// error CS0029: Cannot implicitly convert type 'string' to 'int'
i = "Hello";
但有时可能需要将值复制到其他类型的变量或方法参数中。 例如,可能需要将一个整数变量传递给参数类型化为 double 的方法。 或者可能需要将类变量分配给接口类型的变量。 这些类型的操作称为类型转换。 在 C# 中,可以执行以下几种类型的转换:
隐式转换:由于这种转换始终会成功且不会导致数据丢失,因此无需使用任何特殊语法。 示例包括从较小整数类型到较大整数类型的转换以及从派生类到基类的转换。 |
显式转换(强制转换) :必须使用强制转换表达式,才能执行显式转换。 在转换中可能丢失信息时或在出于其他原因转换可能不成功时,必须进行强制转换。 典型的示例包括从数值到精度较低或范围较小的类型的转换和从基类实例到派生类的转换。 |
用户定义的转换:用户定义的转换是使用特殊方法执行,这些方法可定义为在没有基类和派生类关系的自定义类型之间启用显式转换和隐式转换。 有关详细信息,请参阅用户定义转换运算符。 |
使用帮助程序类进行转换:若要在非兼容类型(如整数和 System.DateTime 对象,或十六进制字符串和字节数组)之间转换,可使用 System.BitConverter 类、System.Convert 类和内置数值类型的 Parse 方法(如 Int32.Parse)。 有关详细信息,请参见如何将字节数组转换为 int、如何将字符串转换为数字和如何在十六进制字符串与数值类型之间转换。 |
//隐式转换
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApp4
{
class Program
{
static void Main(string[] args)
{
int a = 20;
int b = 6;
double x = a / b;
Console.WriteLine(x);
Console.WriteLine("{0:0.00}", x);
double y = a * 1.0 / b;
Console.WriteLine("{0:0.000}", y);
Console.ReadKey();
}
}
}
//输出结果为:
//3
//3.00
//3.333
//显式转换(强制转换)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApp4
{
class Program
{
static void Main(string[] args)
{
double a = 66.538;
int b = (int)a;
Console.WriteLine(b);
Console.ReadKey();
}
}
}
//输出结果为:66
Convert类型转换:将一个基本数据类型转换为另一个基本数据类型。
Convert 方法是数据类型转换中最灵活的方法,它能够将任意数据类型的值转换成任意数据类型,前提是不要超出指定数据类型的范围。
对于整型和浮点型的强制数据类型操作也可以使用 Convert 方法代替,但是依然会损失存储范围大的数据类型的精度。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApp4
{
class Program
{
static void Main(string[] args)
{
String sum1 = Console.ReadLine();
double sum2 = Convert.ToDouble(sum1);
Console.WriteLine(sum2);
Console.ReadKey();
}
}
}
//输入整数或者浮点数都能正常输出,但是输入字符就会bug。
注意:Console.ReadLine:从标准输入流读取下一行字符。此处是字符,必须用String接受。