Skip to content

for循环

有时候我们想要明确地重复某件事很多次,或者批量处理一堆东西,此时for循环就派上用场了

语法

for i in end

gdscript
for 迭代变量 in 循环次数:
    循环体

如果循环次数是浮点数,则会向上取整:

  • for i in 10.0等同于for i in 10

  • for i in 10.1等同于for i in 11

如果循环次数是浮点数,迭代变量也会是一个浮点数

迭代变量是自动声明的,因此不能和作用域内其他已声明的变量重名

迭代变量可以在循环体内直接使用,作用域仅限于循环体

迭代变量会在每一次循环结束时增加1

迭代变量从0开始,到循环次数 - 1结束

gdscript
for i in 10:
    print(i)

上面的代码将输出0到10之间的每一个整数,但不包含10,总共10个数

for i in range(end)

gdscript
for 迭代变量 in range(循环次数):
    循环体

规则同for i in end

  • 会进行指定次数次循环,

  • 迭代变量从0开始,到循环次数 - 1结束

  • 迭代变量会在每一次循环结束时增加1

但当range()的参数为一个浮点数时,会向下取整,因为range的所有参数要求是一个整数,而迭代变量仍然会是一个整数,该项规则也适用于后面的其他使用range的语法:

  • for i in range(10.0)等同于for i in range(10)/for i in 10

  • for i in range(10.9)等同于for i in range(10)/for i in 10

for i in range(start, end)

gdscript
for 迭代变量 in range(迭代变量起始值, 迭代变量结束值):
    循环体

这种语法能够精准地控制迭代变量起始值和结束值,迭代变量每次循环结束都会加1

循环会在迭代变量下一次迭代将达到指定的结束值时停止

也就是说在这个语法中,迭代变量在循环中的值为:起始值 ~ 结束值 - 1

gdscript
for i in range(2, 5):
    print(i)

在上面的例子中,迭代变量i从起始值2开始,每次循环加1,到结束值5之前停止,最终值为4,总共进行3次循环

将会输出以下内容:

gdscript
2
3
4

如果起始值大于等于结束值那循环就不会开始

在下面的代码中,什么也不会输出

gdscript
for i in range(5, 2):
    print(i)
    
for i in range(5, 5):
    print(i)

for i in range(start, end, step)

gdscript
for 迭代变量 in range(迭代变量起始值, 迭代变量结束值, 迭代步长):
    循环体

当你不仅想控制 从哪里开始到哪里结束,还想决定 每次加(或减)多少,就可以使用这种三参数形式

规则与for i in range(start, end)相似,具体如下:

  • 迭代变量从start开始,每次循环结束,迭代变量都会加上迭代步长step,在下一次将到达end时结束

  • step可以是负数,但是不能为0,否则循环不会开始,如果是单独调用range则会报错

    Error calling GDScript utility function "range()": Step argument is zero!

  • start小于end时(正向循环),step不能是负数,否则循环不会开始

    • for i in range(0, 10, -1)
  • end小于start时(逆向循环),step不能是正数,否则循环不会开始

    • for i in range(10, 0, 1)
  • startend不能相等,否则循环不会开始

  • 当正向循环时,step如果大于等于end,则只会进行一次循环

  • 当逆向循环时,step的绝对值如果大于等于start,则只会进行一次循环

gdscript
for i in range(0, 10, 2):
    print(i) # 输出0, 2, 4, 6, 8

for i in range(10, 0, -2):
    print(i) # 输出10, 8, 6, 4, 2

迭代浮点数

由于range的参数只能是整数,因此不能使步长为浮点数,如每次迭代增加或减少0.1

但可以通过手动转换,得到浮点数迭代变量

步长0.01:

gdscript
 for i in range(0, 100, 1):
     var float_i = i / 100.0
     print(float_i)

步长0.05:

gdscript
for i in range(0, 100, 5):
    var float_i = i / 100.0
    print(float_i)

for c in 字符串

gdscript
for 迭代变量 in 字符串:
    循环体

有时候我们想对字符串里的每个字符做点什么,就可以用这个写法

每一轮循环里,c 都会是字符串中的一个字符(类型也是字符串,只不过长度是 1)

循环会从头到尾正序遍历整个字符串

当最后一个字符处理完,循环就自动结束了

遍历是指根据顺序访问某个集合中的每一个元素

gdscript
for c in "Hello World!":
    print(c)

上面的代码将会依次输出字符串"Hello World!"中每一个字符

H
e
l
l
o
 
W
o
r
l
d
!

for和while

迭代变量

  • while 循环中,我们需要手动控制迭代变量(比如自己加一)

  • 而在 for 循环中,迭代变量是由循环自动管理的

gdscript
var i = 0
while i < 10:
    print(i)
    i += 1
gdscript
for i in 10:
    print(i)

我们可以看到,同样的逻辑,相同的循环次数,使用for语句会更加简洁

手动修改迭代变量的后果

while循环中,手动更改迭代变量后如果导致循环条件的结果为false会在本次循环结束后,结束整个循环。

下面这段 while 中我们手动把 i 改成 20,让循环条件立刻变成 false,所以这段代码只会进行一次循环

gdscript
var i = 0
while i < 10:
    print(i)
    i = 20
    print(i)
    i += 1

for循环中,手动更改迭代变量不会导致循环结束,且仅在当前迭代中有效,下一迭代时迭代变量会变回原本的值

下面的代码中即使我们中途把 i 改成了 20,也只是在当前这一轮生效。下一轮迭代时,for 会重新用自己的方式控制变量,继续正常循环。

gdscript
for i in 10:
    print(i)
    i = 20
    print(i)

for的迭代变量也可以是一个对象,for的迭代变量只属于该循环,为其赋值不会影响原本的值,我们修改的只是副本,但通过引用传递的对象除外(如节点,数组,字典)!

相互转换

whlie语句和for语句间也能够互相转换

gdscript
for i in range(10, 0, -2):
    print(i)
gdscript
var i = 10
while i > 0:
    print(i)
    i -= 2

虽然写法不一样,实际效果是一样的,只是 for 更方便、结构更明确,很适合用于“明确知道循环次数”的情况

循环嵌套

有时候我们需要在一个循环中,再进行另一轮循环,这就是 循环嵌套 。不论是 forforwhilewhile,还是 forwhile 互相嵌套,都是允许的。

嵌套时,内层循环可以访问外层的迭代变量这对于处理二维结构(比如行列、坐标点等)非常有用

不过要注意的是: 太深的嵌套会让代码难以阅读,最好不要超过三层

下面的代码演示了如何用嵌套循环在控制台打印出一个 5×5 的小方块和一个高为5的直角三角形和等腰三角形

外层循环代表行,内层循环代表列

gdscript
# 定义宽度
var w = 5
# 定义高度
var h = 5
# 矩形
var box : String
for i in h:
    for j in w:
        # 每一行的每一列填充一个星号
        box +=  "*"
     # 每一行结束后换行
    box += "\n"
print(box)

# 直角三角形
var right_triangle : String 
# 行数从1开始,到 h 结束
for i in range(1, h + 1):   
    # 列数从1开始,到 i 结束
    for j in range(1, i + 1):
        # 每一行填充i个星号
        right_triangle += "*"
    # 每一行结束后换行
    right_triangle += "\n"
print(right_triangle)

# 等边三角形
var equicrural_triangle : String
# 行数,从1开始,到 h 结束
for i in range(1, h + 1):
    # 每一行前面填充 h - i 个空格
    for j in range(1, h - i + 1):
        equicrural_triangle += " "
    # 然后每一行再填充 2 * i - 1 个星号
    for j in range(1, 2 * i):
        equicrural_triangle += "*"
    # 每一行结束后换行
    equicrural_triangle += "\n"
print(equicrural_triangle)

练习

  1. 使用 for 循环,打印从 0 到 9 的每一个数字

  2. 使用 for 循环,打印 1 到 19 之间所有奇数

  3. 给定一个字符串 :"GDScript",使用 for 循环逐字输出每个字符

  4. 以下 while 循环打印从 0 到 4 的数字,把它改写成 for 版本

    gdscript
    var i = 0
    while i < 5:
        print(i)
        i += 1
  5. 以下 for 循环打印 10 到 1(倒序),把它改成 while

    gdscript
    for i in range(10, 0, -1):
        print(i)
  6. 给定字符串 "HeLLo WOrLd!",统计并打印其中大写字母的总数

    提示:String.to_upper()可以将字符串转换为大写,将转换后的结果进行某些操作或许……?

  7. 使用 for,找出 1~30 中所有能被 3 整除的数字,并打印出来

  8. 使用嵌套 for 循环打印 1 到 9 的乘法表(只输出格式:1 x 2 = 2 这种形式)

    提示:由于print会自动换行,可以在循环中拼接字符串,最后再打印出来