C#高级编程三十八天----运算符

运算符


类别


运算符


算术运算符


+ - * /


逻辑运算符


& | ^ ~ && || ~


字符串连接运算符


+


增量和减量运算符


++ --


移位运算符


<< >>


比较运算符


== != < > <= >=


赋值运算符


= += -= *= /=  %=  &=  |= ^=  >>=  <<=


成员访问运算符运算符(用于对象和结构)


.


索引运算符(用于数组和所引起)


[]


类型转换运算符


()


条件运算符(三元运算符)


?:


委托连接和删除运算符


+ -


对象创建运算符


new


类型信息运算符


sizeof is typeof as


溢出异常控制运算符


checked unchecked


间接寻址运算符


[]


名称空间别名限定符


::


空额合并运算符


??

sizeof,*,->和&只能用于不安全的代码,注意sizeof运算符在早期版本中使用,自从.NET 2以来就不要了.

使用C#运算符 最大的一个缺点是与C风格的语言类似,对于赋值(=)和比较(==)运算符C#使用不同的运算符.例如:

x=3  //x等于3

如果要比较x与另一个值:

if(x==3)

{}

因为C#非常严格的类型安全则防止出现常见的C错误,比如在C中不出错的:

if(x=3)

{}

这在C#中是错误的.

在C#中使用加号(+)连接字符串,使用”&”发号表示连个不同整数值的按位AND运算,”|”符号表示两个整数值的按位OR运算.C#中海油取模运算符(%),7%5的结果为2.

C#很少使用指针和间接寻址运算符(->)

C#中的拥有简化赋值操作符:

例如:x++等价于x=x+1;x*=y等价于x=x*y

C#中的++x和x++的意思是不一样的,一个是前置,一个是后置 .案例:

int x=1;

if (++x==2)//因为这里是前置,所以先执行+1操作,x为2

{

Console.WriteLine("x=2");

}

if (x++==3)//因为这里是前置,所以先判断,然后再执行+1操作

{

Console.WriteLine("x=3");

}

Console.WriteLine(x);

Console.ReadKey();

下面介绍C#中频繁使用的基本运算符和类型强制转换运算符.

1条件运算符

条件运算符(?:)也成三元运算符:

condition ? true_value : false_valur

condition 为要判断的布尔表达式,true_value是condition为true时返回的值,false_value是condition为false时返回的值.

案例:

int x=1;

string s = x + " ";

s += (x == 1 ? "man" : "men");

Console.WriteLine(s);

2 .checked和unchecked

案例:

byte b = 255;

b++;

Console.WriteLine(b.ToString());

Console.ReadKey();

因为byte数据类型只能包含0~255的数,所以递增b的值会导致溢出.输出b的值为0.

如果把代码修改一下:

byte b = 255;

checked

{

b++;

}

Console.WriteLine(b.ToString());

Console.ReadKey();

CLR就是执行溢出检查,如果发生溢出,就会抛出异常.

执行代码会抛出异常.

如果要禁止异常检查,则可以把代码标记为unchecked

byte b = 255;

unchecked

{

b++;

}

Console.WriteLine(b.ToString());

Console.ReadKey();

本例中,不会抛出异常,但会丢失数据,因为byte数据类型不能包含256,溢出的位会丢弃,所以b的值为0.

注意,unchecked是默认行为.只有在需要把几行未检查的代码放在一个显式的标记为checked的大代码块中,才需要显示的使用unchecked关键字.

3.is运算符

is运算符可以检查对象是否与特定的类型兼容.”兼容”表示对象或该类型,或者派生自该类型.例如,要检查变量是否与object类型兼容,可以使用下面的代码:

int i = 10;

if (i is object)

{

Console.WriteLine("i is object");

}

4.as运算符

5.as运算符用于执行引用类型的显示类型转换.如果要转换的类型于指定的类型兼容,转换就会成功进行:如果类型不兼容,as运算符就会返回null值.如下例,如果object引用实际上不引用string实例,把object引用转换为string就会返回null:

object o1 = "some string";

object o2 = 5;

string s1 = o1 as string;

string s2 = o2 as string;

as运算符允许在一部中进行安全的类型转换,不需要先使用is运算符测试类型,在执行转换

5.sizeof运算符

使用sizeof运算符可以确定栈中值类型需要的长度(单位是字节):

Console.WriteLine(sizeof(int));

结果显示4,因为int有四个字节.

如果对于复杂类型(和非基元类型)使用sizeof运算符,就需要把代码放在unsafe块中,如下:

unsafe

{

Console.WriteLine(sizeof(Person));

}

6.typeof运算符

typeof运算符返回一个表示特定类型的System.Type对象.例如,typeof(string)返回表示System.String类型的Type对象.在使用反射技术动态的查找对象的相关信息时,这个运算符很有用.

7.可空类型和运算符

对于布尔类型,可以给他指定true或false值.但是,要把该类型的值定义为undefined,该怎么办>此时使用可空类型可以给应用程序提供一个独特的值.如果在程序中使用可空类型,就必须考虑null值在与各种运算符一起使用时的影响.通常可空类型与一元或二元运算符一起使用时,如果其中一个操作数或两个操作数都输null,其结果就是null.例如:

int? a = null;

int? b = a + 4;//b=null

int? c = a * b;//c=null

但是在比较可空类型时,只要有一个操作数是null,比较结果就是false.既不能因为一个条件是false,就认为该条件的对立面是true,这在使用非可空类型的程序中很常见.例如:

int? a = null;

int? b = -5;

if (a>=b)

{

Console.WriteLine("a>=b");

}

else

{

Console.WriteLine("a<b");

}

8.空合并运算符

空合并运算符(??)提供了一种快捷方式,可以在处理可空类型和引用类型时表示null可能的值.这个运算符放在两个操作数之间,第一个操作数必须是一个可空类型或引用类型;第二个操作数必须与第一个操作数的类型相同,或者可以隐含的转换为第一个操作数的类型.空合并运算符的计算如下:

如果第一个操作数不是null,整个表达式就等于第一个操作数的值.

如果第一个操作数是null,整个表达式就等于第二个操作数的值.

案例:

int? a = null;

int b;

b = a ?? 10;

Console.WriteLine(b);

a = 3;

b = a ?? 10;

Console.WriteLine(b);

运算符的优先级(从高到低的顺序)



运算符


初级运算符


() . [] x++ x-- new typeof sizeof checked uncheched


一元运算符


+ - ! ~ ++x --x和数据类型强制转换


乘除运算符


* / %


加减运算符


+ -


移位运算符


<< >>


关系运算符


< > <= >= is as


比较运算符


== !=


按位AND运算符


&


按位XOR运算符


^


按位OR运算符


|


布尔AND运算符


&&


布尔OR运算符


||


条件运算符


?:


赋值运算符


= += -= *= /= %= &= |= ^= <<= >>= >>>=

注意:在复杂的表达式中,应避免利用运算符又声称正确的结果,使用圆括号指定运算符的执行顺序,可以使代码更整洁,避免出现潜在的冲突.

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-11 21:31:26

C#高级编程三十八天----运算符的相关文章

C++面向对象高级编程(三)

版权声明:本文为博主原创文章,未经博主允许不得转载. 接下来的几篇文章,我将回忆一下C++的基础. C++的由两部分组成 1.C++语言 2.C++标准库 本篇文章主要分享我学习C++语言的笔记. 本节主要介绍 Big Three 即析构函数,拷贝构造函数,赋值拷贝函数,前面主要围绕不带指针的class complex本节中主要围绕带指针的String类 前面我说过如果你创建的类不带有指针,那么多半你可以不用写析构函数,但是如果你创建了一个带指针的类,那么你必须重写Big Three 创建一个类

C#高级编程三十七天----结构比较

结构比较 数组和元组都实现接口IStructuralEquatable和IStructuralComparable.这两个接口不仅可以比较引用,还可以比较内容.这些接口都是显示实现的,所以在使用时需要把数组和元组强制转换为这个接口.IStructuralEquatable接口用于比较两个元组或数组是否有相同的内容,IStructuralComparable接口用于给元组或数组排序. using System; using System.Collections.Generic; using Sys

C#高级编程五十八天----并行集合

并行集合 对于并行任务,与其相关紧密的就是对一些共享资源,数据结构的并行訪问.常常要做的就是对一些队列进行加锁-解锁,然后运行类似插入,删除等等相互排斥操作. .NET4提供了一些封装好的支持并行操作数据容器,能够降低并行编程的复杂程度. 并行集合的命名空间:System.Collections.Concurrent 并行容器: ConcurrentQueue ConcurrentStack ConcurrentBag: 一个无序的数据结构集,当不考虑顺序时很实用. BlockingCollec

C#高级编程六十八天---LINQ小结

LINQ小结 一.LINQ是什么 LINQ也就是Language Interrated Query的缩写,怎么一个缩写法我也不明白,即语言集成查询,是微软在.NET3.5中提出的一项新技术,LINQ主要包含四个组件,下面看一下LINQ的一个架构图: 简单的介绍一些四个组件: 1.Linq to SQL 组件----可以查询基于关于数据的数据(微软本身只是实现了对SQL Server的查询,可以对数据库中的数据进行查询,修改,插入删除,排序等操作) 2.LINQ to Dataset组件----可

C#高级编程四十八天----列表

C#中的List C#中deList怎么样?List<T>类是ArrayList类的泛型等效类,该类使用大小可按需动态增长的数组实现List<T>泛型接口. 泛型的好处:它为使用C#语言编写面向对象程序增加了极大的效力和灵活性,不会强行对值类型进行装箱和拆箱,或对引用类型进行向下强制类型转化,所以性能得到提高. 性能注意事项:再决定使用List<T>还是使用ArrayList类(两者具有类似的功能)时,记住IList<T>类在大多数情况下执行得更好并且是类型

C#高级编程三十天----泛型结构,泛型方法,泛型委托

泛型结构 泛型结构和泛型类几乎是一直的,只是泛型结构没有继承的特性..NET平台提供的一个泛型结构是(可空类型)Nullablle<T>.可空类型的引入,主要是为了解决数据库语言中的数字与编程语言中的数字的区别(数据库中数字可以为空,编程语言中数字不可为空).因为Nullable<T>使用过于的繁琐,于是就引入了一种特殊的语法,使用个"?"运算符.例: int? x1; Nullable<int> x2; x1和x2这两种方式定义是等价的. 非空类型

Unix环境高级编程(三)标准I/O库

标准I/O库是ISO C的标准,在很多操作系统上面都实现.Unix文件I/O函数都是针对文件描述符的,当打开一个文件的时候,返回该文件描述符用于后续的I/O操作.而对于标准I/O库,操作则是围绕流进行,当用标准I/O库打开或者创建一个文件时,使得一个流与文件相关联.标准I/O库使用了缓冲技术,使用缓冲的目的是尽可能减少使用read和write调用次数,但是效率不高.每次进行读写时候需要复制两次数据.第一次是在内核和标准I/O缓冲之间(调用read和write),第二次是在标准I/O缓冲区和用户程

C#高级编程三十五天----foreach和yield

枚举 在foreach语句中使用枚举,可以迭代集合中的元素,且无需知道集合中的元素个数. 数组或集合实现带GetEumerator()方法的IEumerable接口.GetEumerator()方法返回一个实现IEunmerable接口的枚举. GetEnumerator()方法用IEnumerable接口定义.foreach语句并不真的需要在集合类中实现这个借口.有一个名为GetEnumerator()的方法,他返回实现了IEnumerator接口的对象就足够了. IEnumerator接口

effective OC2.0 52阅读笔记(六 大中枢派发)+ Objective-C高级编程 (三Grand Central Dispatch)

41 多用派发队列,少用同步锁 总结:当多个线程执行同一份代码时,可能会出现问题,这时有@synchronized(self){}内置同步块.或NSLock对象.然而这只是某种程度上的线程安全,使用串行同步队列(serial sychronization queue).更有效率的方法是使用串行队列同步取方法,异步设置方法.执行异步派发时需要拷贝块.再优化就是改用并发队列,同步取方法,使用栅栏块(只是对并发队列有意义)异步设置方法(读取操作可以并行,但是写入操作必须单独执行)dispatch_ba