Methods (or functions)

We can make new commands (or methods). This lets us decompose our program into smaller pieces that are easier to understand.
type name()
{
  statement1;
  statement2;
  ...
}

Example:

int printGreeting()
{
  cout << "Hello, world!" << endl;
  cout << "I hope you had a great day.";
  return 0;
}

int main()
{
  string name = readLine("Next name? ");
  while (name != "")
  {
    printGreeting();
    name = readLine("Next name? ");
  }
  return 0;
}
Introduce the void type. Replace return type of printGreeting with void.

Is the following code correct?

void printGreeting()
{
  cout << "Hello " << name << endl;
  cout << "I hope you had a great day.";
}

int main()
{
  string name = readLine("Next name? ");
  while (name != "")
  {
    printGreeting();
    name = readLine("Next name? ");
  }
  return 0;
}
No. Why? Because name is an undefined variable inside printGreeting.

Another example:

void run()
{
  int x = 2;
  printX();
}

void printX()
{
  cout << "X has value " << x << endl; //ERROR: "Undefined variable x"
}

Scope and Parameters

int x = 5;
if (someCondition()) {
  int y = 5;
}
cout << x + y << endl; //Error: Undefined variable y
Run through this program assuming that someCondition is true. Show how at closing braces, y becomes history.

When a program exits a code block, all variables declared inside that block go away!

The scope of a variable refers to the section of code where a variable can be accessed:

Variables have a lifetime (called scope):

int main()
{
  double v = 8; //comes to life here ...
  if (condition) {
    v = 4;  //still alive here ...
    ... some code
  }
  ... some other code
} //it goes away here (at the end of its code block)
The code block representing the full body of the function is the inner most code block in which it was declared. Another example:
int main()
{
  ... some code
  if (condition) {
    int w = 4;  //w is created here
    ... some code
  } //w goes away here (at the end of its code block)
  ... some other code
}
Draw a box around the inner code block to show the scope of w.

You cannot have two variables with the same name in the same scope.

int main()
{
  ... some code
  if (condition) {
    int w = 4;  //w is created here
    ... some code
    int w = 4; //ERROR!
  } //w goes away here (at the end of its code block)
  ... some other code
}

Another example: variables declared in the for construct are assumed to belong to the scope defined by the for loop's body.

for (int i = 1; i <= 100; i++)
{
  int i = 2; //ERROR
  cout << i << endl;
}

You can have two variables with the same name in different scopes

int main()
{
  for (int i = 0; i < 5; i++) { //i ok here
    int w = 2;                  // w ok here
  }
  for (int i = 0; i < 2; i++) { //i ok here
    int w = 3;                  // w ok here
  }
}

You can have two variables with the same name in nested scopes (variable shadowing)

for (int i = 1; i <= 100; i++) {
  while (...) {
    int i = 5; //ERROR
  }
}

You can have two variables with the same name in different scopes

void foo()
{
  int w = 3;
  for (int i = 0; i < 5; i++) { //i ok here
    int w = 4;                  // w ok here
  }
  for (int i = 0; i < 2; i++) { //i ok here
    int w = 5;                  // w ok here
  }
}
void bar()
{
  int w = 2;
  foo();
  cout << w << endl;
}
Show how execution proceeds and how foo scope gets activated when statements in foo are getting executed, and how bar's scope is restored when foo returns from execution.

Revisiting sentinel loops

#include <iostream>
#include "simpio.h"
using namespace std;
int main() {
  int sum = 0; //sum must be declared outside
         //of the loop! Otherwise it
         //will be redeclared many
         //times
  int num = getInteger("number? "); //num must
  			    //be declared
  			    //outside of
  			    //the loop!
  			    //Otherwise,
  			    //the loop
  			    //condition
  			    //makes no sense.
  while (num != -1)
  {
    sum += num;
    num = getInteger("number? ");
  }
  cout << "Sum is " << sum << endl;
  return 0;
}

Another example: here, num goes out of scope at the end of each loop iteration. At that point, we have already used its value and can discard it.

int main() {
  int sum = 0;
  while (true)
  {
    int num = getInteger("Enter a number: ");
    if (num == -1) {
      break; //immediately exits loop
    }
    sum += num;
  }
  cout << "Sum is " << sum << endl;
  return 0;
}
Parameters

Continued in the next lecture!