几种主流语言的循环语法
C 语言的循环结构(while、for、do-while)是现代命令式编程语言的基石。以 C 语言为基准,可以清晰地看到其他语言在"语法糖"、"安全性"和"迭代器协议"上的演进。
以下是对各语言循环语法的系统总结,重点在于与 C 语言的异同点。
基准:C 语言
C语言的循环结构简洁、底层,直接映射到底层汇编的跳转指令。
while循环: 先判断,后执行。do...while循环: 先执行一次,后判断。for循环: 最经典的初始化; 条件; 增量结构。
核心特点:
-
基于索引/指针: C语言的循环通常依赖于整数索引或指针算术来遍历数组。
-
极度灵活:
for循环的三个部分都可以为空,甚至可以放入多行语句(用逗号连接)。 -
作用域: 在 C89 标准中,循环变量必须在循环外定义;C99 支持在
for( int i=0; ... )内定义,但作用域仅限于循环体。
1、C++ (向后兼容 + 现代 STL)
C++ 完全兼容 C 的三种循环,但在 C++11 及以后标准中引入了基于范围的 for 循环。
-
语法:
for (declaration : range) { ... } -
与 C 的异同:
-
相同点: 依然保留 C 风格的
for和while,用于需要索引或复杂控制的场景。 -
不同点:
-
遍历集合更安全: 不需要手动管理索引器,避免了“差一错误”。
-
支持引用:
for (auto& x : vec)可以直接修改容器元素,C语言则需要解引用指针(*p)。 -
底层原理: 它是基于迭代器的语法糖,编译器会展开为类似
begin()和end()的调用。
-
-
2、Java
Java 在语法上几乎克隆了 C,但增加了增强型 for 循环(也称 for-each)。
-
经典循环: 与 C 语言完全一致。
-
增强型 for 循环:
for (Type item : collection) { ... } -
与 C 的异同:
-
相同点:
while,do-while, 标准for逻辑与 C 一致。 -
不同点:
-
增强型循环: 类似于 C++,但只能用于数组或实现了
Iterable接口的对象。 -
作用域限制: 在
for(int i=0...)中定义的i,其作用域严格限制在循环内(C++也是如此,但老 C 代码常不注意)。 -
无指针算术: Java 没有 C 语言那样的指针算术,所以
for循环的条件判断通常是.length或.size(),而不是p != end。
-
-
3、JavaScript
JS 继承了 C 的语法风格,但由于其动态特性和异步生态,循环变体很多。
-
C 风格:
for,while,do-while语法与 C 完全相同。 -
for...in: 遍历对象的可枚举属性(键)。 -
for...of(ES6): 遍历可迭代对象的值。 -
与 C 的异同:
-
相同点: 基础
for循环逻辑一致,常用于遍历数组索引。 -
不同点:
-
类型声明是可选的:
for (let i=0; ...)使用let/var/const代替 C 的int。 -
隐式类型转换: JS 的循环条件判断比 C 更“宽”,但也更容易踩坑(如
0 == false)。 -
遍历方式分离: C 语言只有一种遍历方式(索引/指针);JS 区分了遍历“索引/键”(
for-in)和遍历“值”(for-of)。
-
-
4、Go (Golang)
Go 语言删除了 C 风格的括号内的三段式 for 循环,并将 while 和 do-while 合并进了 for 关键字。
-
语法:
for init; condition; post { ... } -
替代
while:for condition { ... }(省略 init 和 post)。 -
替代
do-while: Go 没有直接等价物,通常需要配合for { if !condition { break } }。 -
Range 循环:
for i, v := range slice { ... } -
与 C 的异同:
-
相同点: 保留了
init; condition; post的结构,但必须加花括号,且左括号不能换行。 -
不同点:
-
语法简化: 只有
for一个关键字。 -
多变量赋值:
range可以同时返回索引和值,解决了 C 语言中i和array[i]同时书写的繁琐。 -
逗号 Ok 模式: 遍历 Map 时,可以只取 key 或同时取 key/value。
-
-
5、Rust
Rust 借鉴了 Ruby/Python 的迭代器思想,没有 C 风格的 for (i=0; i<n; i++) 循环。
-
无限循环:
loop { ... }(比 C 的while(1)更清晰,编译器可分析是否返回值)。 -
while循环:while condition { ... }(类似 C 的 while)。 -
for循环: 严格基于迭代器。for i in 0..5 { ... }。 -
与 C 的异同:
-
相同点: 保留了
while循环。 -
不同点:
-
消灭索引循环: Rust 强制使用迭代器。这避免了数组越界(C 语言最常见的 bug 之一)。如果必须用索引,也是用
(0..10).for_each(|i| ...)这种方式。 -
所有权机制: 在循环中,变量可能被 move,这是 C 语言没有的概念。
-
break可以带返回值:let result = loop { break 5; };,这在 C 中需要借助额外变量或函数返回。
-
-
6、Python
Python 彻底抛弃了 C 风格的 for (i=0;...) 和 do-while。
-
for循环: 本质是“foreach”。for item in iterable:。 -
while循环: 语法与 C 类似,但去掉了括号。 -
else分支: Python 循环可以带else,当循环正常结束(非 break)时执行。 -
与 C 的异同:
-
相同点:
while的逻辑流(判断-执行)与 C 一致。 -
不同点:
-
强制缩进: 用缩进代替 C 的花括号
{}。 -
没有
do-while: 通常用while True: ... if condition: break模拟。 -
没有前置条件的
for: C 的for可以做任何事(如死循环、复杂初始化);Python 的for只能遍历序列。如需计数,必须使用range()函数:for i in range(10):。
-
-
7、Lua
Lua 的循环语法非常独特,它使用 while...end 和 repeat...until,以及数值型 for 和泛型 for。
-
while:while condition do ... end。 -
repeat(do-while):repeat ... until condition(注意:until 条件为真时结束,C 的 do-while 是条件为假时继续,逻辑是反的)。 -
数值
for:for var = start, end, step do ... end。 -
与 C 的异同:
-
相同点: 逻辑控制流一致。
-
不同点:
-
for循环是数值范围,不是条件判断: C 的for(i=1; i<=10; i++)在 Lua 中写作for i=1, 10, 1 do。Lua 的for循环在进入循环前就确定了范围,循环体内修改i不会影响循环次数(C 语言中修改i会直接影响)。 -
泛型
for:for k, v in pairs(t) do ... end,极其强大的迭代器机制,用于遍历表。
-
-
8、PHP
PHP 保留了 C 风格的所有循环,并增加了 foreach。
-
C 风格:
for,while,do-while,用法与 C 几乎一模一样。 -
foreach:foreach ($arr as$value)或foreach ($arr as$key => $value)。 -
与 C 的异同:
-
相同点: PHP 的
for循环完全照搬 C,甚至包括在循环体中修改循环变量$i的行为。 -
不同点:
-
引用传值:
foreach ($arr as &$value)可以直接修改数组元素,这是 C 语言指针操作的高级封装。 -
数组指针: 虽然有
each()和next()函数(类似 C 的指针移动),但现代 PHP 推荐使用foreach。
-
-
9、Zig
Zig 是一门现代系统语言,试图保持 C 的简洁性但增加安全性。它的 for 循环非常强大。
-
while循环: 类似 C,但支持continue时的表达式(如while (i < 10) : (i += 1))。 -
for循环: 用于遍历数组、切片、Range。for (items) |item, index| { ... }。 -
与 C 的异同:
-
相同点: 保留了直接操作内存的能力,写法低层感强。
-
不同点:
-
显式捕获:
for循环可以显式捕获index和item,甚至用_忽略。 -
内联汇编感: Zig 的
while允许在循环标签处定义更新逻辑,这比 C 的for末段更灵活。 -
无隐式转换: 条件判断必须是
bool类型,C 语言允许int直接作为条件(非0即真),Zig 不允许。
-
-
现代语言的设计趋势是:让循环表达“意图”而不是“过程”。C 语言表达的是“我初始化一个变量,检查条件,增加变量,然后执行代码”;而现代语言倾向于表达“我要遍历这个集合中的每一个元素”。