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";
}
|
|