【问题标题】:Is there any programming language which has a for-while loop?是否有任何具有 for-while 循环的编程语言?
【发布时间】:2017-04-27 04:23:59
【问题描述】:

这就是我所说的 for-while 循环:

for (<init>; <update>) <body> while (<test>);

大致翻译为:

<init>
<body>

while (<test>) {
    <update>
    <body>
}

这似乎是very common programming pattern。然而,我所知道的任何语言都没有这样的控制结构。因此,一个常见的解决方法是按如下方式实现它:

<init>

while (true) {
    <body>
    unless (<test>) break;
    <update>
}

虽然这可行,但感觉非常笨拙。在我看来,在无限 while 循环中间有条件中断违背了结构化编程的精神。

这是一个需要 for-while 循环的激励示例:

function swap(arr, i, j) {
    var tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
    return arr;
}

function heapify(heap, i) {
    var len = heap.length;

    for (var min = i; swap(heap, i, min), i = min) {
        var left  = 2 * i + 1;
        var right = 2 * (i + 1);

        if (left  < len && heap[left]  < heap[min]) min = left;
        if (right < len && heap[right] < heap[min]) min = right;
    } while (min !== i);

    return heap;
}

如您所见,该控件非常易于操作,并且代码比解决方法更简洁:

function swap(arr, i, j) {
    var tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
    return arr;
}

function heapify(heap, i) {
    var len = heap.length;
    var min = i;

    do (true) {
        var left  = 2 * i + 1;
        var right = 2 * (i + 1);

        if (left  < len && heap[left]  < heap[min]) min = left;
        if (right < len && heap[right] < heap[min]) min = right;

        if (min === i) break;
        swap(heap, i, min);
        i = min;
    }

    return heap;
}

不管怎样,你知道有什么编程语言有这样的控制结构吗? Lisp 不算,因为它主要是功能性的,我正在寻找一种主要是命令式的编程语言。

【问题讨论】:

  • 如此“非常常见的编程模式”,我想我在四年的日志职业生涯中从未见过它?:-)
  • @paxdiablo 也许你不会编写很多需要这种控制结构的程序,这很好。然而,在我长达十年的编程经验中,我多次遇到过这种模式。这不是一个很常见的模式。但是,我认为需要一个新的控制结构是很常见的。
  • @paxdiablo 这是一个Python Enhancement Proposal,用于控制结构类似于我所描述的结构。这表明我所描述的编程模式确实并不少见。
  • @paxdiablo 顺便说一下,这种模式似乎被称为Loop and a Half 模式。因此,这确实是一种非常普遍的模式。
  • 为什么要用“for-while”而不是“do-while”和可选的 表达式?就像do { &lt;body&gt; } while (&lt;test&gt;; &lt;update&gt;); 一样,“do”关键字和结构已经暗示了 before 测试的执行。 "for" 关键字通常暗示了一个长期建立的模式,即 然后 之前。这不会改变需求也不会回答您的问题,但关键字选择更有意义。

标签: loops language-features structured-programming


【解决方案1】:

我意识到这不是一个完全令人满意的答案,因为 c# 没有这样的内置控制结构,但我最初预计语法会更简洁,因此它几乎是您正在寻找的. (事实证明,c# 不会将 lambda 表达式隐式转换为布尔函数,因此表达式周围有显式的“垃圾”。)

除此之外,以下 c# 代码演示了我在 cmets 中提到的备用关键字选择:do { &lt;body&gt; } while (&lt;test&gt;; &lt;update&gt;)。这种 do-while-update 语法比您建议的 for-while 语法更好地匹配模式流。除非您关心构造变量的范围,否则任何新构造都需要为&lt;init&gt; 提供一个特殊位置(如 for 循环)已经值得怀疑,但根据我的经验,现有的 do-construct 无论如何都没有提供。

var min = i; //<init>
do {
    //<body>
    var left = 2 * i + 1;
    var right = 2 * (i + 1);

    if (left < len && heap[left] < heap[min])
        min = left;
    if (right < len && heap[right] < heap[min])
        min = right;
} while ((min != 1) // <test>
    ? ((Func<bool>)(() => {
        swap(heap, i, min); i = min; //<update>
        return true; }))() : false);

注意:三元条件运算符确保&lt;update&gt; 部分仅在&lt;test&gt; 为真时执行。

【讨论】:

    猜你喜欢
    • 2011-09-30
    • 2012-01-05
    • 2015-04-24
    • 1970-01-01
    • 1970-01-01
    • 2015-02-13
    • 2012-01-02
    • 1970-01-01
    相关资源
    最近更新 更多