本文节选自《LPC语言基础教程:从零学习游戏开发》,版权归@mudren,欢迎转载,但必须注明来源(mud.ren)。
第二节 LPC语言的循环结构
循环结构在C语言中有 while、do..while、for 和 if..goto 四种,在LPC语言中没有 goto 关键字,所以基本循环只有三种,而且使用方法和C语言完全一样。
while 语句
while语句用于循环结构,满足条件时,不断执行循环体。
while (expression)
statement
上面代码中,如果表达式expression为非零值(表示真),就会执行statement语句,然后再次判断expression是否为零;如果expression为零(表示伪)就跳出循环,不再执行循环体。
while (i < n)
i = i + 2;
上面示例中,只要i小于n,i就会不断增加2。
如果循环体有多个语句,就需要使用大括号将这些语句组合在一起。
while (expression) {
statement;
statement;
}
下面是一个例子。
i = 0;
while (i < 10) {
printf("i is now %d!\n", i);
i++;
}
printf("All done!\n");
上面代码中,循环体会执行10次,每次将i增加1,直到等于10才退出循环。
只要条件为真,while会产生无限循环。下面是一种常见的无限循环的写法。
while (1) {
// ...
}
上面的示例虽然是无限循环,但是循环体内部可以用break语句跳出循环。
do...while 结构
do...while结构是while的变体,它会先执行一次循环体,然后再判断是否满足条件。如果满足的话,就继续执行循环体,否则跳出循环。
do statement
while (expression);
上面代码中,不管条件expression是否成立,循环体statement至少会执行一次。每次statement执行完毕,就会判断一次expression,决定是否结束循环。
i = 10;
do --i;
while (i > 0);
上面示例中,变量i先减去1,再判断是否大于0。如果大于0,就继续减去1,直到i等于0为止。
如果循环部分有多条语句,就需要放在大括号里面。
i = 10;
do {
printf("i is %d\n", i);
i++;
} while (i < 10);
printf("All done!\n");
上面例子中,变量i并不满足小于10的条件,但是循环体还是会执行一次。
for 语句
for语句是最常用的循环结构,通常用于精确控制循环次数。
for (initialization; continuation; action)
statement;
上面代码中,for语句的条件部分(即圆括号里面的部分)有三个表达式。
initialization:初始化表达式,用于初始化循环变量,只执行一次。continuation:判断表达式,只要为true,就会不断执行循环体。action:循环变量处理表达式,每轮循环结束后执行,使得循环变量发生变化。
循环体部分的statement可以是一条语句,也可以是放在大括号里面的复合语句。下面是一个例子。
for (int i = 10; i > 0; i--)
printf("i is %d\n", i);
上面示例中,循环变量i在for的第一个表达式里面声明,该变量只用于本次循环。离开循环体之后,就会失效。
条件部分的三个表达式,每一个都可以有多个语句,语句与语句之间使用逗号分隔。
int i, j;
for (i = 0, j = 999; i < 10; i++, j--) {
printf("%d, %d\n", i, j);
}
上面示例中,初始化部分有两个语句,分别对变量i和j进行赋值。
for的三个表达式都不是必需的,甚至可以全部省略,这会形成无限循环。
for (;;) {
printf("本行会无限循环地打印。\n" );
}
上面示例由于没有判断条件,就会形成无限循环。
break 语句
break语句有两种用法。一种是与switch语句配套使用,用来中断某个分支的执行,这种用法前面已经介绍过了。另一种用法是在循环体内部跳出循环,不再进行后面的循环了。
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
printf("%d, %d\n", i, j);
break;
}
}
上面示例中,break语句使得循环跳到下一个i。
while ((ch = getchar()) != EOF) {
if (ch == '\n') break;
putchar(ch);
}
上面示例中,一旦读到换行符(\n),break命令就跳出整个while循环,不再继续读取了。
注意,break命令只能跳出循环体和switch结构,不能跳出if结构。
if (n > 1) {
if (n > 2) break; // 无效
printf("hello\n");
}
上面示例中,break语句是无效的,因为它不能跳出外层的if结构。
continue 语句
continue语句用于在循环体内部终止本轮循环,进入下一轮循环。只要遇到continue语句,循环体内部后面的语句就不执行了,回到循环体的头部,开始执行下一轮循环。
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
printf("%d, %d\n", i, j);
continue;
}
}
上面示例中,有没有continue语句,效果一样,都表示跳到下一个j。
while ((ch = getchar()) != '\n') {
if (ch == '\t') continue;
putchar(ch);
}
上面示例中,只要读到的字符是制表符(\t),就用continue语句跳过该字符,读取下一个字符。
foreach 语句
和C语言不同的是,在LPC语言中增加了 foreach 循环语句用来处理数组和映射,语法如下:
foreach (<var> [, <var>] in <expr) <statement or block>
如:
foreach(item in array){}
foreach(key, value in mapping){}
给一个简单的示例:
// 示例:4.2.1
int main(object me, string arg)
{
int *array = ({1, 2, 3, 4, 5, 6, 7});
foreach(int i in array)
{
printf("%d\n", i);
}
return 1;
}
运行后输出结果如下:
1
2
3
4
5
6
7
如果需要循环处理数组和映射,在LPC中推荐使用 foreach,简单方便。
另外,foreach还支持传引用ref,具体语法如下:
foreach (ref x in array)
foreach (x, ref y in mapping)
如下示例:
int main(object me, string arg)
{
mixed *arr = ({1,2,3,4,5});
foreach(int ref x in arr)
x *= 3;
// print_r为自己写的sefun,格式化打印数组的值方式调试用
print_r(arr);
return 1;
}
输出结果为:
({
0 => 3
1 => 6
2 => 9
3 => 12
4 => 15
})
在foreach中改变值直接改变了原始数组的值,在映射中使用类似,也可以直接传引用并修改值,这里不再演示。