.. _name-scope: ########## Name Scope ########## .. note:: This has nothing to do with mouthwash! Now that we are building programs with more than one module, and can start to talk about the right way to organize a bigger program, we need to introduce the concept of `name scope`. Simply put, this is a concept that defines where in a program we can `refer` to a name. That name can be the name of a variable, constant, or module. Long ago, I used an analogy to explain `name scope`. The analogy involved surrounding parts of your program with one way mirrors. You know how these work, from one side you cannot see through them, but from the other side you can see through them. We will surround the entire program file in such a mirror, and further, we will surround each module we create in that file in another mirror. The mirrors will be set up so that from outside of the file, you cannot look into the file, and from outside of any module (but inside the file), you cannot see into the function. If you are standing inside the function, you can see out of the function to the world outside of the function, maybe even outside of the file. ********* One catch ********* There is one catch to this rule. You are only allowed to look upward in your program, never downward. As you read your program code, you will define names of variables and constants which hold your data. We have already heard the rule that you cannot use a name unless the compiler knows everything it need to know about that name so it can make sure you use it correctly. You may also define modules in your code, either fully, or in two parts: the prototype followed by the full module definition. The scope rules determine where in our program we can refer to the module name, meaning where we can `call` the module into action! You can pretend that each module has the name of the module painted on the outside of the enclosing mirror. Here is how scope works. ***** Scope ***** At any point in your program code where you want to use a name, we need to look upward in the program to see if that name has been defined above us. If so, we are allowed to use the name If not, the compiler will generate an error. If we have modules in the program between where we want to use the name, we cannot see into those modules, but we can see around them to code above the modules surrounding mirror. Again, if the name can be found using that set of rules, we can use the name. ****************** Module local names ****************** Names created in a module are called `local`, meaning they are only visible to code inside that module. This protects them from accidentally being used by any other code in the program. We want this to allow us to move the module into another program without breaking anything in that new program. What is interesting about modules, though, is that they can use names of variables and constants outside of their surrounding mirrors. We call these names `global` since they must be defined outside of any module to be seen. Normally, we place such names at the top of the program which makes then visible to any code below the point where they are defined. The `global` term indicates that you can use those names anywhere in your program. Modules can see other modules as well, so a module can `call` another module if needed. This is how we build large programs, dividing them up into a bunch of modules that activate each other as needed to do the required work. Module parameter names ====================== The names of parameters we create for our modules are actually local to the module, although it is common to see those names in a prototype, or module definition. The names themselves can only be used `inside` the module, and act like specially initialized variables that code in the module can use. When some piece of code `calls` the module, those parameter names are initialized with the right values at that moment. The caller's code determines what value will be placed in those variables, and the module code will not be aware how that all happened! .. note;: In a later programming course, you will learn that it is possible to get information out from inside the module using these parameter names, but we will not worry about that for now. Here is an example program, just to reinforce this scope concept: .. code-block:: c #include // makes a bunch of names "global" (like cout, and cin) using namespace std; // simplifies some names const double PI = acos(-1.0); // define a "global" constant named PI void myfunction(double angle) { double radians; // uninitialized local variable radians = angle * PI / 180.0; // using global PI, OK since it is above here cout << "Radians:" << radians << endl; // using several globals and a local } int main(int argc, char ** argv) { cout << "Hello, there!" << endl; // global cout used here myfunction(45.0); // calling module defined above. angle will be 45.0 } This code shows several examples of using names defined above. In module `main`, we cannot use the name `radians` since it is invisible to us. It is hiden inside the morrit that surrounds `myfunction`. We can call `myfunction`, since we can see its name. The analogy is important in organizing code. It i common in several languages, but not all. You will need to learn the specific rules for `scope` in what ever language you end up using!