语句按类型分可为:

声明语句

嵌入语句(执行动作或管理控制流)

标签语句(跳转语句)

按复杂程度区分:

简单语句

​ 简单语句不需要大括号

块(一系列语句的组合,包含所有语句和嵌套块)

​ 被一组大括号包围

表达式语句

控制流语句

条件

if – 按条件执行;当条件满足时执行语句、块
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// x <= 10 -- Expr 的值必须为 bool
if (x <= 10)
z = x - 1; // 简单语句
if (x <= 10)
{ // 块
z = x - 1;
z = x - 2;
}

int x = 5;
if (x) // compiler error
{
z = x - 1;
z = x - 2;
}

if…else – 双路分支;
1
2
3
4
5
6
// 伪代码
if(TestExpr)
Statement1
else
Statement2
当TestExpr = True 时,执行 Statement1,否则执行 Statement2
switch – 多路分支

准确的说是switch case 语句。

多路分支:代表可以有很多路,远超2个。

每个分支可以包括一个或多个分支标签;

每个分支会以一个跳转语句结尾; 可以是break,也可以是 return 等其他;

满足分支条件后,可以执行分支的语句;

case 后面跟的通常是一个常量。TestExpr 与 case里的常量匹配,如果成功,执行当前语句;跳出switch。

image-20220813114114677

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 伪代码
switch(TestExpr)
{
case ConstExpr1:
Statement1;
break;
case ConstExpr2:
Statement2;
break;
case ConstExpr3:
Statement3;
break;
default:
Statement4;
break;
}

注意事项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// 不支持语法
...
switch(x)
{
case 1:
Console.WriteLine("case: {0}", 1); // Control cannot fall through from one case label `case 1:' to another
// -- 不能从 一个 case 到另一个case
case 2:
Console.WriteLine("case: {0}", 2);
break;
default:
Console.WriteLine("case: default");
break; // default 的 break 需要存在
}

// 可以这样
...
int x = 2;
switch(x)
{
case 1:
case 2:
Console.WriteLine("case: {0}", 1);
Console.WriteLine("case: {0}", 2);
break;
}
...

循环

while – 条件循环语句
1
2
3
4
5
6
while(expr)
{
Statement
}
// 当expr 表达式为True时,执行Statement;Statement语句执行完成之后,重新判断expr是否为True,如果为True循环执行;否则,当expr 为False时,停止执行。
// 一般会在在State语句的开始实现一个expr不满足的情况。防止死循环。

while循环语句流程图

do…while – 条件循环语句,和while 有所不同。
1
2
3
4
do
Statement
while(expr);
如表达式可以看出,dowhiie 是先执行一遍do语句,然后去判断while里的循环条件是否成立,如果为True那么继续执行语句,否则停止执行该循环语句。

do-while表达式

for – 条件循环语句;简单全面的语句
1
2
for( Initializer; TestExpr; IterationExpr )
Statement
  • Initializer 代表着初始化;通常在这里去声明条件变量的值,当当前循环只执行一次;可省略;
  • TestExpr 条件表达式 同上述 if 、while,只有当TestExpr为True时,才会执行语句;可省略,当省略时,代表TestExpr始终为True。
  • IterationExpr 迭代器表达式,新名词
  • Initializer、 TestExpr和 IterationExpr都是可选的;
  • 表达式是可选的,但分号是必须的。

​ 初始化语句 Initializer 只是执行一次,判断 TestExpr 条件如果成立,执行 Statement;Statement语句执行完成之后去执行 iterationExpr

image-20220813112252603

1
2
3
4
5
static void Main() 
{
for(int i = 0; i <10; i++) // 这里声明的 i 是一个局部变量
Statemenet
}
1
2
3
4
5
6
7
8
9
static void Main() 
{
const int MaxI = 5
for (int i = 0, j= 10;i < MaxI; i++, j += 10)
{
Console. Mriteline(" (o), {1}",i,j);
}
}

foreach

跳转

用于中断或者取消当前语句/分支/块/方法的执行。

break
  • ​ 可以用在 switch … case,
  • ​ 可以用在 for , foreach , while , do…while (循环语句)
  • ​ 多层循环嵌套只能跳出内层
continue
  • 跳出当前循环,
  • 通常放在循环语句前面
1
2
3
4
5
6
7
8
9
10
11
12
13
for(int x = 0;x < 10; x ++)
{
Console.Write("{0}, ", x);
}
// output 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,

for(int x = 0;x < 10; x ++)
{
if (x < 3) continue;
Console.Write("{0}, ", x);
}

// output 3, 4, 5, 6, 7, 8, 9,
return

结合方法使用

goto

很C语言, 高级语言见不到这样的语法。

  • 标签语句结合使用
  • 无条件转移控制到一个标签语句
1
2
3
4
5
6
7
8
for(int x = 0;x < 10; x ++)
{
if (x == 3) goto aaa;
Console.Write("{0}, ", x);
}
aaa: Console.WriteLine("tag aaa");

// output 0, 1, 2, tag aaa
throw

抛错

标签语句

标签语句由一个标识符后面跟着一个冒号再跟着一条语句组成。它有下面的形式。

Identifier: Statement

标签语句的执行完全如同标签不存在一样,并仅执行Statement部分。

  • 给语句增加一个标签允许控制从代码的其他部分转移到该语句。
  • 标签语句只允许用在块内部。

标签

​ 不能是关键字

​ 不能和另一个标签名称相同

标签语句作用域

external

using 语句

通常作为资源引入的 using 指令。

image-20220813132028847

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using System;
using System.IO;
class Program {
static void Main() {
Console.WriteLine("hello wrold");
using (TextWriter tw = File.CreateText("Lincoln.txt"))
{
tw.WriteLine(" Four score and seven years ago, ..."); // 调用IO 生成文件并写入一短话。
}
using (TextReader td = File.OpenText("Lincoln.txt"))
{
Console.WriteLine(td.ReadLine()); // Four score and seven years ago, ...
}
}
}
  • 分配资源;
  • 把Statement放进try块
  • 创建资源的Dispose方法的调用,并把它放进finally块。

资源使用率的问题,总结还是性能的问题。

通过using语句可以在 语句块执行完成之后,自动 dispose。

总的来说就是销毁