1. 表达式
运算符是一个符号,它表示返回单个结果的操作。操作数 operand 是指为运算符输入的数据元素。
– 将操作数作为输入,执行某个操作, 基于该操作返回一个值。
表达式时运算符和操作数的字符串。可做为操作数的结构有:字面量,常量,变量,方法调用,元素访问器,其它表达式。
表达式求值是将每个运算符应用到它的操作数的过程,以适当的顺序产生一个值。
2. 字面量
字面量 literal 是源码中键入是数字或字符串,表示一个指定类型的明确的,固定的值。
int x = 1024;
float f= 3.14;
bool flag= true;
double = 1.2345;
char c=‘x’;
string s= “test”;
对于引用类型变量,字面量null表示变量没有设置为内存中的数据。
整数字面量
最常用的字面量。没有小数点,带可选后缀,指明整数类型。
123,整型
123L,长整型
123U,无符号整型
123UL ,无符号长整型
整数类型字面可以写成十六进制形式。(0-9_A-F)
实数字面量
实数字面量的组成:十进制数字,一个可选小数点,一个可选的指数部分,一个可选的后缀。
123F, float类型
123.45,double类型
1.2345m, decimal类型
1.23e-3 ,指数形式
字符串字面量
字符字面量是由2个单引号内的字符组成。单个字符,一个简单转义序列,一个十六进制转义序列或一个Unicode转义序列。
类型是char
简单的转义序列是一个反斜杠后面跟单个字符
十六进制转义序列是一个反斜杠,后跟一个大写或小写的x,再跟4个十六进制数字
Unicode转义序列是一个反斜杠,后跟一个大写或小写的u,再跟4个十六进制数字
char c1=‘d’; 单个字符
char c2 =’\n’; 简单转义字符
char c3= ‘\x0061’; 十六进制转义序列
char c4 =’\u005a’; Unicode转义序列
字符串字面量
字符串字面量使用双引号标记,不同于字符字面量使用单引号。‘
string s1=“Hello world”;
string s2=“Val1\t5,\nVal2\t10”;
逐字符字面量使用@,严格按照原字符输出。
测试如下:
string s1 = “Hi Test”;
string v1 = @“Hi Test”;
Console.WriteLine(s1);
Console.WriteLine(v1);
输出:
Hi Test
Hi Test
string s2 = “It started,\“Four score and seven…\””;
string v2= @“It started,”“Four score and seven…”"";
Console.WriteLine(s2);
Console.WriteLine(v2);
输出:
_It started,“Four score and seven…”
_
It started,“Four score and seven…”
string s3 = “Value 1 \t 5,Val 2\t 10”;
string v3 = @“Value 1 \t 5,Val 2\t 10”;
Console.WriteLine(s3);
Console.WriteLine(v3);
输出:
_Value 1 5,Val 2 10
_
Value 1 \t 5,Val 2\t 10
string s4 = “C:\\Program Files\\Microsof\\”;
string v4= @“C:\Program Files\Microsof\”;
Console.WriteLine(s4);
Console.WriteLine(v4);
输出:
_C:\Program Files\Microsof\
_
C:\Program Files\Microsof\
string s5 = “Print \x000AMultiple \u000ALines”;
string v5 = @"Print
Multiple
Lines";
Console.WriteLine(s5);
Console.WriteLine(v5);
输出:
Multiple
Lines
Multiple
Lines
编译器让相同的字符串字面共享堆中同一内存位置以节约内存。
3. 求值顺序
表达式可由许多嵌套的子表达式构成,子表达式的求值顺序可使表达式的值最终发生差别。
优先级
C#中有45个基本运算符,14个优先级
结合性
当连续的运算符有相同的优先级,求值顺序由操作结合性决定。
左结合运算符:从左至右求值
右结合运算符:从右至左求值
除赋值运算符外,其它二元运算符都是左结合的;赋值运算符和条件运算符是右结合。
可以使用圆括号( )显示的设定子表达式的求值顺序。
4. 简单算法运算符
基本的四则运算,二元左结合运算符(加,减,乘, 除)
5. 求余运算符
求余运算符 %, 返会余数
测试代码如下:
Console.WriteLine($“0除以3余数是:{0%3}”);
Console.WriteLine($“1除以3余数是:{1 % 3}”);
Console.WriteLine($“2除以3余数是:{2 % 3}”);
Console.WriteLine($“3除以3余数是:{3 % 3}”);
Console.WriteLine($“4除以3余数是:{4 % 3}”);
输出:
0除以3余数是:0
1除以3余数是:1
2除以3余数是:2
3除以3余数是:0
4除以3余数是:1
求余还可以用实数
Console.WriteLine($“0.0f % 1.5f is:{0.0f%1.5f}”);
Console.WriteLine($“0.5f % 1.5f is:{0.5f % 1.5f}”);
Console.WriteLine($“1.0f % 1.5f is:{1.0f % 1.5f}”);
Console.WriteLine($“1.5f % 1.5f is:{1.5f % 1.5f}”);
Console.WriteLine($“2.0f % 1.5f is:{2.0f % 1.5f}”);
Console.WriteLine($“2.5f % 1.5f is:{2.5f % 1.5f}”);
输出:
0.0f % 1.5f is:0
0.5f % 1.5f is:0.5
1.0f % 1.5f is:1
1.5f % 1.5f is:0
2.0f % 1.5f is:0.5
2.5f % 1.5f is:1
6.关系比较运算符和相等比较运算符
返回 bool 类型值,关系运算符和相等比较运算符都是二元左结合运算符。
与C,C++不同,C#中数字不具备布尔意义。
比较 操作和相等操作
对大多数引用类型来说,比较它们的相等性,将只是比较它们的引用。
引用相等,即它们指向内存中相同的对象。这称浅比较。
引用变量指向相同的堆地址,则2个变量相等
创建一个demo类来测试:
class demo
{
public int Id { get; set; }
public demo(int id)
{
this.Id = id;
}
}
测试如下:
var a = new demo(1);
var b = new demo(1);
var c = a;
if(a == b)
Console.WriteLine(“Ture”);
else
Console.WriteLine(“False”);
if (a == c)
Console.WriteLine(“Ture”);
else
Console.WriteLine(“False”);
输出:
_False //a,b 指向不同的堆内存
_
Ture //a,c 指向相同的堆内存
string类型对象是引用类型,但它的比较方式不同!!比较字符串相等时,将比较它们的长度和内容。
如果2个字符串具有相同的长度和内容,那么相等性返回True,即使它们占用不同内存区域。即深比较
string s1 = “test”;
string s2 = “test”;
if(s1==s2)
Console.WriteLine(“True”);
else
Console.WriteLine(“False”);
输出:Ture
8. 递增运算符和递减运算符
堆操作数加1或减1.
自增,自减是一元的,有前置和后置形式
前置:++x, --x ; 先计算后使用,即先计算增1或减1,返回计算后的新值
后置:x++,x–; 先使用后计算,使用原值,再返回计算后的新值
int x = 10;
int y = 10;
Console.WriteLine($"{x}前置++:{++x}"); //11
Console.WriteLine($"{y}后置++:{y++}"); //10
int x = 10;
int y = 10;
Console.WriteLine($"{x}前置–:{–x}");
Console.WriteLine($"{y}后置–:{y–}");
输出:
_10前置–:9
_
10后置–:10