操作符(Operator)也可以称作 运算符 ,操作符是用来操作数据的,(被操作符操作的数据称为操作数(Operand));
操作符的个数代表了一门编程语言最基本的运算能力,有了这些最基本的运算能力,就可以组合成我们想要的更复杂的逻辑,且操作符个数越多,组合时就越方便。
操作符是函数的 “简记法”;计算机操作符与数学运算符在本质上是相同的,最大的区别就是:计算机操作符不能脱离与它关联的数据类型。
//举例说明操作符不能脱离与它关联的数据类型
int a = 5;
int b = 4;
int c = a / b;//显然 c 值为1
double d = 5.0;
double e = 4.0;
double f = d / e;//显然 f 值为1.25
(1)除了带有赋值功能的操作符,同优先级操作符都是从左向右进行运算。
int x;
x = 3 + 4 + 5;
//两个加号"+"是同优先级,运算时从左往右:3+4=7——>7+5=12
(2)带有赋值功能的操作符的运算顺序是从右到左。
int x = 100;
int y = 200;
int z = 300;
x += y += z;
//从右往左运行:z = 300——>y=200+300=500——>x=100+500=600
基本表达式:可以理解为表达一定运算意图的式子,是最简单的,不能再被拆分的表达式。
基本运算符用以构成基本表达式。
(1)成员访问操作符 " . "
功能:
访问外层名称空间的子集名称空间;
访问名称空间中的类型;
访问类型中的静态成员;
访问对象的成员;
(2)方法调用操作符 " f(x) "
(3)元素访问操作符 " a[x] "
x代表索引,索引不一定都是整数
举例:
//创建实例后不需在后面加 "()"调用构造器
int [] MyIntArray = new int [10];
//"10"代表创建一个长度为10的整形数组(有10个元素),并且在创建时把这10个元素初始化成int类型的默认值(为0)
int [] MyIntArray2 = new int[]{
1,2,3,4,5};
//"{}"是初始化器,表示告诉编译器,在这个数组中,有5个元素,值分别为1,2,3,4,5
int [] MyIntArray3 = new int[6]{
1,2,3,4,5,6};
//可同时使用" [] " 与" {} ",但要注意相互对应
访问数组元素:在 [ ] 中输入数组元素的下标,也就是偏移量,第一个元素的下标为0.
如果懒得计算到底有多少个元素,同时又想访问数组中的最后一个元素,可以这样写:
MyIntArray[MyIntArray.Length - 1];
(4)后置的自增 " ++ " ,与自减 " – " (注意这是两个减号 -)
先传值,后自增
int x = 100;
int y = x++;//y = 100;x = 101
(5)typeof
typeof:帮助查看一个类型的内部结构。(内部结构包含着数据类型的基本信息,例如:是什么数据类型?属于哪个名称空间?有多少个方法?等)
(6)default
default:帮助获取一个数据类型的默认值
引用类型:默认值为空值null
结构体类型:默认值为0
枚举类型:
声明枚举类型的语法:
enum <enum_name>
{
enumeration list
}
//enum_name:枚举类型的名称
//enumeration list:是一个用逗号分隔的标识符列表
枚举类型属于值类型,一个枚举的关联值隐式地或显式的被赋值;如果不为其显式赋值,那么编译器会自动为其中的每一个元素按从头至尾的顺序分别与0——N(整数;依次加一)匹配起来;如果显式赋值时没有为任何元素赋值0,就会出现逻辑上的错误;
new操作符的主要功能
a.帮助我们在内存中创建一个类型的实例,并立刻调用该实例的实例构造器(instance constructor)。
b.如果在new的左侧有赋值符号,那么还能得到该实例的地址,并通过赋值符号交给负责访问实例的变量,构成变量与实例之间的引用关系。
new操作符的附加功能
调用实例的初始化器,从而初始化实例的多个属性
var关键字
显式类型变量:在声明这个变量时,明显告诉编译器该变量的数据类型。
var关键字的功能:帮助声明隐式类型的变量,编译器会根据变量被赋予的值自动判断变量的数据类型。
语法糖衣:只要想在内存中创建实例,就要调用new操作符吗?
不是,比如说:
//声明一个string类型的变量
string Name = "Tim";
//声明一个整形数组
int [] MyIntArray = {
1,2,3,4,5};
上述代码称作C#的语法糖衣:由于 String 和 int [ ] 都是非常基本的类型,就如同 int 这个基本类型一样,所以微软在创建C#时,为了统一基本类型的使用体验,将一些本来需要被调用的new隐藏了,以此达到简化代码的目的。
new操作符的危险性
一旦在一个类型中调用了new操作符(new操作符用以创建某个类型的实例),那么这个正在编写的类型就与这个创建实例的类型构成了非常紧密的耦合。
所以,new虽然很强大,但不能滥用;在大项目中,有一项名为 依赖注入 的设计模式,可帮助我们把紧耦合变成相对松的耦合。
new关键字的多用途
a.new作为操作符
b.new作为修饰符(子类隐藏父类)
(8)checked与unchecked
功能:用来检查一个值在内存中是否有溢出
值溢出:一个值在内存中所占的空间大小决定了这个值能够表达的范围,一旦超出了这个范围,那么这个值就会产生溢出。
checked:需要检查是否出现值溢出,一旦溢出,报错
unchecked:不需要检查
作为关键字的其他用法:上下文用法(checked语句块:在这个语句块的上下文范围之内,所有值溢出都会被检测到)
(9)delegate
delegate这个关键字最广泛的用途不是作为操作符,而是用来声明”委托”这个数据类型。
把delegate当做操作符来声明匿名方法已经是一个过时的技术了,被lambda表达式所取代了。
(10)sizeof:帮助获取一个对象在内存中所占的字节数
注意:
(11)->:通过指针处理结构体中的数据(获取或赋值),直接操作内存(不常用)
需要明确的是:C#中是有真正的指针的,但为了类型安全,默认并不支持指针,所以需要开启不安全代码(unsafe code)开发模式编写指针操作。
C#中规定:指针操作:取地址,用指针访问成员等,只能用于结构体类型,不能用于引用类型。
//定义指针
int* p1,p2;//p1,p2都是int*指针
int *p1,*p2;//c++中定义两个int*z指针
int *p1,p2;//C++中,p2只是一个普通的int