Recall that each variable in modern programming languages has:
If information (variables) are used or maintained in a some part/section of the program, it is generally easier to make sure that the program is correct.
When the program cannot access (is not allowed to use) some variables, the correctness of the program can be maintained with more ease (because the programmer can work more focused).
Lifetime has to do with when a variable is created and destroyed
Scoping has to do with when a variable is accessible and used.
Therefore, the scope of every variable is a sub-range of its lifetime
(Not every veriable that exists is also accessible).
In other words, which parts of your program can see or use the variable.
The collection of all variables that are visible/accessing at a given point is called the program scope
And you can define an "inner inner scope" inside the inner scope, and so on (scoping levels can go on indefinitely)
When you define an inner scope, this inner scope will inherit all variables that are accessible in the outer (enclosing) scope |
Each time you define an new scope,
you can define NEW VARIABLES that will
ONLY EXIST in that scope
In other words: variables that are defined in a given scope will be destroyed when the scope ends |
The two scoping rules creates the following problem:
Which variable does the name X refer to ?
Programming languages use the following name resolution rule:
A name X always refer
to an object is defined in the "closest" scope of its occurence.
In other words: if the variable X is defined in the current scope, then X will refer to that object. If X is not defined in the current scope, the program will search outward and locate the first scope in which X is defined. The name X will refer to that object. |
..... { (Outer scope) .... .... { (Begin of inner scope) (Inner scope) .... .... } (End of inner scope) .... .... } |
int main(int argc, char *argv[]) { int x; x = 1; // int x is accessible after its definition cout << "x = " << x << "\n"; // prints 1 { x = 3.14; // int x is ALSO inside new scope cout << "x = " << x << "\n"; // prints 3 } cout << "x = " << x << "\n"; // prints 3 } |
int main(int argc, char *argv[]) { int x; x = 1; // int x is accessible after its definition cout << "x = " << x << "\n"; // prints 1 { float x; <-------------- change x = 3.14; // int x is ALSO inside new scope cout << "x = " << x << "\n"; // prints ??? } cout << "x = " << x << "\n"; // prints ??? } |
int main(int argc, char *argv[]) { { float x; <-------------- x = 3.14; // int x is ALSO inside new scope cout << "x = " << x << "\n"; // prints 3.14 } cout << "x = " << x << "\n"; // prints ??? } |
int sum; // Global float f; // variables int main(argc, char *argv[]) { .... } |
int global1; int main(int argc, char *argv[]) { int local1; .. only local1 accessible (and global1)... { float local2; local1 and local2 (and global1) are accessible } .. only local1 accessible... } float f(float x) { int local3; .. only local3 accessible (and global1)... { float local4; local3 and local4 (and global1) are accessible } .. only local3 accessible... } |
Java will forbid the user to define another variable with the same name in an inner scope
Java adopts a "careful" approach, and tries to prevent the programmer from "confusing oneself"... put it bluntly: Java assumes that you don't know what you're doing...
Java is made for incompetent programmers who do not know what they are doing.... But if you know what you're doing, you will like C++ better.