D Programming Language Tutorial
Ali Çehreli



İngilizce Kaynaklar

Diğer



Logical Expressions

Actual work that a program performs are accomplished by expressions. Any part of a program that produces a value or a side effect is called an expression. It has a very wide definition, because even a constant value like 42 and a string like "hello" are expressions because they produce the respective constant values 42 and "hello".

Note: Don't confuse producing a value with defining a variable. Values need not be associated with variables.

Function calls like writeln are expressions as well, because they have side effects. In the case of writeln, the effect is on the output stream by the placement of characters on it. Another example from the programs that we have written so far would be the assignment operation, which affects the variable on its left-hand side.

Because of producing values, expressions can take part in other expressions. This allows us to form more complex expressions from simpler ones. For example, assuming that there is a function named currentTemperature() that produces the value of the current air temperature, the value that it produces may directly be used in a writeln expression:

    writeln("It's ", currentTemperature(),
            " degrees at the moment.");

That line consists of four expressions:

  1. "It's "
  2. currentTemperature()
  3. " degrees at the moment."
  4. the writeln expression that makes use of the other three

In this chapter we will cover the particular type of expression that is used in conditional statements.

Before going further though, I would like to repeat the assignment operator once more, this time emphasizing the two expressions that appear on its left and right sides: the assignment operator (=) assigns the value of the expression on its right-hand side to the expression on its left-hand side (e.g. to a variable).

    temperature = 23      // temperature's value becomes 23
Logical Expressions

Logical expressions are the expressions that are used in Boolean arithmetic. Logical expressions are what makes computer programs make decisions like "if the answer is yes, I will save the file".

Logical expressions can have one of only two values: false that indicates falsity, and true that indicates truth.

I will use writeln expressions in the following examples. If a line has true printed at the end, it will mean that what is printed on the line is true. Similarly, false will mean that what is on the line is false. For example, if the output of a program is the following,

There is coffee: true

then it will mean that "there is coffee". Similarly,

There is coffee: false

will mean that "there isn't coffee". Note that the fact that "is" appears on the left-hand side does not mean that coffee exists. I use the "... is ...: false" construct to mean "is not" or "is false".

Logical expressions are used extensively in conditional statements, loops, function parameters, etc. It is essential to understand how they work. Luckily, logical expressions are very easy to explain and use.

The logical operators that are used in logical expressions are the following:

Grouping expressions

The order in which the expressions are evaluated can be specified by using parentheses to group them. When parenthesized expressions appear in more complex expressions, the parenthesized expressions are evaluated before they can be used in the expressions that they appear in. For example, the expression "if there is coffee or tea, and also cookie or scone; then I am happy" can be coded like the following:

writeln("I am happy: ",
(existsCoffee || existsTea) && (existsCookie || existsScone));

If the sub expressions were not parenthesized, the expressions would be evaluated according to operator precedence rules of D (which have been inherited from the C language). Since in these rules && has a higher precedence than ||, writing the expression without parentheses would not be evaluated as intended:

writeln("I am happy: ",
existsCoffee || existsTea && existsCookie || existsScone);

The && operator would be evaluated first and the whole expression would be the semantic equivalent of the following expression:

writeln("I am happy: ",
existsCoffee || (existsTea && existsCookie) || existsScone);

That has a totally different meaning: "if there is coffee, or tea and cookie, or scone; then I am happy".

Reading bool input

All of the bool values above are automatically printed as "false" or "true". It is not the case in the opposite direction: the strings "false" and "true" are not automatically read as the values false and true. For that reason, the input must be first read as a string and then be converted to a bool value.

Since one of the exercises below requires you to enter "false" and "true" from the standard input, I have been forced to use D features that I haven't explained to you yet. I will have to define a function below that will convert the input string to a bool value. This function will achieve its task by calling to, which is defined in the module std.conv. (You may see ConvException errors if you enter anything other than "false" or "true".)

I am hoping that all of the code that are in the main() functions of the following programs are clear at this point. read_bool() is the function that contains new features. Although I have inserted comments to explain what it does, you can ignore that function for now. Still, it must be a part of the source code for the program to compile and work correctly.

Exercises
  1. We've seen above that the < and the > operators are used to determine whether a value is less than or greater than another value; but there is no operator that answers the question "is between?" to determine whether a value is between two other values.
  2. Let's assume that a programmer has written the following code to determine whether value is between 10 and 20. Observe that the program cannot be compiled as written:

    import std.stdio;
    
    void main()
    {
        int value = 15;
    
        writeln("Is between: ",
                10 < value < 20);        // ← compilation ERROR
    }
    

    Try using parentheses around the whole expression:

        writeln("Is between: ",
                (10 < value < 20));      // ← compilation ERROR
    

    Observe that it still cannot be compiled.

  3. While searching for a solution to this problem, the same programmer discovers that the following use of parentheses now enables the code to be compiled:
  4.     writeln("Is between: ",
                (10 < value) < 20);      // ← compiles but WRONG
    

    Observe that the program now works as expected and prints "true". Unfortunately that output is misleading because the program has a bug. To see the effect of that bug, replace 15 with a value greater than 20:

        int value = 21;
    

    Observe that the program still prints "true" even though 21 is not less than 20.

    Hint: Remember that the type of a logical expression is bool. It shouldn't make sense whether a bool value is less than 20.

  5. The logical expression that answers the question "is between?" must instead be coded like this: "is greater than the lower value and less than the upper value?"
  6. Change the expression in the program according to that logic and observe that it now prints "true" as expected. Additionally, test that the logical expression works correctly for other values as well: for example, when value is 50 or 1, the program should print "false"; and when it's 12, the program should print "true".

  7. Let's assume that we can go to the beach when one of the following conditions is true:
    • If the distance to the beach is less than 10 and there is a bicycle for everyone
    • If there is less than 6 of us, and we have a car, and one of us has a driver license

    As written, the following program always prints "true". Construct a logical expression that will print "true" when one of the conditions above is true. (When trying the program, enter "false" or "true" for questions that start with "Is there a".). Don't forget to include the read_bool() function when testing the following program:

    import std.stdio;
    import std.conv;
    import std.string;
    
    void main()
    {
        write("How many are we? ");
        int personCount;
        readf(" %s", &personCount);
    
        write("How many bicycles are there? ");
        int bicycleCount;
        readf(" %s", &bicycleCount);
    
        write("What is the distance to the beach? ");
        int distance;
        readf(" %s", &distance);
    
        bool existsCar = read_bool("Is there a car? ");
        bool existsLicense =
            read_bool("Is there a driver license? ");
    
        /*
          Replace the 'true' below with a logical expression that
          produces the value 'true' when one of the conditions
          listed in the question is satisfied:
         */
        writeln("We are going to the beach: ", true);
    }
    
    /*
      Please note that this function includes features that will
      be explained in later chapters.
     */
    bool read_bool(string message)
    {
        // Print the message
        write(message, "(false or true) ");
    
        // Read the line as a string
        string input;
        while (input.length == 0) {
            input = chomp(readln());
        }
    
        // Produce a 'bool' value from that string
        bool result = to!bool(input);
    
        // Return the result to the caller
        return result;
    }
    

    Enter various values and test that the logical expression that you wrote works correctly.

... the solutions