# D (The Programming Language)/d2/Conditionals and Loops

 Topics: Language and Phobos - DGui (example placeholder - can be any library) Previous Lessons: 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - T

# Lesson 10: Conditionals and Loops

Conditionals and loops are essential for writing D programs.

## Introductory Code

### Palindrome Checker

```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: ");
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.");
}
}
```

### More Conditionals and Branching

```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!
*/
```

## Concepts

### The `if` and `else` Statements

Using `if` allows you to make part of your code only execute if a certain condition is met.

```    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
}
```

In fact, if the section of code that's inside the if or else is only one line long, you can omit the curly brackets.

```    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
```

As a result, this is often seen:

```   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();
}
```

### The Condition

The condition that goes inside of the parentheses in conditional statements such as `if` can be anything convertible to `bool`. That includes integral and floating-point types (`true` if nonzero, `false` if otherwise) and pointers (`null` is `false`, and dynamic arrays (always `true`).

### The `while` Loop

A while loop will allow you to repeat a block of code as long as a certain condition is met. There are two forms of the while loop:

```   while(condition1) {
do_this();
}
```

and

```   do {
do_this();
} while(condition1)
```

The difference is, in the first example, if condition1 is false, `do_this` is never called, while in the second example it would be called once (the conditional check happens after the code is executed once).

### The `foreach` Loop

This loop is for iteration. Take a look at these two ways to use `foreach`:

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

### The `for` Loop

This type of looping is the most complex, but it is also the one that gives a lot of control. It is defined in the same way as other C-like languages:

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

The initialization expression is executed only once during the beginning. Then condition is checked to be `true` or `false`. If it is `true`, the code inside of the conditional block (inside of the brackets) is executed. After that execution, the counting expression is executed. Then, the condition is checked, and if it is `true`, the loop continues. For example:

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

You can even omit parts of what goes inside the parentheses of the `for`. These two are equivalent:

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

### `break` and `continue`

These are two statements that are used inside of loops.

The `break` statement breaks out of the loop. Whenever the `break` statement is encountered, the loop is immediately exited. This statement can go inside of `while`, `for`, `foreach`, and `switch` blocks (you will learn about those later).

The `continue` statement causes a loop to restart at the beginning. Let's see, through code, exactly how this works. This code example counts to 7 but skips 5.

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

### Switches and More

D allows absolute branching with labels and `goto`.

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

Do not use these unless if you have to. Code that uses labels can most often be written with more readable looping constructs, like `for`, `while`, and `foreach`.

There is something in D, C and C++ called the `switch`. D's switches are actually more powerful than C and C++'s switches.

```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 { .. }
}
```

Note that you must have a `break` in order to get out of the switch. Otherwise, fall-through occurs. Also, you can use `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
*/
```

Strings can be used in `case`. This is a feature that's not in C or C++.

### `else`

(It doesn't seems to work in recent compilers).
You can use else for `foreach`, `while`, and `for` loops, too. If any of those loops have an `else` clause, then the `else` is only executed if the loop terminates normally (i.e. not with `break`).

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

//Output: No four found.
```