跳到主要内容

控制流

控制流语句用于控制程序的执行顺序。Sii 2 提供了条件语句、循环语句和跳转语句,让您能够根据不同的条件执行不同的代码,或者重复执行某些代码。

条件语句

if 语句

if 语句根据条件决定是否执行代码块:

if (condition) {
// 条件为 true 时执行的代码
}

示例:

let age: int = 18;

if (age >= 18) {
sii.io.print("已成年");
}

if-else 语句

if-else 语句提供两个分支,根据条件选择执行:

if (condition) {
// 条件为 true 时执行
} else {
// 条件为 false 时执行
}

示例:

let score: int = 85;

if (score >= 60) {
sii.io.print("及格");
} else {
sii.io.print("不及格");
}

嵌套 if 语句

可以在 ifelse 块中嵌套另一个 if 语句:

let score: int = 85;

if (score >= 60) {
if (score >= 90) {
sii.io.print("优秀");
} else {
sii.io.print("良好");
}
} else {
sii.io.print("不及格");
}

条件表达式

if 语句也可以作为表达式使用,返回一个值:

let score: int = 85;
let grade: string = if (score >= 90) { "A" } else { "B" };
sii.io.print(grade);

注意:条件表达式必须包含 else 分支,否则无法确定返回值。

循环语句

forloop 语句

forloop 语句用于重复执行代码块,语法类似 C 语言的 for 循环:

forloop (初始化; 条件; 更新) {
// 循环体
}

基本语法:

forloop (let i: int = 0; i < 10; i.getUp(1)) {
sii.io.print(i.toString());
}

各部分说明:

  • 初始化:循环开始前执行一次,通常用于声明和初始化循环变量
  • 条件:每次循环前检查,为 true 时继续执行
  • 更新:每次循环后执行,通常用于更新循环变量
  • 循环体:重复执行的代码块

示例:

// 打印 0 到 9(使用 getUp 方法自增)
forloop (let i: int = 0; i < 10; i.getUp(1)) {
sii.io.print(i.toString());
}

// 倒序打印(使用 getDn 方法自减,或使用赋值语句)
forloop (let i: int = 9; i >= 0; i.getDn(1)) {
sii.io.print(i.toString());
}

// 或使用赋值语句
forloop (let i: int = 9; i >= 0; i = i - 1) {
sii.io.print(i.toString());
}

// 使用赋值语句更新
forloop (let i: int = 0; i < 10; i = i + 1) {
sii.io.print(i.toString());
}

// 遍历数组
let numbers: arr<int> = [10, 20, 30, 40, 50];
forloop (let i: int = 0; i < numbers.length(); i.getUp(1)) {
sii.io.print(numbers[i].toString());
}

自增/自减方法:

Sii 2 提供了以下方法用于自增和自减:

  • getUp(step):先自增,然后返回新值(相当于 ++i),step 默认为 1
  • toUp(step):先返回原值,然后自增(相当于 i++),step 默认为 1
  • getDn(step):先自减,然后返回新值(相当于 --i),step 默认为 1
  • toDn(step):先返回原值,然后自减(相当于 i--),step 默认为 1
let i: int = 0;

// 使用 getUp(先自增后返回)
let a: int = i.getUp(1); // i = 1, a = 1

// 使用 toUp(先返回后自增)
let b: int = i.toUp(1); // i = 2, b = 1

// 在 forloop 中通常使用 getUp
forloop (let j: int = 0; j < 10; j.getUp(1)) {
// 循环体
}

可选的初始化、条件和更新:

forloop 的三个部分都是可选的:

// 只有条件
let i: int = 0;
forloop (; i < 10; ) {
sii.io.print(i.toString());
i.getUp(1); // 或 i = i + 1
}

// 无限循环
forloop (; ; ) {
sii.io.print("无限循环");
// 需要使用 break 跳出
}

while 语句

while 语句在条件为 true 时重复执行代码块:

while (condition) {
// 循环体
}

示例:

let count: int = 0;

while (count < 5) {
sii.io.print(count.toString());
count = count + 1;
}

while 与 forloop 的区别:

  • forloop:适合已知循环次数的场景
  • while:适合条件复杂或循环次数未知的场景

示例:读取用户输入直到满足条件

let input: string = "";
while (input != "quit") {
input = sii.io.readLine();
sii.io.print("您输入了: " + input);
}

跳转语句

break 语句

break 语句用于立即跳出循环:

forloop (let i: int = 0; i < 10; i.getUp(1)) {
if (i == 5) {
break; // 当 i 等于 5 时跳出循环
}
sii.io.print(i.toString());
}
// 输出:0, 1, 2, 3, 4

在嵌套循环中使用 break:

break 只跳出最内层的循环:

forloop (let i: int = 0; i < 3; i.getUp(1)) {
forloop (let j: int = 0; j < 3; j.getUp(1)) {
if (j == 1) {
break; // 只跳出内层循环
}
sii.io.print(i.toString() + ", " + j.toString());
}
}

continue 语句

continue 语句用于跳过当前循环的剩余代码,继续下一次循环:

forloop (let i: int = 0; i < 10; i.getUp(1)) {
if (i % 2 == 0) {
continue; // 跳过偶数,只处理奇数
}
sii.io.print(i.toString());
}
// 输出:1, 3, 5, 7, 9

示例:处理数组时跳过某些元素

let numbers: arr<int> = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

forloop (let i: int = 0; i < numbers.length(); i.getUp(1)) {
if (numbers[i] % 3 == 0) {
continue; // 跳过能被 3 整除的数
}
sii.io.print(numbers[i].toString());
}
// 输出:1, 2, 4, 5, 7, 8, 10

控制流最佳实践

1. 避免深层嵌套

深层嵌套的 if 语句会降低代码可读性:

// 不良的写法:深层嵌套
if (condition1) {
if (condition2) {
if (condition3) {
// 代码
}
}
}

// 良好的写法:使用早期返回或逻辑运算符
if (!condition1) {
back;
}
if (!condition2) {
back;
}
if (condition3) {
// 代码
}

2. 使用有意义的条件

条件表达式应该清晰表达意图:

// 良好的写法:条件清晰
if (age >= 18) {
sii.io.print("已成年");
}

// 不良的写法:条件不清晰
if (!(age < 18)) {
sii.io.print("已成年");
}

3. 避免无限循环

确保循环有明确的退出条件:

// 良好的写法:有明确的退出条件
let count: int = 0;
while (count < 10) {
sii.io.print(count.toString());
count = count + 1;
}

// 不良的写法:可能无限循环
let count: int = 0;
while (count < 10) {
sii.io.print(count.toString());
// 忘记更新 count,导致无限循环
}

4. 合理使用 break 和 continue

breakcontinue 应该用于简化逻辑,而不是增加复杂性:

// 良好的写法:使用 continue 简化逻辑
forloop (let i: int = 0; i < numbers.length(); i.getUp(1)) {
if (numbers[i] < 0) {
continue; // 跳过负数
}
// 处理正数
processNumber(numbers[i]);
}

// 不良的写法:过度使用 break
forloop (let i: int = 0; i < numbers.length(); i.getUp(1)) {
if (numbers[i] >= 0) {
processNumber(numbers[i]);
} else {
break; // 遇到负数就停止,可能不是预期行为
}
}

完整示例

示例 1:查找数组中的元素

func findIndex(numbers: arr<int>, target: int): int {
forloop (let i: int = 0; i < numbers.length(); i.getUp(1)) {
if (numbers[i] == target) {
back i; // 找到后立即返回
}
}
back -1; // 未找到返回 -1
}

示例 2:计算阶乘

func factorial(n: int): int {
if (n <= 1) {
back 1;
}

let result: int = 1;
forloop (let i: int = 2; i <= n; i.getUp(1)) {
result = result * i;
}
back result;
}

示例 3:验证用户输入

func validateInput(): string {
let input: string = "";

while (true) {
input = sii.io.readLine();

if (input.length() == 0) {
sii.io.print("输入不能为空,请重新输入:");
continue;
}

if (input.length() < 3) {
sii.io.print("输入长度至少为 3,请重新输入:");
continue;
}

break; // 输入有效,跳出循环
}

back input;
}

示例 4:处理数组并跳过无效值

func processNumbers(numbers: arr<int>): void {
forloop (let i: int = 0; i < numbers.length(); i.getUp(1)) {
let num: int = numbers[i];

// 跳过负数
if (num < 0) {
continue;
}

// 跳过大于 100 的数
if (num > 100) {
continue;
}

// 处理有效值
sii.io.print("处理数字: " + num.toString());
}
}

小结

本章介绍了 Sii 2 的控制流语句:

  • 条件语句ifif-else、嵌套条件、条件表达式
  • 循环语句forloopwhile
  • 跳转语句breakcontinue
  • 最佳实践:如何编写清晰、可维护的控制流代码

下一章我们将学习类和接口,了解面向对象编程的核心概念。