Physics 5 - Class Notes  3/17/2011

 

We left some issues about namepaces unresolved, so here is an attempt to clear those issues up.

Let’s start with Ex. 3.5 from page 45 of FCC++, has been modified slightly to use the standard ISO C++:

//  FCC++ Example 3.5, page 45, with modifications by GH

 

#include <iostream>

 

using namespace std;

 

namespace X

{ int x = 22;

}

 

namespace Y

{ int y = 33;

  namespace Z

  { int z = 44;

  }

}

 

int main()

{ int x = 55;

  cout << X::x << " " << Y::Z::z << " " << x << endl;

  using namespace Y;                // after this, Y:: can be omitted

  cout << y << " " << Z::z << endl;

}

 


The console output of this program is shown below:

22 44 55

33 44

Press any key to continue . . .

 

As http://www.cplusplus.com/doc/tutorial/namespaces/ says, “Namespaces allow [you] to group entities like classes, objects and functions under a name. This way the global scope can be divided in sub-scopes, each one with its own name.” 

Or, as Deitel puts it, “A program includes many identifiers defined in different scopes.  Sometimes a variable of one scope will overlap (i.e. collide) with a variable of the same name in a different scope, potentially creating confusion.  Such overlapping can occur at many levels.  Identifier overlapping occurs frequently in third-party libraries that happen to use the same names for global identifiers (such as functions.)  When this occurs, compiler errors usually are generated.  Ideally, in large programs, every entity should be declared in a class, function, block or namespace.  This helps clarify the entity’s role.”

Functions can also be part of a namespace.  In the example below, the function “increase()” has been added to each namespace with a different definition in each. 

//  FCC++ Example 3.5, page 45, with more modifications by GH

 

#include <iostream>

 

using namespace std;

 

namespace X

{ int x = 22;

      int increase(int x) {

            return x + 10;

      }

}

 

namespace Y

{ int y = 33;

    int increase(int x) {

            return x + 50;

      }

  namespace Z

  { int z = 44;

      int increase(int x) {

            return x + 100;

      }

  }

}

 

int main()

{ int x = 55;

  cout << X::x << " " << Y::Z::z << " " << x << endl;

  cout << "\nIn namespace X, increase(" << X::x << ") = "

         << X::increase(X::x) << endl;

  cout << "\nIn namespace Y, increase(" << Y::y << ") = "

         << Y::increase(Y::y) << endl;

  using namespace Y;       // after this, Y:: can be omitted

  cout << "\nIn namespace Z, increase(" << Z::z << ") = "

         << Z::increase(Z::z) << endl;

}

 

 

The output to the console of this program is below:

22 44 55

 

In namespace X, increase(22) = 32

 

In namespace Y, increase(33) = 83

 

In namespace Z, increase(44) = 144

Press any key to continue . . .

 

 

 

 

The confusion we had in class was in trying to follow Problem 3.5, as listed below

// FCC++ using namespace problem 3.6

#include <iostream>

using namespace std;

 

int x = 22;

 

int main () {

   int y = 33;

   cout << x << " " << y << endl;

   namespace local1 {

      int x = 44;

        int z = 55;

        cout << x << " " << y << " " << z << endl;

   }

   x = 66;

   namespace local2 {

      int y = 77;

        int z = 88;

        cout << x << " " << y << " " << z << endl;

   }

   cout << x << " " << y << " " << endl;

   return 0;

}


The error  “error C2870: 'local1' : a namespace definition must appear either at file scope or immediately within another namespace definition” is  produced.  It seems that the code in the text is in error and that you cannot define a namespace within the main() function. 

// FCC++ using namespace problem 3.6, modified by GH to actually work

#include <iostream>

using namespace std;

 

int x = 22;

namespace local1 {

  int x = 44;   int z = 55;    

}

 

namespace local2 {

  int x = 77;   int y = 88;

}

 

int main () {

   cout << "\nOriginally, x = " << x << endl << endl;

   int x = 144;

   int y = 133;

   cout << "x = " << x << " " << "local1::x = " << local1::x << " "

          << "y = " << y << " " << "local1::z = " << local1::z << endl;

   using namespace local2; 

   cout << "\nAfter using namespace local2, \n";

   cout << "x = " << x << " " << "y = " << y << endl;

   cout << "\nAfter setting x to 66 \n";

   x = 66;

   cout << "x = " << x << " " << "y = " << y << endl;

}

 

The above program produces this output.  Can you explain the scope of each variable declaration?

x = 144 local1::x = 44 y = 133 local1::z = 55

 

After using namespace local2,

x = 144 y = 133

 

After setting x to 66

x = 66 y = 133

Press any key to continue . . .

 

We also looked at Programming Problem 3.10:  A year is a leap year if it is divisible by 4 but not by 100 unless it is also divisible by 400.  So the years  1996 and 2000 are leap years, but the years  1999 and 1900 are not.  Write a program that inputs a y6ear and prints whether it is a leap year. Here’s the solution we developed in class:

//  Problem 3.10, page 61, as solved in class

#include <iostream>

using namespace std;

 

int main()

{ int n;

  cout << "Enter year: ";

  cin >> n;

  /*if (n % 400 == 0) cout << n << " is a leap year.\n";

  else if (n % 100 == 0) cout << n << " is a not leap year.\n";

  else if (n % 4 == 0) cout << n << " is a leap year.\n";

  else cout << n << " is a not leap year.\n";*/

  if(n%4 == 0) // further checking is required

        if(n%100 == 0) // further checking is required

              if(n%400 == 0) //2000 is a leap year

                    cout << n << " is a leap year.";

              else cout << n << " is not a leap year."; //1900 is not

        else cout << " is a leap year."; // 1996 is a leap year

  else cout << n << " is not a leap year."; // 1999 is not

  return 0;

}


Here is the book’s solution:

//  Problem 3.10, page 61

#include <iostream>

 

using namespace std;

 

int main()

{ int n;

  cout << "Enter year: ";

  cin >> n;

  if (n % 400 == 0) cout << n << " is a leap year.\n";

  else if (n % 100 == 0) cout << n << " is a not leap year.\n";

  else if (n % 4 == 0) cout << n << " is a leap year.\n";

  else cout << n << " is a not leap year.\n";

}