c
exercises
exercises.cπ§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*)®Var);
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;
}