一个很多人没想过的问题:为什么编程语言有 for,还要设计 while?

刚开始学编程的时候,我也被一个问题困扰了很久:

既然 for 循环和 while 循环都能实现重复执行代码, 那为什么编程语言要同时提供这两种? 这不是多此一举吗?

当时的我觉得自己很聪明,甚至隐隐觉得:

“这语言设计得不太优雅。”

但后来写了几年代码、踩过无数坑,再回头看才发现—— 这个问题本身,就暴露了我当年只是在“写语法”,还没真正理解“编程”。

-****01-

**表面看一样,其实“关注点完全不同” **

先看一组最经典的对比:

<pre data-start="542" data-end="692" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); margin: 0px; padding: 0px; outline: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;">

// for 循环 for (let i = 0; i < 5; i++) { console.log(i); } // while 循环 let i = 0; while (i < 5) { console.log(i); i++; }

</pre>

输出一模一样,对吧?

但如果你只是停在“结果一样”,那你就错过了关键点

真正的差别在于:语言在帮你强调什么

维度 for 循环 while 循环
初始化 集中在一行 分散在代码中
条件判断 显式 显式
状态更新 强制出现 程序员自己保证
关注重点 执行多少次 什么时候结束

for 是“次数驱动”,while 是“条件驱动”。

[图片上传失败...(image-4f0e74-1767606721008)]

-****02-

**for = 计数思维,while = 状态思维 **

1. for 循环:我清楚“要做多少次”

<pre data-start="1018" data-end="1187" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); margin: 0px; padding: 0px; outline: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;">

// 遍历数组:元素个数是确定的 for (let i = 0; i < users.length; i++) { processUser(users[i]); } // 固定次数的操作 for (let i = 0; i < 10; i++) { createButton(); }

</pre>

for 循环在语法层面就已经告诉你:

****这是一个“有明确边界”的过程****

这对阅读代码的人非常友好。

2. while 循环:我只关心“什么时候停”

<pre data-start="1284" data-end="1436" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); margin: 0px; padding: 0px; outline: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;">

// 等待用户输入 while (!userInput) { userInput = getUserInput(); } // 处理队列 while (queue.length > 0) { processTask(queue.shift()); }

</pre>

while 的潜台词是:

****“我不知道会跑多久,但我知道停止条件。”****

[图片上传失败...(image-3e9532-1767606721008)]

-****03-

为什么语言设计者要保留 while?

这里得稍微讲点历史。

早期的世界:只有 goto(人类的噩梦)

<pre data-start="1570" data-end="1627" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); margin: 0px; padding: 0px; outline: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;">

LOOP_START: ; 执行代码 JMP LOOP_START

</pre>

  • 可读性极差

  • 稍不注意就死循环

  • 代码像一团意大利面

结构化编程的革命

后来语言设计者提出三种基本结构:

  • 顺序

  • 分支

  • 循环

其中:

  • while:最小、最基础的循环抽象(“当条件成立时执行”)

  • for:在 while 之上的“高级语法糖”,专门服务计数场景

不是 while 多余,而是 for 太常用了,所以被“单独优化”了。

真实项目里,它们的分工非常清晰

for 更适合这些场景

<pre data-start="1893" data-end="2089" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); margin: 0px; padding: 0px; outline: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;">

// 已知长度 for (let i = 0; i < items.length; i++) { console.log(items[i]); } // 倒序 for (let i = items.length - 1; i >= 0; i--) {} // 非 1 步长 for (let i = 0; i < 100; i += 5) {}

</pre>

优势关键词:

  • 作用域清晰

  • 边界明确

  • 不容易写出死循环

while 更适合这些场景

<pre data-start="2149" data-end="2286" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); margin: 0px; padding: 0px; outline: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;">

// 不确定次数 while (!isDataLoaded) { awaitsleep(100); } // 状态驱动 while (gameIsRunning) { update(); render(); }

</pre>

优势关键词:

  • 贴近业务语义

  • 条件灵活

  • 更像“自然语言”

[图片上传失败...(image-76fac1-1767606721007)]

-****04-****为什么 forEach / map 不能完全取代 for?

这是很多新手的第二个误区

<pre data-start="2383" data-end="2587" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); margin: 0px; padding: 0px; outline: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;">

functionfindFirstMatch(items, condition) { for (let i = 0; i < items.length; i++) { if (condition(items[i])) { return i; // 直接退出 } } return -1; }

</pre>

而 forEach 呢?

<pre data-start="2603" data-end="2666" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0); margin: 0px; padding: 0px; outline: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;">

items.forEach(item => { // 不能 break });

</pre>

一旦涉及提前退出、复杂控制流,传统 for 仍然是最优解。

[图片上传失败...(image-76dfd7-1767606721004)]

-****05-****总结

真正的选择原则

记住这两句话就够了:

我是在“数次数”,还是在“等条件”?

  • 数次数 for

  • 等条件 while

  • 数据转换 map / filter

  • 查找 + 提前退出 for

为什么语言要提供两种循环?

因为它们解决的是两类完全不同的问题

  • for:结构化、边界明确、适合阅读

  • while:语义自然、状态驱动、贴近现实

就像工具箱里同时有螺丝刀和扳手, 不是为了炫技,而是为了让你在正确的场景,用最顺手的工具。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容