Topics To Cover

Blocks


if(   )
{
  // then-block
}
else
{
  // else-block
}
Code in between {}'s forms a block. Therefore:
  • The if is followed by a block (i.e., the then block)
  • The else is followed by a block (i.e., the else block).

So, suppose I wanted to write a program that works as follows:

Compute areas of circles and triangles for the user, first asking the user which kind of object he was interested in.

Important: See if you can write the program on your own. Although this problem looks simple, a lot of students have struggled to solve this problem (or its similar kind).

Sample runs (with user input in red):

$ ./area
Do you have a circle or a triangle? circle
Enter the radius of your circle: 1
Area equals 3.14
$ ./area
Do you have a circle or a triangle? triangle
Enter base length: 1
Enter height: 1
Area equals 0.5
For simplicity, use 3.14 for π.

Hint: Read the input over multiple stages. In addition, it's better to declare necessary variables inside the relevant block.

Solutions: the program.

Scope

Consider the following code.

int k;
cin >> k;
if ((k % 2) == 0)
{
  string s;
  s = "even";
}
else
{
  string s;
  s = "odd";
}
cout << s << endl;
The code is slightly different from what we saw in the last lecture. In particular:
  • We assign a variable of type string the value "even" if k is even and "odd" otherwise.
  • Then, after the if-statment, we'll do the printing. We might implement it like this:

However, when we try to compile this the compiler complains as follows:

s is an undeclared identifier.
This is exactly what the compiler would say if we'd never defined s at all. Well, as far as the compiler is concerned when it processes the "cout << s << endl;" statement, we haven't defined s.

int k;
cin >> k;
if ((k % 2) == 0)
{
string s; s = "even";
} else {
string s; s = "odd";
} cout << s << endl;


The above problem is caused by the scope of variables in C++.
  • The scope of a variable is the portion of the code that "sees" the variable, i.e. that knows it exists.
  • The scope of a variable ends with the innermost block in which it was defined.
  • In this case, each blue rectangle shows the scope of each variable s.

The statement cout << s << endl; is outside of the scope, in which the variable s doesn't exist!


int k;
cin >> k;
string s; if ((k % 2) == 0) { s = "even"; } else { s = "odd"; } cout << s << endl;
To fix the problem, we simply need to move the declaration of s outside of the if/else-blocks so that its scope extends to cout statement.

Let's check your understanding on scope

Given the code below, what should be the output?
code output

int a;
a = 3;
cout << a << endl;

{
  // you can create a block without an if statement!
  int a;
  a = 5;
  cout << a << endl;
}

cout << a << endl;
Drag your mouse below.
3
5
3
To see what is going on in more detail, let's check the address of the variables.
code output memory diagram
 
// ...
 1:  int a;   // location 0 
 2:  a = 3;
 3:  cout << a << endl;
 4:  cout << &a << endl;
 5:  
 6:  {
 7:   int a;  // location 1
 8:   a = 5;
 9:   cout << a << endl;
10:   cout << &a << endl;
11:  }
12:  
13:  cout << a << endl;
14:  cout << &a << endl;
3
0x7fffd00e5240
5
0x7fffd00e5244
3
0x7fffd00e5240
   address           contents      (variables)
...
0x7fffd845c238
0x7fffd845c23c
0x7fffd845c240          3          a in location 0
0x7fffd845c244          5          a in location 1
0x7fffd845c248
0x7fffd845c24c
0x7fffd845c250
...
  • As you see in the above diagram, the variable a defined in location 0 is located at address 0x...240. This variable is accessed in lines 2-4 and lines 13-14.
  • However, the variable a defined in location 1 is located at address 0x...244. This variable is accessed in lines 8-10.
  • In summary, you are allowed to define a variable in an inner block whose name is the same as an variable outside of the block. However, these variables each have their own storage, even though the name is the same.

Other questions on scope

  1. (True/False) The following code compiles successfully.
    
    int a;
    a = 4;
    int a;
    a = 5;
    
    Answer:
    False. You are not allowed to define different variables with the same name in the same block. 
    
  2. Consider the following code and its output.
    code output
     
    //...
     1:  int a;
     2:  cout << &a << endl;
     3: 
     4:  {
     5:      int b;
     6:      cout << &b << endl;
     7:  }
     8:
     9:  int c;
    10:  cout << &c << endl;
    
    0x7fffce54efa0
    0x7fffce54efa4
    0x7fffce54efa4
    
    Why is the address of variable b the same as the address of variable c?

    Answer (Drag your mouse below):

    The variable b was destroyed when the inner block ends at line 7. This space (for variable b) was reused when variable c is newly defined at line 9.

Blocks and Indentation

Read the section of "Curly Braces" in Programming Style Guide

Shortcut: Dropping {}'s from one-statement blocks

If your then-block (or else-block) consists of a single statement, you can drop the {}'s - but only if it consists of a single statement! This is just a shorthand to save you some keystrokes and a little bit of screen realestate. So, for example, in the previous code fragment we may remove the {}'s, since both blocks consist of a single statement.
 
int k;
cin >> k;
string s;

if ((k % 2) == 0)
  s = "even";
else
  s = "odd";

cout << s << endl;
This is just a shortcut to save keystroks and screen space, but you will see this shortcut often.

A common pitfall

If you try to drop the {}'s when you have more than one thing in the block, you'll run into trouble.
WrongRight
 
if ((k % 2) == 0)
  s = "even";
  cout << s << endl;
else
  s = "odd";
  cout << s << endl;
  
if ((k % 2) == 0)
{
  s = "even";
  cout << s << endl;
}
else
{
  s = "odd";
  cout << s << endl;
}
The code snippet on the left will not compile successfully.

Mandatory Practice Problems

Other Practice Problems

  1. Remainders - this is a toy problem that forces you to face a fundamental problem in computer science: swapping values. This is important to know and understand!

Do you know ...