跳转到内容

D(编程语言)/d2/条件语句和循环

50% developed
维基教科书,开放的书,开放的世界

第 10 课:条件语句和循环

[编辑 | 编辑源代码]

条件语句和循环对于编写 D 程序至关重要。

入门代码

[编辑 | 编辑源代码]

回文检测器

[编辑 | 编辑源代码]
module palindromes;

import std.stdio;

bool isPalindrome(string s)
{
    int length = s.length;
    int limit = length / 2;
    for (int i = 0; i < limit; ++i)
    {
        if (s[i] != s[$ - 1 - i])
        {
            return false;
        }
    }
    return true;
}

void main()
{
    string[] examples = ["", "hannah", "socks", "2002", ">><<>>", "lobster"];
    foreach(e; examples)
    {
        if(!e.length) continue;  // skip that empty string

        if(isPalindrome(e))
            writeln(e, " is an example of a palindrome.");
        else
            writeln(e, " is an example of what's not a palindrome.");
    }
    while(true)
    {
        write("Type any word: ");
        string input = readln();
        if(input.length <= 1)  // length == 1 means input == "\n"
            break;  // nothing was typed
        input = input[0 .. $-1];  // strip the newline
        if(isPalindrome(input))
            writeln(input, " is a palindrome.");
        else
            writeln(input, " is not a palindrome.");
    }
}

更多条件语句和分支

[编辑 | 编辑源代码]
import std.stdio;

string analyzeHoursOfSleep(int hours)
{
    if(!hours) return "You didn't sleep at all.";
    
    string msg = "";
    switch(hours)
    {
        case 1,2,3:
            msg ~= "You slept way too little!  ";
            goto case 7;
        case 4: .. case 6:
            msg ~= "Take a nap later to increase alertness.  ";
        case 7:
            msg ~= "Try to go back to sleep for a bit more.  ";
            break;
        default:
            msg ~= "Good morning.  Grab a cup of coffee.  ";
    }
    return msg ~ '\n';
}

void main()
{
    writeln(analyzeHoursOfSleep(3));
    writeln(analyzeHoursOfSleep(6));
    writeln(analyzeHoursOfSleep(7));
    writeln(analyzeHoursOfSleep(13));
    
    int i = 0;
L1: while(true)
    {
        while(true)
        {
            if(i == 3)
                break L1;
            i++;
            break;
        }
        writeln("Still not out of the loop!");
    }
}

/*
Output:
You slept way too little!  Try to go back to sleep for a bit more.

Take a nap later to increase alertness.  Try to go back to sleep for a bit more.

Try to go back to sleep for a bit more.

Good morning.  Grab a cup of coffee.

Still not out of the loop!
Still not out of the loop!
Still not out of the loop!
*/

ifelse 语句

[编辑 | 编辑源代码]

使用 if 允许您只在满足特定条件时执行代码的一部分。

    if(condition that evaluates to true or false)
    {
        // code that is executed if condition is true
    } else {
        // code that is executed if condition is false
    }

事实上,如果 ifelse 中的代码段只有一行长,则可以省略花括号。

    if(condition1) do_this();
    else if(condition2) do_that();  // only executed if condition1 is false, but
    // condition2 is true
    else do_the_other_thing();  // only executed if both condition1 and condition2 are false

因此,这经常被看到

   if (condition1) {
       do_something1();
       something_more1();
   } else if(condition2) {
       do_something2();
       something_more2();
   } else if(condition3) {
       do_something3();
       something_more3();
   } else if(condition4) {
       do_something4();
       something_more4();
   } else {
       do_something_else();
   }

放在 if 等条件语句中的括号内的条件可以是任何可以转换为 bool 的值。这包括整型和浮点型(非零值为 true,否则为 false)以及指针(nullfalse)和动态数组(始终为 true)。

while 循环

[编辑 | 编辑源代码]

while 循环允许您重复执行代码块,直到满足特定条件为止。while 循环有两种形式

   while(condition1) {
       do_this();
   }

   do {
       do_this();
   } while(condition1)

区别在于,在第一个示例中,如果 condition1 为假,则不会调用 do_this,而在第二个示例中,它将被调用一次(条件检查发生在代码执行一次之后)。

foreach 循环

[编辑 | 编辑源代码]

此循环用于 迭代。看看使用 foreach 的两种方法

foreach(i; [1,2,3,4]) {
    writeln(i);
}
foreach(i; 1 .. 5) { writeln(i); }  // equivalent to above

for 循环

[编辑 | 编辑源代码]

这种类型的循环是最复杂的,但它也是最能控制的。它与其他类 C 语言的定义方式相同

   for(initialization; condition; counting expression) { ... }

初始化 表达式仅在开头执行一次。然后检查 condition 是否为 truefalse。如果为 true,则执行条件块内的代码(括号内的代码)。执行完该代码后,将执行 计数表达式。然后,检查 condition,如果为 true,则继续循环。例如

for(int i=0; i <= 5; i++)
{
    write(i);
}
// output: 012345

您甚至可以省略 for 括号内的部分内容。以下两者是等价的

for(int i=0; i==0; ) {
    i = do_something();
}
int i = 0;
while(i == 0) {
    i = do_something();
}

breakcontinue

[编辑 | 编辑源代码]

这是两种在循环中使用的语句。

break 语句会跳出循环。每当遇到 break 语句时,循环会立即退出。此语句可以放在 whileforforeachswitch 块内(您将在后面学习这些块)。

continue 语句会导致循环从开头重新开始。让我们通过代码看看它是如何工作的。此代码示例计算到 7,但跳过 5。

for(int i = 0; i <= 7; i++)
{
    if(i == 5) continue;
    writeln(i);
}

switch 和更多

[编辑 | 编辑源代码]

D 允许使用标签和 goto 进行绝对分支。

int i = 0;
looper:  // this is a label
write(i);
i++;
if(i < 10) goto looper;
writeln("Done!");
// 0123456789Done!

除非必须,否则不要使用它们。使用标签的代码通常可以用更易读的循环结构(如 forwhileforeach)来编写。

D、C 和 C++ 中有一个叫做 switch 的东西。D 的 switch 实际上比 C 和 C++ 的 switch 更强大。

switch(age)
{
   case 0,1:  // if(age == 0 || age == 1) { ... }
       writeln("Infant");
       break;
   case 2,3,4:  // else if (age == 2 || age == 3 || age == 4) { .. }
       writeln("Toddler");
       break;
   case 5: .. case 11:
       writeln("Kid");
       break;
   case 12:
       writeln("Almost teen");
       break;
   case 13: .. case 19:
       writeln("Teenager");
       break;
   default:  // else { .. }
       writeln("Adult");
}

请注意,您必须使用 break 才能跳出 switch。否则,会发生 贯穿。此外,您可以使用 goto

int a = 3;
switch(a)
{
    case 1:
        writeln("Hello");
    case 2:
        writeln("Again");
        break;
    case 3:
        goto case 1;
    default:
        writeln("Bye");
}
/* output: Hello
           Again
*/

字符串可以在 case 中使用。这是 C 或 C++ 中没有的功能。

(它似乎在最近的编译器中不起作用)。
您也可以对 foreachwhilefor 循环使用 else。如果这些循环中的任何一个都有一个 else 子句,那么只有当循环正常终止(即不使用 break)时,才会执行 else

int[] arr = [1,2,3,5,6];
foreach(item; arr)
{
    if(item == 4) break;
}
else
{
    writeln("No four found.");
}

//Output: No four found.
华夏公益教科书