c

examples

examples.cšŸ”§
/*
 * =============================================================================
 * SCOPE AND STORAGE CLASSES - EXAMPLES FILE
 * =============================================================================
 * 
 * This file demonstrates variable scope and storage classes in C.
 * Topics covered: auto, register, static, extern, local/global scope
 * 
 * Compilation: gcc examples.c -o examples
 * Execution: ./examples
 * =============================================================================
 */

#include <stdio.h>
#include <stdlib.h>

/*
 * =============================================================================
 * GLOBAL VARIABLES SECTION
 * =============================================================================
 * Variables declared outside all functions have file scope (global scope).
 * They are accessible from any function in this file.
 */

int globalVar = 100;                    // Global variable (file scope)
static int staticGlobalVar = 200;       // Static global (file scope, limited linkage)

/*
 * =============================================================================
 * EXAMPLE 1: Block Scope (Local Variables)
 * =============================================================================
 * Variables declared inside a block { } are only accessible within that block.
 */
void example1_block_scope(void) {
    printf("\n=== Example 1: Block Scope ===\n");
    
    int outerVar = 10;      // Scope: entire function
    printf("Outer variable: %d\n", outerVar);
    
    {
        // Inner block starts here
        int innerVar = 20;  // Scope: only this inner block
        printf("Inner variable: %d\n", innerVar);
        printf("Outer variable (from inner block): %d\n", outerVar);
    }
    // Inner block ends - innerVar is destroyed
    
    // printf("innerVar: %d\n", innerVar);  // ERROR! innerVar not accessible
    printf("Outer variable still accessible: %d\n", outerVar);
    
    // Demonstrating nested blocks
    for (int i = 0; i < 3; i++) {
        int loopVar = i * 10;   // New variable each iteration
        printf("Loop iteration %d: loopVar = %d\n", i, loopVar);
    }
    // i and loopVar not accessible here
}

/*
 * =============================================================================
 * EXAMPLE 2: Function Scope and Global Variables
 * =============================================================================
 * Global variables can be accessed from any function.
 */
void modifyGlobal(void) {
    globalVar = 150;    // Modifying global variable
    printf("  Inside modifyGlobal: globalVar = %d\n", globalVar);
}

void readGlobal(void) {
    printf("  Inside readGlobal: globalVar = %d\n", globalVar);
}

void example2_global_scope(void) {
    printf("\n=== Example 2: Global Scope ===\n");
    
    printf("Initial globalVar: %d\n", globalVar);
    
    readGlobal();
    modifyGlobal();
    readGlobal();
    
    // Modify from this function too
    globalVar = 300;
    printf("After modification: globalVar = %d\n", globalVar);
    
    // Reset for other examples
    globalVar = 100;
}

/*
 * =============================================================================
 * EXAMPLE 3: The auto Storage Class
 * =============================================================================
 * auto is the default storage class for local variables.
 * Variables are created and destroyed with each function call.
 */
void example3_auto_storage(void) {
    printf("\n=== Example 3: auto Storage Class ===\n");
    
    // These are implicitly auto
    int x = 10;
    int y = 20;
    
    // Explicit auto (rarely used in modern C)
    auto int z = 30;
    
    printf("auto variables (implicit): x = %d, y = %d\n", x, y);
    printf("auto variable (explicit): z = %d\n", z);
    
    printf("\nDemonstrating auto variable recreation:\n");
}

void autoDemo(void) {
    int count = 0;      // Recreated each call
    count++;
    printf("  count = %d (always 1 because recreated each call)\n", count);
}

void callAutoDemo(void) {
    printf("Calling autoDemo 3 times:\n");
    autoDemo();
    autoDemo();
    autoDemo();
}

/*
 * =============================================================================
 * EXAMPLE 4: The static Storage Class - Local Static Variables
 * =============================================================================
 * Static local variables retain their value between function calls.
 * They are initialized only once.
 */
void staticCounter(void) {
    static int count = 0;   // Initialized once, persists between calls
    count++;
    printf("  staticCounter called %d time(s)\n", count);
}

void example4_static_local(void) {
    printf("\n=== Example 4: static Local Variables ===\n");
    
    printf("Calling staticCounter 5 times:\n");
    for (int i = 0; i < 5; i++) {
        staticCounter();
    }
    
    printf("\nNotice how count persists between calls!\n");
}

/*
 * =============================================================================
 * EXAMPLE 5: static vs auto Comparison
 * =============================================================================
 * Comparing behavior of static and auto variables.
 */
void autoFunction(void) {
    int autoVar = 0;        // Reset each call
    autoVar++;
    printf("  autoVar = %d\n", autoVar);
}

void staticFunction(void) {
    static int staticVar = 0;   // Persists between calls
    staticVar++;
    printf("  staticVar = %d\n", staticVar);
}

void example5_static_vs_auto(void) {
    printf("\n=== Example 5: static vs auto Comparison ===\n");
    
    printf("Calling autoFunction 3 times:\n");
    autoFunction();
    autoFunction();
    autoFunction();
    
    printf("\nCalling staticFunction 3 times:\n");
    staticFunction();
    staticFunction();
    staticFunction();
    
    printf("\nauto resets; static persists.\n");
}

/*
 * =============================================================================
 * EXAMPLE 6: Static Global Variables (File Scope Limitation)
 * =============================================================================
 * static global variables are only accessible within the same file.
 */
void example6_static_global(void) {
    printf("\n=== Example 6: static Global Variables ===\n");
    
    printf("staticGlobalVar = %d\n", staticGlobalVar);
    printf("This variable is only accessible in this file.\n");
    printf("Other .c files cannot access staticGlobalVar.\n");
    
    staticGlobalVar = 250;
    printf("Modified staticGlobalVar = %d\n", staticGlobalVar);
}

/*
 * =============================================================================
 * EXAMPLE 7: The register Storage Class
 * =============================================================================
 * register suggests storing variable in CPU register for faster access.
 * Cannot take address of register variable.
 */
void example7_register_storage(void) {
    printf("\n=== Example 7: register Storage Class ===\n");
    
    register int i;
    register int sum = 0;
    
    // Fast loop with register variable
    printf("Calculating sum of 1 to 100:\n");
    for (i = 1; i <= 100; i++) {
        sum += i;
    }
    printf("Sum = %d\n", sum);
    
    // Demonstrating limitation
    printf("\nNote: Cannot take address of register variable.\n");
    printf("// int *ptr = &i;  // This would cause an error\n");
    
    // Regular variable for comparison
    int regular = 10;
    int *ptr = &regular;
    printf("Address of regular variable: %p\n", (void*)ptr);
}

/*
 * =============================================================================
 * EXAMPLE 8: extern Declaration (Same File)
 * =============================================================================
 * extern can reference a variable defined later in the same file.
 */
void example8_extern_same_file(void);  // Forward declaration

// Variable defined below, but we use extern to reference it first
extern int lateDefinedVar;

void example8_extern_same_file(void) {
    printf("\n=== Example 8: extern Declaration ===\n");
    
    printf("lateDefinedVar = %d\n", lateDefinedVar);
    printf("This variable is defined below but accessible via extern.\n");
    
    lateDefinedVar = 999;
    printf("Modified lateDefinedVar = %d\n", lateDefinedVar);
}

int lateDefinedVar = 500;  // Definition (memory allocated here)

/*
 * =============================================================================
 * EXAMPLE 9: Variable Shadowing
 * =============================================================================
 * Inner scope variables can "shadow" outer scope variables with same name.
 */
int shadowTest = 1000;  // Global

void example9_shadowing(void) {
    printf("\n=== Example 9: Variable Shadowing ===\n");
    
    printf("Global shadowTest: %d\n", shadowTest);
    
    int shadowTest = 2000;  // Shadows global variable
    printf("Local shadowTest (shadows global): %d\n", shadowTest);
    
    {
        int shadowTest = 3000;  // Shadows the local variable
        printf("Inner block shadowTest: %d\n", shadowTest);
    }
    
    printf("Local shadowTest (after inner block): %d\n", shadowTest);
    
    // The global is unchanged
    printf("\nNote: Global variable is unchanged, just hidden.\n");
}

/*
 * =============================================================================
 * EXAMPLE 10: Practical Use of static - Singleton Pattern
 * =============================================================================
 * Using static to implement a simple singleton-like pattern.
 */
int* getSingletonValue(void) {
    static int singleton = 42;  // Created once, persists
    return &singleton;          // Return address (safe because static)
}

void example10_singleton_pattern(void) {
    printf("\n=== Example 10: Singleton with static ===\n");
    
    int *ptr1 = getSingletonValue();
    int *ptr2 = getSingletonValue();
    
    printf("First call: value = %d, address = %p\n", *ptr1, (void*)ptr1);
    printf("Second call: value = %d, address = %p\n", *ptr2, (void*)ptr2);
    
    if (ptr1 == ptr2) {
        printf("Same address! Static variable persists.\n");
    }
    
    // Modify through one pointer
    *ptr1 = 100;
    printf("After *ptr1 = 100: *ptr2 = %d\n", *ptr2);
}

/*
 * =============================================================================
 * EXAMPLE 11: Function Call Counter
 * =============================================================================
 * Practical example: counting function invocations.
 */
int getCallCount(void) {
    static int callCount = 0;
    return ++callCount;
}

void example11_call_counter(void) {
    printf("\n=== Example 11: Function Call Counter ===\n");
    
    printf("Function call counts:\n");
    for (int i = 0; i < 5; i++) {
        printf("  Call #%d: getCallCount() = %d\n", i + 1, getCallCount());
    }
}

/*
 * =============================================================================
 * EXAMPLE 12: Initialization Differences
 * =============================================================================
 * Comparing initialization behavior of different storage classes.
 */
int uninitGlobal;               // Default: 0
static int uninitStaticGlobal;  // Default: 0

void example12_initialization(void) {
    printf("\n=== Example 12: Initialization Behavior ===\n");
    
    int uninitAuto;             // Default: garbage (undefined)
    static int uninitStatic;    // Default: 0
    
    printf("Uninitialized global: %d (default 0)\n", uninitGlobal);
    printf("Uninitialized static global: %d (default 0)\n", uninitStaticGlobal);
    printf("Uninitialized static local: %d (default 0)\n", uninitStatic);
    printf("Uninitialized auto (WARNING - garbage): %d\n", uninitAuto);
    
    printf("\nAlways initialize auto variables explicitly!\n");
}

/*
 * =============================================================================
 * EXAMPLE 13: Memory Addresses - Storage Location
 * =============================================================================
 * Showing where different variables are stored in memory.
 */
void example13_memory_locations(void) {
    printf("\n=== Example 13: Memory Locations ===\n");
    
    int autoVar = 10;
    static int staticVar = 20;
    
    printf("Variable addresses:\n");
    printf("  Global variable:       %p\n", (void*)&globalVar);
    printf("  Static global:         %p\n", (void*)&staticGlobalVar);
    printf("  Static local:          %p\n", (void*)&staticVar);
    printf("  Auto (local):          %p\n", (void*)&autoVar);
    
    printf("\nNotice: static variables have similar addresses (data segment)\n");
    printf("Auto variables are on the stack (different memory region)\n");
}

/*
 * =============================================================================
 * EXAMPLE 14: Returning Pointer to Static Variable
 * =============================================================================
 * Safe to return pointer to static local (persists after function returns).
 */
int* safeReturn(void) {
    static int value = 100;
    return &value;  // Safe - static persists
}

// DANGEROUS - Don't do this!
// int* unsafeReturn(void) {
//     int value = 100;
//     return &value;  // UNSAFE - auto destroyed after return
// }

void example14_safe_return(void) {
    printf("\n=== Example 14: Safe Pointer Return ===\n");
    
    int *ptr = safeReturn();
    printf("Returned pointer to static: %d\n", *ptr);
    
    *ptr = 200;
    printf("Modified through pointer: %d\n", *safeReturn());
    
    printf("\nReturning pointers to static variables is safe.\n");
    printf("NEVER return pointers to auto (local) variables!\n");
}

/*
 * =============================================================================
 * MAIN FUNCTION
 * =============================================================================
 */
int main(void) {
    printf("╔════════════════════════════════════════════════════════════╗\n");
    printf("ā•‘     SCOPE AND STORAGE CLASSES - DEMONSTRATION PROGRAM      ā•‘\n");
    printf("ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•\n");
    
    example1_block_scope();
    example2_global_scope();
    example3_auto_storage();
    callAutoDemo();
    example4_static_local();
    example5_static_vs_auto();
    example6_static_global();
    example7_register_storage();
    example8_extern_same_file();
    example9_shadowing();
    example10_singleton_pattern();
    example11_call_counter();
    example12_initialization();
    example13_memory_locations();
    example14_safe_return();
    
    printf("\n╔════════════════════════════════════════════════════════════╗\n");
    printf("ā•‘                    EXAMPLES COMPLETED                       ā•‘\n");
    printf("ā•šā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•ā•\n");
    
    return 0;
}
Examples - C Programming Tutorial | DeepML