表达式
1.表达式的定义
通用定义:一种专门用来求值的语法实体
C#中定义:由一个或多个操作数,零个或多个操作符,功能是求值,求值的结果可能是四类
Single value、object、method、namespace
(说明至少要有一个操作数,但不一定要有操作符)
C#中表达式值的类型:
(1)单值 Single value
赋值表达式得到的值类型是 单值single value
如赋值表达式,其值就等于赋给变量的值
图中表达式值为100
自增表达式x++、++x的值也是单值
(2)对象 object
new表达式得到的值类型是 对象object
此表达式值是一个实例对象
所以new表达式可以跟在赋值后面
(3)方法 method
用于数据类型【委托】Action,委托可以用于管理多个方法
起源可能是C、C++中的【函数指针】,java中没有委托语法
新建委托时,初始化器括号内里写需要交给这个委托的函数
括号内是一个表达式,操作符是“.”成员访问操作符,操作数是类型Console和成员WriteLine
这个表达式的结果(值)是一个方法
(4)命名空间 namespace
例如调用时写类的全名,蓝色部分是一个“命名空间访问表达式”,操作符是“.”
蓝色部分这个表达式的值类型是命名空间
表达式由操作数、操作符或simple name组成,simple name可能是一个变量名、类型名、
还可以由字面值、函数调用参与构成表达式
如typeof操作符,参与构成表达式的int64是一个类型
总结
(1)表达式是构成算法逻辑的最小单元,表达一定的算法意图
(2)因为操作符有优先级,所以其构成的表达式也有优先级
2.C#中表达式的分类
通常把表达式得到的值的类型称作表达式的类型
函数调用、数组元素访问表达式的类型,都由对应的函数返回值、数组元素类型决定
checked表达式的类型和被操作数一致
NULL值合并操作符??的表达式的类型由左边的操作数的类型参数决定
例如操作一个可空整型,表达式的值类型就是整型
调用void函数的表达式的值类型为“nothing”,不属于任何类型
3.复合表达式
复合表达式根据操作符优先级判断优先级、运算方向
赋值操作符运算顺序为从右到左,其他操作符从左到右
语句
通用广义定义:
是命令式编程语言(高级语言)的最小可编译独立元素,用来表达一些动作
高级语言的程序就是由语句所构成的
编程就是使用语句编写程序
语句由表达式组成,每一个表达式表达语句的一个动作
低级语言(如汇编语言)中没有语句,只有指令(CPU可以直接执行的动作)
编译就是把高级语言中的语句,翻译成机器语言的指令
编译后的汇编语言展示,看看图一乐就好
C#狭义定义:
语句的功能:陈述算法思想,控制逻辑走向,完成有意义的动作
C#中的语句像C、C++一样是以分号结尾(但并非所有分号结尾都是语句)
C#中所有语句一定都出现在方法体中
语句分类
C#中语句大类型分为标签语句、声明语句、嵌入式语句
语句详解
嵌入式语句:
蓝色标出的是嵌套在if语句中的嵌入式语句
可作为嵌入式语句的语句类型:
1.声明语句
局部变量声明(在方法体外的声明不能算语句)
官方手册:
类型可以有type和var(待定类型,第一次赋值时确定,之后不可改变)
声明可以后接变量的初始化器:
注:初始化器不叫赋值,应与赋值区分
初始化器可以是一个值,也可以是一个表达式
编程规范:为提高程序可读性,一般不采用以下写法
C#数组初始化器:
常量:声明后无法再改变的变量,需要声明是在类型前面加关键字const
常量的声明必须带初始化器!
2.表达式语句
(1)调用表达式
(2)对象创建表达式
(3)赋值表达式
(4)自增表达式++、--
(5)await表达式(待续)
当以表达式作为语句时,表达式自己得到的值会被丢弃,只执行动作
返回值不为void的函数调用表达式作为语句使用时,值也会被丢弃
编程规范:平时尽量避免以非void方法作为语句,遵守单一职责功能
这样的无意义语句在C语言中能通过编译,但在C#中不行
3.块语句{ }(block)
用于把一堆语句组合放在语法上只能放一个语句的地方(大括号),是一个语句的容器
不是所有大括号都是块语句,以上这些分别是命名空间体、类体、方法体
出现在方法体中的大括号就是块语句,编译器会将块语句当作一条语句来看待
块语句是完整语句,大括号后不用写分号
块语句中可以塞入所有类型的语句,包括标签语句、声明语句、嵌入式语句
ex:标签语句(待续)
goto:跳转到一个标签位置
快捷键:光标放在一个快捷键上时,按下ctrl+右大括号键,光标会从一对大括号中的一个跳转到另一个
ex:变量的作用域
在一个块语句中,可以看到在块之外声明的变量、本块中声明的变量
但在一个块语句外,无法看到在块之内声明的变量
一个局部变量的作用域:所在的块语句(之内),变量声明语句之后
4.选择(分支)语句if、switch
(1)if语句
分为带else的和不带else的,if后括号内写bool类型的表达式
括号之后是一个嵌入式语句,只有嵌入式语句可以放在if后,标签语句和声明语句不可以
编程规范:即便if后只接一条语句,为可读性、扩展性考虑,也应将其写在大括号中
代码提示快捷键:写下if过后按两下tab键,就会打出整个大括号
多分支else if语句:
逻辑关系为逐级筛选
(2)switch语句
switch可以判断的表达式类型:
注:switch的括号里不能填float、double等浮点型类型的表达式!
Switch section
是switch的每一个分支,从标签开头,由break;结束
标签是每个switch section的开头,分为两种,case标签和default标签
case:switch的指定选项,后接括号,括号内写一个常量表达式
该常量表达式的值类型必须与switch()中写的表达式类型一致
当switch()中表达式值与case后常量表达式值一致时,执行该case section分支
语言发展历史:
在C、C++中,如果一个section结尾不加break,会继续执行紧跟着的下一个section的内容,这样的逻辑违反人类常识,所以在C#中取消了这样的功能
C#中每个section分支结束必须写break!
多个case标签可使用同一个section
Default:switch的默认选项
类似if的else,在所有case分支条件都不满足的时候执行default分支
快捷键:Ctrl + L 剪切一整行
Goto语句在switch中
switch中的case、default都是标签语句
标签语句可以使用goto传送
VS中switch的提示
1、声明一个枚举类型
2、声明一个该枚举类型的变量,以此变量写switch语句
一按回车,VS就会自动打印出所有枚举项的对应分支+一个default分支
编程规范:写switch时无论写什么功能,都加上一个default分支,以避免一些意想不到的逻辑
5.try语句
尝试执行一个语句块,并捕捉到出现的异常
可以带有一个catch子语句,能够在运行时捕捉异常
可以带有一个finally子语句,无论执行try时是否发生异常,finally语句块都会继续执行
1.不带catch子句,只带finally的情况
没有catch语句时,try出现异常不会被捕捉到,但也不会导致程序的崩溃
2.带上catch子语句
能够捕捉到出现的异常
3.catch语句分类
有通用catch语句,能捕捉到所有类型的异常
也可以通过在catch后写上(异常类型)来捕捉特定类型的异常
在C#手册中,每个方法的详解都会写出该方法可能会出现的异常类型
4.try语句意义
try、catch、finally语句可以让程序能够捕捉和应对异常,使程序有一定的容错性
编程规范:在写程序时,要极力避免程序的崩溃,所以必须使用try语句来捕捉和应对异常,向用户显示比较友好的信息
5.粗略处理异常:
当发现一个语句可能出现异常时,可以将其装进try-catch语句
catch中输出异常提示
但由于try-catch语句使用了大括号语句块,会影响变量的作用域
要注意变量的声明是否因为被装在try语句中导致外面用不了该变量
将变量声明提到大括号外
6.精确处理异常:
按上文中提到的手册中查阅到的异常类型
使用多个catch,括号内写上异常类型,来精确地区分抓到的异常,将出现的异常类型反馈给用户
7.访问异常实例
catch语句后除了可写异常类型外,还可以多写一个异常的标识符
就是一个异常的实例变量,能够访问这个实例,将具体的异常内容打印出来
例如:“输入的字符串格式不正确”
8.finally语句用法
写在catch语句后,无论try语句块是否发生异常,finally中的程序都会被执行
一般用来写:
1.示范一些系统资源,如关闭数据库的连接(类似写C时关闭文件)
2.在finally子句中写程序的执行记录(log)
3.一些计算的保底默认值
7.through关键字
不处理异常,将异常丢出去,丢给调用该段异常程序的函数
将异常交由调用者来处理
初学者一般用不到through,看看图一乐就好
through语法比较灵活,省略异常实例的标识符也能运行
作为开发岗,出现异常你不去抓,QA测试这个程序的时候就会抓到一个最严重的“程序崩溃”bug,反馈给管理系统,数据库里就会有一个崩溃级bug记到你头上(QAQ