Visibility scope. Functions.


Scope

According to Wikipedia:

Scope defines certain area of the program, in which limits identifier (name) of some variable continuous binding with it variable and returning its value. In case if same identifier is outside the scope of binding it can be associated with another variable, or not being used (not associated with any of them).

In essence, it means that variable, which has been declared in concrete block of code is observable inside of this bloke and in all nested. However, variable, which has been declared in nested blocks of code, is not visible in external ones.

To clarify situation, let us grapple with the fact what block of code means. At bottom, block is a part of a code, which is grouped as one. By implication it is quite similar to the text paragraph. In order to outline blocks in program special constructions are being used, which in C language are called operator brackets and specified by means of curly braces {}. Code, which is situated inside of such brackets, is a block of code.

#include <stdio.h>
// global scope
int main() {
// beginning of the main function block ()
int x, y; // variables, declared in block main()
int max;
    scanf("%d %d", &x, &y);
max = x; if ( y > max ) { // nested block of code
max = y;
    } //end of nested block
    return 0;} // end of the main function block ()

Each block of code defines scope for declared in it variables. To ease understanding let us highlight with color binding scope of each block from given program above.


Now we turn directly to variables. It can be a long story, but, since clear comprehension appears during work let us come up with considering of a couple of examples:

#include <stdio.h>
int globalVariable = 10; // global variable
int main() {
// internal block of code (function main)
int value = 42; // variable declared in internal block
{ //nested block of code
printf("internal block: value = %d\n", value);
printf("internal block: globalVariable = %d\n", globalVariable);
    }
    printf("external block: value = %d\n", value);
printf("external block: globalVariable = %d\n", globalVariable);
    return 0;
}

And result is:

internal block: value = 42
internal block: globalVariable = 10
external block: value = 42
external block: globalVariable = 10

Global variable globalVariable is declared in global scope, so that is accessible in all programs blocks. Variable value is declared in block of main() function (in external block), consequently, it is accessible in block, where it is declared in its all nested blocks. Variable value — is a local variable of main() function, thus inaccessible in a global scope. In case if changing variable value in nested blocks, such changes will be visible in external blocks, including block in which this variable is declared. Let us demonstrate it:

#include <stdio.h>
int main() {
// external block of code (body of function main)
int value = 42; // variable declared in external block
{
//nested block of code
        printf("internal block: value = %d\n", value);
printf("internal block: globalVariable = %d\n", globalVariable);
        value += 10;
globalVariable += 7;
}
    printf("external block: value = %d\n", value);
printf("external block: globalVariable = %d\n", globalVariable);
    return 0;
}

Result:

internal block: value = 42
internal block: globalVariable = 10
external block: value = 42
external block: globalVariable = 17

We can declare variables in any block of code, but it is necessary to remember, that variable that has been declared locally, is observable only in that block of code, where it was initially assigned.

#include <stdio.h>
int globalVariable = 10; // global variable
int main() {
// external block of code (body of function main)
int value = 42; // variable declared in external block
{
//nested block of code
int localVariable = 57; // variable declared in nested block
printf("internal block: value = %d\n", value);
printf("internal block: globalVariable = %d\n", globalVariable);
printf("internal block: localVariable = %d\n", localVariable);
value += 10;
globalVariable += 7;
}
    printf("external block: value = %d\n", value);
printf("external block: globalVariable = %d\n", globalVariable);
// localVariable is inaccessible in external block printf("external block: localVariable = %d\n", localVariable);
return 0;
}

In case if we try to compile this code the massage about occurrence of a particular error will be received:

scope.c: error: use of undeclared identifier 'localVariable';

It should be taken in consideration that variables names in external and nested blocks can be the same, wherein the program will work correctly.

#include <stdio.h>
int main() {
    int value = 42;
{
int value = 57;
printf("internal block: value = %d\n", value);
}
    printf("external block: value = %d\n", value);
    return 0;
}

Such program result is represented next:

internal block: value = 57
external block: value = 42

Captain obvious to the rescue!

Variable value, which has been declared in a function main() block and variable value, which, in its turn, has been declared in the nested block are different variables! For us they have the same name, however, its variables meanings are kept in different memory areas!

However, such approach to writing code makes it more difficult to understand it. So that it is not recommended to declare variables in such way. Even despite the fact if that they are declared in the different nested blocks.

For example, we cannot create files with the same name in one folder. But having created nested folder we can easily save file with the same name as previous file had. But once we use search, we will get several files with the same name, which will complicate our work. So, think over properly how to declare variable to exclude duplicating names.


Functions


You have been already met with functions. You have been using them quite widely and intensely, for example, in order to output information you used function called printf(), for the record — scanf() and all your programs logic you were describing in the body of function main(). So that it is possible to presume that you have been used functions rather successfully. The last thing is to find out what the function is?

Function is a named part of a programming code (subprogram, procedure), which can be addressed from another part of a program. There is a solid connection between the name of a function and the address of the first instruction (operator), which is included in it and which is being used to receive control when addressing the function. After function has been executed the control is received back to the return address — some point in the program, where current function was called.

Put it simply, we can describe in the form of code some sequence of actions, take it to the block of code, name it in accordance with provided actions and allocate separately. Wherein, we will be still able to address to this block of code in any place of our program and without any limitations regarding its number.

But it is necessary to understand that function should be declared and defined in specific way. For declaration it is required to point out type of returned by function value and count passed arguments to function with indication of their types. Function defines its own, local scope, which includes arguments passed to the function and also locally declared variables. Moreover, function can consist in it addressing to other functions.

Let us conduct an experiment:

#include <stdio.h>
int main() {
int sum = 0;
    { // block for calculating a sum of declared variables
int x, y;
        scanf("%d %d", &x, &y);
        sum = x + y;
}
    printf("%d\n", sum);
    return 0;
}

By the time of running program, we will achieve quite correct result. Furthermore, in case, when we need to calculate sum again, we just can copy appropriate part of code, changing only variable name for saving result.

It can seem to be convenient, but what to do, if it is necessary to calculate sum of several couples of numbers? Copying such block a few times in a row? I do not think it is a good idea. Plus, in case if instead of sum it will be required to calculate division, so that to the program code should be changed considerably. That is why let us try to bring out given code. But before, let us define several statements:

  • Given block of code should be named
  • Sum of numbers will be returned from block, instead of manipulation with global variables.
#include <stdio.h>
int sum() {
int x, y; scanf("%d %d", &x, &y);
return x + y;
}
int main() {
int result = sum();
    printf("%d\n", result);
    return 0;
}

Now, at any moment we can sum up two numbers, using function called sum(). But it is little illogical in realization of this function, which, basically, just sums up something, to let it ready any values. It is incorrect, since the function should perform one solid and logically finished operation. Let us rewrite our code:

#include <stdio.h>
int sum(int x, int y) {
return x + y;
}
int main() {
int a, b;
    scanf("%d %d", &a, &b);
    printf("%d\n", sum(a, b));
    return 0;
}

What has changed? Now, instead of letting function reading two numbers inside of a it, we just pass to it numbers subjected to calculation in the form of arguments. Since the function returns integer value and the result of conducted calculation is required only to be displayed it is possible to pass value provided by function sum() as an argument straight to the function printf(), yet not storing result of addition.