Beginning Visual C# 2005
Authors: Watson K. Nagel C. Pedersen J.
Published year: 2005
Pages: 28-30/278
Buy this book on amazon.com >>

Exercises

  1. In the following code, how would you refer to the name great from code in the namespace fabulous ?

    
    namespace fabulous
    
    
    {
    
    
    // code in fabulous namespace
    
    
    }
    
    
    namespace super
    
    
    {
    
    
    namespace smashing
    
    
    {
    
    
    // great name defined
    
    
    }
    
    
    }
    
    
  2. Which of the following is not a legal variable name?

    • myVariableIsGood

    • 99Flake

    • _floor

    • time2GetJiggyWidIt

    • wrox.com

  3. Is the string "supercalifragilisticexpialidocious" too big to fit in a string variable? Why?

  4. By considering operator precedence, list the steps involved in the computation of the following expression:

    
    resultVar += var1 * var2 + var3 % var4 / var5;
    
    
  5. Write a console application that obtains four int values from the user and displays the product. Hint: you may recall that the Convert.ToDouble() command was used to covert the input from the console to a double; the equivalent command to convert from a string to an int is Convert.ToInt32() .



Chapter 4: Flow Control

Overview

All of the C# code you've seen so far has had one thing in common. In each case, program execution has proceeded from one line to the next in top-to-bottom order, missing nothing. If all applications worked like this then you would be very limited in what you could do.

In this chapter, you look at two methods of controlling program flow, that is, the order of execution of lines of C# code. These two methods are:

  • Branching , where you execute code conditionally, depending on the outcome of an evaluation, such as "only execute this code if myVal is less than 10."

  • Looping , or repeatedly executing the same statements (for a certain number of times or until a test condition has been reached).

Both of these techniques involve the use of Boolean logic . In the last chapter you saw the bool type, but didn't actually do much with it. In this chapter you use it a lot, and so the chapter will start by discussing what is meant by Boolean logic so that you can use it in flow control scenarios.



Boolean Logic

The bool type introduced in the last chapter can hold one of only two values, true or false . This type is often used to record the result of some operation, so that you can act on this result. In particular, bool types are used to store the result of a comparison .

Note

As an historical aside, it is worth remembering (and respecting) the English mathematician George Boole, whose work in the mid-nineteenth-century forms the basis of Boolean logic.

As an example, consider the situation (as mentioned in the introduction to this chapter) that you want to execute code based on whether a variable, myVal , is less than 10. To do this, you need some indication of whether the statement " myVal is less than 10" is true or false, that is, you need to know the Boolean result of a comparison.

Boolean comparisons require the use of Boolean comparison operators (also known as relational operators), which are shown in the following table. In all cases here var1 is a bool type variable, while the types of var2 and var3 may vary.

Operator

Category

Example Expression

Result

==

Binary

var1 = var2 == var3;

var1 is assigned the value true if var2 is equal to var3 , or false otherwise .

!=

Binary

var1 = var2 != var3;

var1 is assigned the value true if var2 is not equal to var3 , or false otherwise.

<

Binary

var1 = var2 < var3;

var1 is assigned the value true if var2 is less than var3 , or false otherwise.

>

Binary

var1 = var2 > var3;

var1 is assigned the value true if var2 is greater than var3 , or false otherwise.

<=

Binary

var1 = var2 <= var3;

var1 is assigned the value true if var2 is less than or equal to var3 , or false otherwise.

>=

Binary

var1 = var2 >= var3;

var1 is assigned the value true if var2 is greater than or equal to var3 , or false otherwise.

You might use operators such as these on numeric values in code such as:


bool isLessThan10;


isLessThan10 = myVal < 10;

This code will result in isLessThan10 being assigned the value true if myVal stores a value less than 10, or false otherwise.

You can also use these comparison operators on other types, such as strings:


bool isKarli;


isKarli = myString == "Karli";

Here, isKarli will only be true if myString stores the string "Karli" .

You can also focus on Boolean values:


bool isTrue;


isTrue = myBool == true;

although here you are limited to the use of == and != operators.

Note

Note that a common code error occurs if you unintentionally assume that because val1 < val2 is false, then val1 > val2 is true. If val1 == val2 then both these statements will be false. I'm mentioning this here because it's a mistake I've made in the past!

There are some other Boolean operators that are intended specifically for working with Boolean values, shown in the following table.

Operator

Category

Example Expression

Result

!

Unary

var1 = ! var2;

var1 is assigned the value true if var2 is false , or false if var2 is true . (Logical NOT.)

&

Binary

var1 = var2 & var3;

var1 is assigned the value true if var2 and var3 are both true , or false otherwise. (Logical AND.)

Binary

var1 = var2 var3;

var1 is assigned the value true if either var2 or var3 (or both) are true , or false otherwise. (Logical OR.)

^

Binary

var1 = var2 ^ var3;

var1 is assigned the value true if either var2 or var3 , but not both, are true, or false otherwise. (Logical XOR, or exclusive OR.)

So, the last code snippet above could also be expressed as:


bool isTrue;


isTrue = myBool & true;

The & and operators also have two similar operators, known as conditional Boolean operators, shown in the next table.

Operator

Category

Example Expression

Result

&&

Binary

var1 = var2 && var3;

var1 is assigned the value true if var2 and var3 are both true , or false otherwise. (Logical AND.)

Binary

var1 = var2 var3;

var1 is assigned the value true if either var2 or var3 (or both) are true, or false otherwise. (Logical OR.)

The result of these operators is exactly the same as & and , but there is an important difference in the way this result is obtained, which can result in better performance. Both of these look at the value of their first operand ( var2 in the preceding table) and based on the value of this operand may not need to process the second operator ( var3 above) at all.

If the value of the first operand of the && operator is false , then there is no need to consider the value of the second operand, because the result will be false regardless. Similarly, the operator will return true if its first operand is true , regardless of the value of the second operand.

This isn't the case for the & and operators you saw earlier. With these, both operands will always be evaluated.

Because of this conditional evaluation of operands, you will see a small performance increase if you use && and instead of & and . This will be particularly apparent in applications that use these operators a lot. As a rule of thumb, always use && and where possible.

Note that these operators really come into their own in more complicated situations, where computation of the second operand is only possible with certain values of the first operand, for example:


var1 = (var2 != 0) && (var3 / var2 > 2);

Here, if var2 is zero then dividing var3 by var2 will result in either a "division by zero" error or var1 being defined as infinite (the latter is possible, and detectable, with some types such as float ).

Bitwise Operators

In the light of the discussion in the last section, you may be asking why the & and operators exist at all. The reason is that these operators may be used to perform operations on numeric values. In fact, they operate on the series of bits stored in a variable rather than the value of the variable.

Let's consider these in turn , starting with & . Each bit in the first operand is compared with the bit in the same position in the second operand, resulting in the bit in the same position in the resultant value being assigned a value as shown in the following table.

Operand 1 Bit

Operand 2 Bit

& Result Bit

1

1

1

1

1

is similar, but the result bits are different, as shown in the next table.

Operand 1 Bit

Operand 2 Bit

Result Bit

1

1

1

1

1

1

1

For example, consider the operation shown in the following code:


int result, op1, op2;


op1 = 4;


op2 = 5;


result = op1 & op2;

Here, you must consider the binary representations of op1 and op2 , which are 100 and 101, respectively. The result is obtained by comparing the binary digits in equivalent positions in these two representations as follows :

  • The leftmost bit of result is 1 if the leftmost bit of op1 and op2 are both 1, or 0 otherwise.

  • The next bit of result is 1 if the next bit of op1 and op2 are both 1, or 0 otherwise.

  • Continue for all remaining bits.

In this example, the leftmost bits of op1 and op 2 are both 1, so the leftmost bit of result will be 1, too. The next bits are both 0, and the third bits are 1 and 0, respectively, so the second and third bits of result will be 0. The final value of result in binary representation is, therefore, 100, so result is assigned the value 4. This is shown graphically in the following table.

1

4

&

1

1

&

5

1

4

The same process occurs if you use the operator, except that in this case each result bit is 1 if either of the operand bits in the same position is 1. This is shown in the next table.

1

4

1

1

5

1

1

5

You can also use the Δ ^ operator in the same way, where each result bit is 1 if one or other of the operand bits in the same position is one, but not both, as shown in the following table.

Operand 1 Bit

Operand 2 Bit

^ Result Bit

1

1

1

1

1

1

C# also allows the use of a unary bitwise operator ( ~ ), which acts on its operand by inverting each of its bits, such that the result is a variable having values of 1 for each bit in the operand that is 0, and vice versa: This is shown in the following table.

Operand Bit

~ Result Bit

1

1


Beginning Visual C# 2005
Authors: Watson K. Nagel C. Pedersen J.
Published year: 2005
Pages: 28-30/278
Buy this book on amazon.com >>

Similar books