Lab Experiment 4

Variable and Scope of Variable

Course: C Programming | Semester: BTech First | Instructor: Dr. Mohsin Dar

Learning Objectives

  • Understand the concept of variable scope in C programming
  • Differentiate between global and local variables
  • Explore block scope and its implications
  • Learn about static local variables and their persistence
  • Apply scope rules in practical programming scenarios

What is Variable Scope?

Variable Scope refers to the region of the program where a variable can be accessed or used. It determines the visibility and lifetime of variables in different parts of your program.

Part 1: Global Variables

Global variables are declared outside all functions and can be accessed from any function within the program.

Example 1.1: Basic Global Variable Usage

// Global variable declaration
int globalVar = 100;

void displayGlobal() {
    printf("Global variable in displayGlobal(): %d\n", globalVar);
}

void modifyGlobal() {
    globalVar = 200;
    printf("Modified global variable: %d\n", globalVar);
}

int main() {
    printf("Initial global variable: %d\n", globalVar);
    
    displayGlobal();
    modifyGlobal();
    displayGlobal();
    
    return 0;
}

Expected Output:

Initial global variable: 100
Global variable in displayGlobal(): 100
Modified global variable: 200
Global variable in displayGlobal(): 200
Key Points:
  • Global variables are accessible from all functions
  • Changes made to global variables persist throughout the program
  • Global variables are stored in the data segment of memory

Part 2: Local Variables vs Global Variables

Local variables are declared inside functions and have limited scope. Let's compare their behavior with global variables.

Example 2.1: Local Variable Scope

// Global variable
int globalNumber = 50;

void testLocalScope() {
    int localNumber = 25; // Local variable
    
    printf("Inside testLocalScope():\n");
    printf("  Local variable: %d\n", localNumber);
    printf("  Global variable: %d\n", globalNumber);
    
    // Modifying both variables
    localNumber = 75;
    globalNumber = 150;
    
    printf("After modification:\n");
    printf("  Local variable: %d\n", localNumber);
    printf("  Global variable: %d\n", globalNumber);
}

int main() {
    printf("In main() before function call:\n");
    printf("  Global variable: %d\n", globalNumber);
    
    // This would cause an error - localNumber is not accessible here
    // printf("Local variable: %d\n", localNumber); // ERROR!
    
    testLocalScope();
    
    printf("In main() after function call:\n");
    printf("  Global variable: %d\n", globalNumber);
    
    return 0;
}

Expected Output:

In main() before function call:
  Global variable: 50
Inside testLocalScope():
  Local variable: 25
  Global variable: 50
After modification:
  Local variable: 75
  Global variable: 150
In main() after function call:
  Global variable: 150
Important: Trying to access a local variable outside its function will result in a compilation error. Local variables are destroyed when the function exits.

Part 3: Block Scope Variables

Variables can also be declared within code blocks (enclosed by curly braces) and have block scope.

Example 3.1: Block Scope Demonstration

int main() {
    int outerVar = 10;
    
    printf("Outer variable: %d\n", outerVar);
    
    // Creating a new block
    {
        int innerVar = 20; // Block scope variable
        
        printf("Inside block:\n");
        printf("  Inner variable: %d\n", innerVar);
        printf("  Outer variable: %d\n", outerVar);
        
        // Modifying outer variable from inner block
        outerVar = 30;
        printf("  Modified outer variable: %d\n", outerVar);
    }
    
    printf("Outside block:\n");
    printf("  Outer variable: %d\n", outerVar);
    
    // This would cause an error - innerVar is not accessible here
    // printf("Inner variable: %d\n", innerVar); // ERROR!
    
    return 0;
}

Expected Output:

Outer variable: 10
Inside block:
  Inner variable: 20
  Outer variable: 10
  Modified outer variable: 30
Outside block:
  Outer variable: 30

Example 3.2: Nested Block Scope

int main() {
    int level1 = 100;
    
    printf("Level 1 variable: %d\n", level1);
    
    {
        int level2 = 200;
        printf("Level 2 - level1: %d, level2: %d\n", level1, level2);
        
        {
            int level3 = 300;
            printf("Level 3 - level1: %d, level2: %d, level3: %d\n", 
                   level1, level2, level3);
            
            // All variables are accessible here
            level1 = 111;
            level2 = 222;
            level3 = 333;
        }
        
        printf("Back to Level 2 - level1: %d, level2: %d\n", level1, level2);
        // level3 is not accessible here
    }
    
    printf("Back to Level 1 - level1: %d\n", level1);
    // level2 and level3 are not accessible here
    
    return 0;
}

Expected Output:

Level 1 variable: 100
Level 2 - level1: 100, level2: 200
Level 3 - level1: 100, level2: 200, level3: 300
Back to Level 2 - level1: 111, level2: 222
Back to Level 1 - level1: 111

Part 4: Static Local Variables

Static local variables retain their value between function calls, unlike regular local variables.

Example 4.1: Static vs Regular Local Variables

void demonstrateStatic() {
    int regularVar = 0;        // Regular local variable
    static int staticVar = 0; // Static local variable
    
    printf("Regular variable: %d, Static variable: %d\n", 
           regularVar, staticVar);
    
    regularVar++;
    staticVar++;
    
    printf("After increment - Regular: %d, Static: %d\n", 
           regularVar, staticVar);
}

int main() {
    printf("First call to demonstrateStatic():\n");
    demonstrateStatic();
    
    printf("\nSecond call to demonstrateStatic():\n");
    demonstrateStatic();
    
    printf("\nThird call to demonstrateStatic():\n");
    demonstrateStatic();
    
    return 0;
}

Expected Output:

First call to demonstrateStatic():
Regular variable: 0, Static variable: 0
After increment - Regular: 1, Static: 1

Second call to demonstrateStatic():
Regular variable: 0, Static variable: 1
After increment - Regular: 1, Static: 2

Third call to demonstrateStatic():
Regular variable: 0, Static variable: 2
After increment - Regular: 1, Static: 3

Example 4.2: Practical Use of Static Variables - Function Call Counter

int getCallCount() {
    static int callCount = 0;
    callCount++;
    return callCount;
}

void processData(int data) {
    int callNumber = getCallCount();
    printf("Processing data %d (Call #%d)\n", data, callNumber);
}

int main() {
    processData(10);
    processData(20);
    processData(30);
    
    printf("Total function calls: %d\n", getCallCount());
    
    return 0;
}

Expected Output:

Processing data 10 (Call #1)
Processing data 20 (Call #2)
Processing data 30 (Call #3)
Total function calls: 4

Variable Scope Summary

Variable Type Scope Lifetime Memory Location Accessibility
Global Entire program Program execution Data segment All functions
Local Function only Function execution Stack Current function
Block Block only Block execution Stack Current block
Static Local Function only Program execution Data segment Current function

Complete Lab Exercise

Try this comprehensive example that demonstrates all concepts:

#include <stdio.h>

// Global variable
int globalCounter = 0;

void demonstrateAllScopes(int parameter) {
    // Local variable
    int localVar = 10;
    
    // Static local variable
    static int staticCounter = 0;
    
    printf("\n=== Function Call ===\n");
    printf("Parameter: %d\n", parameter);
    printf("Local variable: %d\n", localVar);
    printf("Static counter: %d\n", staticCounter);
    printf("Global counter: %d\n", globalCounter);
    
    // Block scope demonstration
    {
        int blockVar = 50;
        printf("Block variable: %d\n", blockVar);
        
        // Modifying variables from different scopes
        localVar += 5;
        staticCounter++;
        globalCounter++;
        blockVar += 10;
        
        printf("After modification in block:\n");
        printf("  Local: %d, Static: %d, Global: %d, Block: %d\n",
               localVar, staticCounter, globalCounter, blockVar);
    }
    
    printf("After block (blockVar not accessible):\n");
    printf("  Local: %d, Static: %d, Global: %d\n",
           localVar, staticCounter, globalCounter);
}

int main() {
    printf("Variable Scope Demonstration\n");
    printf("============================\n");
    
    // Multiple function calls to observe behavior
    demonstrateAllScopes(100);
    demonstrateAllScopes(200);
    demonstrateAllScopes(300);
    
    printf("\n=== Final Global Counter Value ===\n");
    printf("Global counter: %d\n", globalCounter);
    
    return 0;
}

Expected Output:

Variable Scope Demonstration
============================

=== Function Call ===
Parameter: 100
Local variable: 10
Static counter: 0
Global counter: 0
Block variable: 50
After modification in block:
  Local: 15, Static: 1, Global: 1, Block: 60
After block (blockVar not accessible):
  Local: 15, Static: 1, Global: 1

=== Function Call ===
Parameter: 200
Local variable: 10
Static counter: 1
Global counter: 1
Block variable: 50
After modification in block:
  Local: 15, Static: 2, Global: 2, Block: 60
After block (blockVar not accessible):
  Local: 15, Static: 2, Global: 2

=== Function Call ===
Parameter: 300
Local variable: 10
Static counter: 2
Global counter: 2
Block variable: 50
After modification in block:
  Local: 15, Static: 3, Global: 3, Block: 60
After block (blockVar not accessible):
  Local: 15, Static: 3, Global: 3

=== Final Global Counter Value ===
Global counter: 3

Lab Assignment Questions

Exercise Questions:

  1. Analysis Question: Explain why the static counter increases with each function call while the local variable resets to 10.
  2. Prediction Question: What would happen if we declared a local variable with the same name as a global variable?
  3. Coding Challenge: Write a function that uses a static variable to calculate the running average of numbers passed to it.
  4. Error Analysis: Identify and explain the compilation errors in attempting to access block-scoped variables outside their blocks.
  5. Best Practices: When would you prefer static local variables over global variables?

Key Takeaways

  • Global variables are accessible throughout the program but should be used sparingly
  • Local variables provide encapsulation and are destroyed when the function exits
  • Block scope allows for temporary variables within specific code sections
  • Static local variables combine local accessibility with persistent storage
  • Understanding scope helps prevent naming conflicts and memory management issues