Submitted by Anonymous (not verified) on Sun, 03/10/2013 - 01:01

Hiding Data

To solve a complex problem in practice, the programmer normally breaks the problem into smaller pieces and deals with each piece of the problem by writing one or two functions (or routines). Then, all the functions are put together to form a complete program that can be used to solve the complex problem.

In the complete program, there might be variables that have to be shared by all the functions. On the other hand, the use of some other variables may be limited to only certain functions. That is, the visibility of those variables is limited, and values assigned to those variables are hidden from many functions.

Limiting the scope of variables is very useful when several programmers are working on different pieces of the same program. If they limit the scope of their variables to their pieces of code, they do not have to worry about conflicting with variables of the same name used by others in other parts of the program.

In C, you can declare a variable and indicate its visibility level by designating its scope. Thus, variables with local scope can only be accessed within the block in which they are declared.

The following sections teach you how to declare variables with different scopes.
Block Scope

In this section, a block refers to any sets of statements enclosed in braces ({ and }). A variable declared within a block has block scope. Thus, the variable is active and accessible from its declaration point to the end of the block. Sometimes, block scope is also called local scope.

For example, the variable i declared within the block of the following main function has block scope:

 

int main()
{
   int i;   /* block scope */
   .
   .
   .
   return 0;
}

 

Usually, a variable with block scope is called a local variable.

Nested Block Scope

You can also declare variables within a nested block. If a variable declared in the outer block shares the same name with one of the variables in the inner block, the variable within the outer block is hidden by the one within the inner block for the scope of the inner block.

Listing 14.1 gives an example of variable scopes in nested blocks.

TYPE
Listing 14.1. Printing out variables with different scope levels.

1:  /* 14L01.c: Scopes in nested block */
2:  #include <stdio.h>
3:
4:  main()
5:  {
6:     int i = 32;   /* block scope 1*/
7:
8:     printf("Within the outer block: i=%d\n", i);
9:
10:    {    /* the beginning of the inner block */
11:      int i, j;    /* block scope 2, int i hides the outer int i*/
12:
13:      printf("Within the inner block:\n");
14:      for (i=0, j=10; i<=10; i++, j--)
15:          printf("i=%2d, j=%2d\n", i, j);
16:    }   /* the end of the inner block */
17:    printf("Within the outer block:  i=%d\n", i);
18:    return 0;
19: }


The following output is displayed on the screen after the executable (14L01.exe) of the program in Listing 14.1 is created and run from a DOS prompt:

OUTPUT

C:\app>14L01
Within the outer block: i=32
Within the inner block:
i= 0, j=10
i= 1, j= 9
i= 2, j= 8
i= 3, j= 7
i= 4, j= 6
i= 5, j= 5
i= 6, j= 4
i= 7, j= 3
i= 8, j= 2
i= 9, j= 1
i=10, j= 0
Within the outer block: i=32
C:\app>

ANALYSIS

The purpose of the program in Listing 14.1 is to show you the different scopes of variables in nested blocks. As you can see, there are two nested blocks in Listing 14.1. The integer variable i declared in line 6 is visible within the outer block enclosed by the braces ({ and }) in lines 5 and 19. Another two integer variables, i and j, declared in line 11, are visible only within the inner block from line 10 to line 16.

Although the integer variable i within the outer block has the same name as one of the integer variables within the inner block, the two integer variables can not be accessed at the same time due to their different scopes.

To prove this, line 8 prints out the value, 32, contained by i within the outer block for the first time. Then, the for loop in lines 14 and 15 displays 10 pairs of values assigned to i and j within the inner block. At this point, there is no sign showing that the integer variable i within the outer block has any effects on the one within the inner block. When the inner block is exited, the variables within the inner block are no longer accessible.

Finally, the statement in line 17 prints out the value of i within the outer block again to find out whether the value has been changed due to the integer variable i within the inner block. The result shows that these two integer variables hide from each other, and no conflict occurs.
Function Scope

Function scope indicates that a variable is active and visible from the beginning to the end of a function.

In C, only the goto label has function scope. For example, the goto label, start, shown in the following code portion has function scope:

int main()
{
   int i;   /* block scope */
   .
   .
   .
   start:   /* A goto label has function scope */
   .
   .
   .
   goto  start;  /* the goto statement */
   .
   .
   .
   return 0;
}


Here the label start is visible from the beginning to the end of the main() function. Therefore, there should not be more than one label having the same name within the main() function.
Program Scope

A variable is said to have program scope when it is declared outside a function. For instance, look at the following code:

int x = 0;        /* program scope */
float y = 0.0;    /* program scope */
int main()
{
   int i;   /* block scope */
   .
   .
   .
   return 0;
}


Here the int variable x and the float variable y have program scope.

Variables with program scope are also called global variables, which are visible among different files. These files are the entire source files that make up an executable program. Note that a global variable is declared with an initializer outside a function.

The program in Listing 14.2 demonstrates the relationship between variables with program scope and variables with block scope.
TYPE
Listing 14.2. The relationship between program scope and block scope.

1:  /* 14L02.c: Program scope vs block scope */
2:  #include <stdio.h>
3:
4:  int x = 1234;         /* program scope */
5:  double y = 1.234567;  /* program scope */
6:
7:  void function_1()
8:  {
9:     printf("From function_1:\n  x=%d, y=%f\n", x, y);
10: }
11:
12: main()
13: {
14:    int x = 4321;   /* block scope 1*/
15:
16:    function_1();
17:    printf("Within the main block:\n  x=%d, y=%f\n", x, y);
18:    /* a nested block */
19:    {
20:       double y = 7.654321;  /* block scope 2 */
21:       function_1();
22:       printf("Within the nested block:\n  x=%d, y=%f\n", x, y);
23:    }
24:    return 0;
25: }



I have the following output shown on the screen after the executable 14L02.exe is created and run from a DOS prompt:

OUTPUT

C:\app>14L02
From function_1:
  x=1234, y=1.234567
Within the main block:
  x=4321, y=1.234567
From function_1:
  x=1234, y=1.234567
Within the nested block:
  x=4321, y=7.654321
C:\app>

ANALYSIS

As you can see in Listing 14.2, there are two global variables, x and y, with program scope; they are declared in lines 4 and 5.

In lines 7_10, a function, called function_1(), is declared. (More details about function declarations and prototypes are taught in the next hour.) The function_1() function contains only one statement; it prints out the values held by both x and y. Because there is no variable declaration made for x or y within the function block, the values of the global variables x and y are used for the statement inside the function. To prove this, the function_1() function is called twice in lines 16 and 21, respectively, from two nested blocks. The output shows that the values of the two global variables x and y are passed to printf() enclosed in the function_1() function body.

Then, line 14 declares another integer variable, x, with block scope, which can replace the global variable x within the block of the main() function. The result made by the statement in line 17 shows that the value of x is the value of the local variable x with block scope, while the value of y is still that of the global variable y.

There is a nested block in lines 19 and 23, within which another double variable y, with block scope, is declared and initialized. Like the variable x within the main() block, this variable, y, within the nested block replaces the global variable y. The statement in line 22 puts the values of the local variables x and y on the screen.

TIP

    Since a global variable is visible among different source files of a program, using global variables increases your program's complexity, which in turn makes your program hard to maintain or debug. Generally, it's not recommended that you declare and use global variables, unless it's very necessary. For instance, you can declare a global variable whose value is used but never changed by several subroutines in your program. (In Hour 23, "The C Preprocessor," you'll learn to use the #define directive to define constants that are used in many places in a program.)

 

Before I introduce file scope, let's talk about the storage class specifiers.

Related Items

মডুলার C প্রোগ্রামিং (Modular C Programming)

কেবল মাত্র একটি ফাংশন দিয়ে কোনো বড়ো জটিল সমস্যা সমাধানের চেষ্টা করা ভাল প্রোগ্রামিংয়ের পদ্ধতি নয়। সঠিক পদ্ধতি হ'ল সমস্যাটিকে কয়েকটি ছোট ছোট এবং সরল টুকরো করে ফেলা যাতে তা আরও বিশদে বোঝা যায় । তারপরে এই ছোট এবং সরল সমস্যাগুলি সমাধান করার জন্য ছোট ছোট ফাংশন ব্লক তৈরি করা এবং পরে সেগুলি নিয়মানুযায়ী সংযোজিত করা ।

Programming Style

Programming Style

In this section, I'd like to briefly highlight some points that will help you write clean programs that can easily be read, understood, and maintained.

Exercises : Answer the following Question

To help solidify your understanding of this hour's lesson, you are encouraged to answer the quiz questions and finish the exercises provided in the Workshop before you move to the next lesson.

Question and Answer

    Q Is the C preprocessor part of the C compiler?

    A No. The C preprocessor is not part of the C compiler. With its own line-oriented grammar and syntax, the C preprocessor runs before the compiler in order to handle named constants, macros, and inclusion of files.

Compiling Your Code Under Conditions

Compiling Your Code Under Conditions

You can select portions of your C program that you want to compile by using a set of preprocessor directives. This is useful, especially when you're testing a piece of new code or debugging a portion of code.