c

exercises

exercises.cπŸ”§
/*
 * =============================================================================
 * SCOPE AND STORAGE CLASSES - EXERCISES FILE
 * =============================================================================
 * 
 * Complete the following exercises to test your understanding of
 * variable scope and storage classes in C.
 * 
 * Compilation: gcc exercises.c -o exercises
 * Execution: ./exercises
 * =============================================================================
 */

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

/*
 * =============================================================================
 * EXERCISE 1: Predict the Output - Block Scope
 * =============================================================================
 * Study the code and predict what will be printed.
 * Then run to verify.
 */
void exercise1_predict_output(void) {
    printf("\n=== Exercise 1: Predict the Output (Block Scope) ===\n");
    
    int x = 10;
    printf("1. x = %d\n", x);
    
    {
        int x = 20;
        printf("2. x = %d\n", x);
        
        {
            int x = 30;
            printf("3. x = %d\n", x);
        }
        
        printf("4. x = %d\n", x);
    }
    
    printf("5. x = %d\n", x);
    
    printf("\nYour predictions:\n");
    printf("1. x = ?\n");
    printf("2. x = ?\n");
    printf("3. x = ?\n");
    printf("4. x = ?\n");
    printf("5. x = ?\n");
}

/*
 * =============================================================================
 * EXERCISE 2: Create a Call Counter
 * =============================================================================
 * Complete the function to count how many times it has been called.
 * Use the appropriate storage class.
 */
int countCalls(void) {
    // TODO: Declare a variable that persists between calls
    // and returns the count of how many times this function was called
    
    // Your code here
    
    return 0;  // Modify this
}

void exercise2_call_counter(void) {
    printf("\n=== Exercise 2: Create a Call Counter ===\n");
    
    printf("Testing countCalls():\n");
    for (int i = 0; i < 5; i++) {
        printf("  Call #%d returned: %d\n", i + 1, countCalls());
    }
    
    printf("\nExpected output: 1, 2, 3, 4, 5\n");
}

/*
 * =============================================================================
 * EXERCISE 3: Fix the Bug
 * =============================================================================
 * This function has a bug related to scope. Find and fix it.
 */
int sumRange(int start, int end) {
    // BUG: The sum variable is in the wrong scope
    
    for (int i = start; i <= end; i++) {
        int sum = 0;    // BUG! Move this
        sum += i;
    }
    
    // return sum;  // Uncomment after fixing
    return 0;       // Remove after fixing
}

void exercise3_fix_bug(void) {
    printf("\n=== Exercise 3: Fix the Scope Bug ===\n");
    
    printf("Sum of 1 to 10: %d\n", sumRange(1, 10));
    printf("Expected: 55\n");
    
    printf("\nHint: Where should 'int sum = 0;' be declared?\n");
}

/*
 * =============================================================================
 * EXERCISE 4: static vs auto Quiz
 * =============================================================================
 * Answer the questions by modifying the answer variables.
 */
void exercise4_quiz(void) {
    printf("\n=== Exercise 4: static vs auto Quiz ===\n");
    
    // Set answers to 1 for auto, 2 for static
    int q1 = 0;  // Which storage class initializes to 0 by default?
    int q2 = 0;  // Which is stored on the stack?
    int q3 = 0;  // Which persists between function calls?
    int q4 = 0;  // Which is the default for local variables?
    int q5 = 0;  // Which can limit global variable visibility to one file?
    
    printf("Questions (1=auto, 2=static):\n");
    printf("1. Initializes to 0 by default: %s\n", 
           q1 == 1 ? "auto" : q1 == 2 ? "static" : "not answered");
    printf("2. Stored on the stack: %s\n",
           q2 == 1 ? "auto" : q2 == 2 ? "static" : "not answered");
    printf("3. Persists between calls: %s\n",
           q3 == 1 ? "auto" : q3 == 2 ? "static" : "not answered");
    printf("4. Default for local vars: %s\n",
           q4 == 1 ? "auto" : q4 == 2 ? "static" : "not answered");
    printf("5. Limits global visibility: %s\n",
           q5 == 1 ? "auto" : q5 == 2 ? "static" : "not answered");
}

/*
 * =============================================================================
 * EXERCISE 5: Implement a Simple ID Generator
 * =============================================================================
 * Create a function that generates unique IDs starting from 1000.
 * Each call should return the next ID.
 */
int generateID(void) {
    // TODO: Use static to maintain the current ID
    // Start from 1000, increment by 1 each call
    
    // Your code here
    
    return 0;  // Modify this
}

void exercise5_id_generator(void) {
    printf("\n=== Exercise 5: ID Generator ===\n");
    
    printf("Generating IDs:\n");
    for (int i = 0; i < 5; i++) {
        printf("  New ID: %d\n", generateID());
    }
    
    printf("\nExpected: 1000, 1001, 1002, 1003, 1004\n");
}

/*
 * =============================================================================
 * EXERCISE 6: Identify Storage Classes
 * =============================================================================
 * For each variable declaration, identify the storage class and scope.
 */
int globalA = 10;
static int globalB = 20;

void exercise6_identify(void) {
    printf("\n=== Exercise 6: Identify Storage Classes ===\n");
    
    int localC = 30;
    static int localD = 40;
    register int localE = 50;
    
    printf("Identify storage class and scope for each:\n\n");
    
    printf("int globalA = 10;        (outside functions)\n");
    printf("  Storage class: ______  Scope: ______\n\n");
    
    printf("static int globalB = 20; (outside functions)\n");
    printf("  Storage class: ______  Scope: ______\n\n");
    
    printf("int localC = 30;         (inside function)\n");
    printf("  Storage class: ______  Scope: ______\n\n");
    
    printf("static int localD = 40;  (inside function)\n");
    printf("  Storage class: ______  Scope: ______\n\n");
    
    printf("register int localE = 50; (inside function)\n");
    printf("  Storage class: ______  Scope: ______\n\n");
    
    // Suppress unused variable warnings
    (void)localC;
    (void)localD;
    (void)localE;
}

/*
 * =============================================================================
 * EXERCISE 7: Memory Persistence Test
 * =============================================================================
 * Complete the function to demonstrate static persistence.
 */
void persistenceDemo(void) {
    // TODO: Create one auto and one static variable
    // Initialize both to 0
    // Increment both by 10
    // Print both values
    
    // Your code here
    
    printf("  auto var = ?\n");
    printf("  static var = ?\n");
}

void exercise7_persistence(void) {
    printf("\n=== Exercise 7: Memory Persistence ===\n");
    
    printf("Calling persistenceDemo 3 times:\n\n");
    
    printf("Call 1:\n");
    persistenceDemo();
    
    printf("\nCall 2:\n");
    persistenceDemo();
    
    printf("\nCall 3:\n");
    persistenceDemo();
    
    printf("\nQuestion: What should the auto and static values be on each call?\n");
}

/*
 * =============================================================================
 * EXERCISE 8: Fix the extern Declaration
 * =============================================================================
 * The following code has issues with extern usage. Fix them.
 */
// extern int undefinedVar;  // Uncomment and fix

void exercise8_extern(void) {
    printf("\n=== Exercise 8: Fix extern Usage ===\n");
    
    // TODO: Create a proper extern relationship
    // 1. Declare a variable with extern
    // 2. Define it somewhere in this file
    // 3. Use it here
    
    printf("This exercise requires understanding declaration vs definition.\n");
    printf("Steps:\n");
    printf("1. Add 'extern int sharedValue;' before this function\n");
    printf("2. Add 'int sharedValue = 100;' somewhere in the file\n");
    printf("3. Print sharedValue here\n");
}

/*
 * =============================================================================
 * EXERCISE 9: Scope Puzzle
 * =============================================================================
 * What will this program print? Trace through carefully.
 */
int puzzle = 1;

void puzzleFunc(void) {
    int puzzle = 2;
    printf("B: puzzle = %d\n", puzzle);
    
    {
        static int puzzle = 3;
        printf("C: puzzle = %d\n", puzzle);
        puzzle++;
    }
}

void exercise9_puzzle(void) {
    printf("\n=== Exercise 9: Scope Puzzle ===\n");
    
    printf("A: puzzle = %d\n", puzzle);
    puzzleFunc();
    printf("D: puzzle = %d\n", puzzle);
    puzzleFunc();
    printf("E: puzzle = %d\n", puzzle);
    
    printf("\nAnalyze: Which 'puzzle' is used in each case?\n");
    printf("Why does C change on the second call to puzzleFunc()?\n");
}

/*
 * =============================================================================
 * EXERCISE 10: Create a Running Average Calculator
 * =============================================================================
 * Create a function that maintains a running average of all numbers passed.
 */
double runningAverage(double newValue) {
    // TODO: Use static variables to track:
    // - Total sum of all values
    // - Count of values
    // Return the current average
    
    // Your code here
    
    return 0.0;  // Modify this
}

void exercise10_running_average(void) {
    printf("\n=== Exercise 10: Running Average ===\n");
    
    double values[] = {10.0, 20.0, 30.0, 40.0, 50.0};
    int n = 5;
    
    printf("Adding values and tracking running average:\n");
    for (int i = 0; i < n; i++) {
        double avg = runningAverage(values[i]);
        printf("  Added %.1f, Average = %.2f\n", values[i], avg);
    }
    
    printf("\nExpected averages: 10.00, 15.00, 20.00, 25.00, 30.00\n");
}

/*
 * =============================================================================
 * EXERCISE 11: Register Variable Limitation
 * =============================================================================
 * Demonstrate what you cannot do with register variables.
 */
void exercise11_register(void) {
    printf("\n=== Exercise 11: Register Limitations ===\n");
    
    register int regVar = 100;
    int normalVar = 200;
    
    printf("Register variable value: %d\n", regVar);
    printf("Normal variable value: %d\n", normalVar);
    printf("Normal variable address: %p\n", (void*)&normalVar);
    
    // TODO: Uncomment the following line and observe the error
    // printf("Register variable address: %p\n", (void*)&regVar);
    
    printf("\nWhat error do you get when uncommenting the address line?\n");
    printf("Why can't you take the address of a register variable?\n");
}

/*
 * =============================================================================
 * EXERCISE 12: True or False
 * =============================================================================
 * Mark each statement as true (1) or false (0).
 */
void exercise12_true_false(void) {
    printf("\n=== Exercise 12: True or False ===\n");
    
    int answers[10] = {0};  // Fill in 1 for true, 0 for false
    
    // answers[0]: static local variables are initialized to 0 by default
    // answers[1]: auto variables are initialized to 0 by default
    // answers[2]: register variables are always stored in CPU registers
    // answers[3]: extern allocates new memory for the variable
    // answers[4]: Global variables can be accessed from any function
    // answers[5]: static global variables can be accessed from other files
    // answers[6]: Local variables exist for the entire program duration
    // answers[7]: You can return a pointer to a static local variable safely
    // answers[8]: The auto keyword is required for local variables
    // answers[9]: static limits the scope of global variables to one file
    
    printf("Statements:\n");
    printf("0. static locals init to 0: %s\n", answers[0] ? "TRUE" : "FALSE");
    printf("1. auto vars init to 0: %s\n", answers[1] ? "TRUE" : "FALSE");
    printf("2. register always in CPU: %s\n", answers[2] ? "TRUE" : "FALSE");
    printf("3. extern allocates memory: %s\n", answers[3] ? "TRUE" : "FALSE");
    printf("4. Global vars accessible anywhere: %s\n", answers[4] ? "TRUE" : "FALSE");
    printf("5. static global across files: %s\n", answers[5] ? "TRUE" : "FALSE");
    printf("6. Local vars exist always: %s\n", answers[6] ? "TRUE" : "FALSE");
    printf("7. Safe to return static ptr: %s\n", answers[7] ? "TRUE" : "FALSE");
    printf("8. auto keyword required: %s\n", answers[8] ? "TRUE" : "FALSE");
    printf("9. static limits global scope: %s\n", answers[9] ? "TRUE" : "FALSE");
}

/*
 * =============================================================================
 * EXERCISE 13: Implement a Simple Cache
 * =============================================================================
 * Create a function that caches the last computed result.
 */
int cachedSquare(int n) {
    // TODO: Use static to cache the last input and result
    // If the same input is passed again, return cached result
    // Otherwise, compute new result and cache it
    
    // Hints:
    // - static int lastInput = -1;
    // - static int lastResult = 0;
    
    // Your code here
    
    printf("  Computing %d^2...\n", n);  // Shows when computation happens
    return n * n;
}

void exercise13_cache(void) {
    printf("\n=== Exercise 13: Simple Cache ===\n");
    
    printf("cachedSquare(5): %d\n", cachedSquare(5));
    printf("cachedSquare(5): %d\n", cachedSquare(5));  // Should use cache
    printf("cachedSquare(3): %d\n", cachedSquare(3));
    printf("cachedSquare(3): %d\n", cachedSquare(3));  // Should use cache
    
    printf("\n'Computing...' should only appear for new values.\n");
}

/*
 * =============================================================================
 * EXERCISE 14: Multi-File Simulation
 * =============================================================================
 * Answer questions about how to share variables across files.
 */
void exercise14_multi_file(void) {
    printf("\n=== Exercise 14: Multi-File Variables ===\n");
    
    printf("Fill in the blanks for sharing variables across files:\n\n");
    
    printf("File: config.c\n");
    printf("  ______ int maxUsers = 100;  // Definition\n\n");
    
    printf("File: main.c\n");
    printf("  ______ int maxUsers;        // Declaration\n\n");
    
    printf("File: utils.c\n");
    printf("  ______ int maxUsers;        // Declaration\n\n");
    
    printf("Question: What keyword goes in each blank?\n");
    printf("Hint: One is nothing (or empty), others use extern.\n");
}

/*
 * =============================================================================
 * EXERCISE 15: Complete the Summary Table
 * =============================================================================
 * Fill in the missing information in the table.
 */
void exercise15_summary(void) {
    printf("\n=== Exercise 15: Complete the Summary ===\n");
    
    printf("β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”\n");
    printf("β”‚ Storage Classβ”‚  Storage  β”‚  Default  β”‚   Scope   β”‚ Lifetime  β”‚\n");
    printf("β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€\n");
    printf("β”‚     auto     β”‚   _____   β”‚  garbage  β”‚   block   β”‚   _____   β”‚\n");
    printf("β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€\n");
    printf("β”‚   register   β”‚  _____    β”‚  _____    β”‚   block   β”‚   block   β”‚\n");
    printf("β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€\n");
    printf("β”‚ static local β”‚   data    β”‚    0      β”‚   _____   β”‚  _____    β”‚\n");
    printf("β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€\n");
    printf("β”‚static global β”‚   _____   β”‚    0      β”‚   file    β”‚  program  β”‚\n");
    printf("β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€\n");
    printf("β”‚    extern    β”‚   data    β”‚    _____  β”‚  _____    β”‚  program  β”‚\n");
    printf("β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜\n");
    
    printf("\nFill in the blanks above.\n");
}

/*
 * =============================================================================
 * MAIN FUNCTION
 * =============================================================================
 */
int main(void) {
    printf("╔════════════════════════════════════════════════════════════╗\n");
    printf("β•‘      SCOPE AND STORAGE CLASSES - EXERCISE FILE             β•‘\n");
    printf("β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•\n");
    printf("\nComplete each exercise by modifying the code above.\n");
    printf("Then compile and run to check your answers.\n");
    
    exercise1_predict_output();
    exercise2_call_counter();
    exercise3_fix_bug();
    exercise4_quiz();
    exercise5_id_generator();
    exercise6_identify();
    exercise7_persistence();
    exercise8_extern();
    exercise9_puzzle();
    exercise10_running_average();
    exercise11_register();
    exercise12_true_false();
    exercise13_cache();
    exercise14_multi_file();
    exercise15_summary();
    
    printf("\n╔════════════════════════════════════════════════════════════╗\n");
    printf("β•‘                       ANSWER KEY                            β•‘\n");
    printf("β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•\n");
    
    printf("\nExercise 1: 10, 20, 30, 20, 10\n");
    printf("Exercise 2: static int count = 0; return ++count;\n");
    printf("Exercise 3: Move 'int sum = 0;' before the for loop\n");
    printf("Exercise 4: 2, 1, 2, 1, 2\n");
    printf("Exercise 5: static int id = 999; return ++id;\n");
    printf("Exercise 6: \n");
    printf("  globalA: none/extern, file scope\n");
    printf("  globalB: static, file scope (limited linkage)\n");
    printf("  localC: auto, block scope\n");
    printf("  localD: static, block scope\n");
    printf("  localE: register, block scope\n");
    printf("Exercise 9: A=1, B=2, C=3, D=1, B=2, C=4, E=1\n");
    printf("Exercise 10: static double sum = 0; static int count = 0;\n");
    printf("             sum += newValue; return sum / ++count;\n");
    printf("Exercise 12: T, F, F, F, T, F, F, T, F, T\n");
    printf("Exercise 14: (nothing), extern, extern\n");
    printf("Exercise 15: stack/block, CPU reg/garbage, block/program, data, 0/global\n");
    
    return 0;
}
Exercises - C Programming Tutorial | DeepML