Skip to main content

Types, Control Flow, and Functions Workshop

This practice page exercises Clusters 2 and 3. Finish the matching concept pages before starting.

Use this compile command for every program below:

gcc -Wall -Wextra -std=c11 -o prog prog.c

Promote to -Werror once the program is clean.

Retrieval Prompts​

  1. Define integer promotion. Which types does it apply to?
  2. State one precedence trap and one sequence-point rule from memory.
  3. State what static does at file scope, and separately what it does at block scope.
  4. State the difference between a function declaration and a function definition.
  5. Name three preprocessor hazards and a rule that avoids each.

Compare and Distinguish​

  • int, long, long long, size_t, int32_t: which to use when and why
  • unsigned overflow vs signed overflow
  • static at file scope vs block scope
  • extern int x; in a header vs int x = 0; in a .c file
  • macro-like function vs static inline function

Common Mistake Check​

For each, identify the error:

  1. if (x = 5) { ... }
  2. #define SQUARE(x) x*x
  3. printf("%d\n", sizeof(int));
  4. int arr[10]; void f(int arr[10]) { size_t n = sizeof arr / sizeof arr[0]; ... }
  5. register int *p = &x;
  6. for (unsigned i = n; i >= 0; i--) { ... }
  7. int *arr = (int*)malloc(sizeof(int)); for (i = 0; i < 10; i++) arr[i] = i;
  8. #define MAX 100; used as for (int i = 0; i < MAX; i++)

Precedence and Sequence Points Drill​

For each expression, give the value on a platform where int is 32-bit, or mark UB. Then parenthesize it the way it actually parses.

  1. 1 + 2 * 3
  2. 1 << 2 + 3
  3. a < b ? 1 : 2 + 3
  4. !0 == 1
  5. 0x01 | 0x02 & 0x03
  6. Given int i = 0;, the value of i++ + ++i
  7. Given int i = 0; int a[3] = {10, 20, 30};, the value after a[i] = i++;
  8. Given int i = 1;, the value of (i++, i++, i)

Integer Width Drill​

Write a program that prints, on your platform:

printf("%zu %zu %zu %zu %zu\n",
sizeof(char), sizeof(short), sizeof(int), sizeof(long), sizeof(long long));

Explain any differences between Linux (LP64) and Windows (LLP64).

Control Flow Drill​

Write each as a small program:

  1. A switch on a char that classifies whitespace, digit, vowel, consonant, other. Use fall-through deliberately with /* fall through */ comments, and break elsewhere.
  2. A for loop that prints only FizzBuzz numbers 1..100 using continue for the non-printing cases.
  3. A do { ... } while (cond); that asks for input until the user types q.
  4. An error-handling chain that uses a single goto cleanup; to free two resources.

Functions and Linkage Drill​

Split a single program into stats.c, stats.h, main.c:

  1. stats.h declares double mean(const int *a, size_t n); and double stdev(const int *a, size_t n);.
  2. stats.c defines both, plus a static helper static double sumsq(const int *a, size_t n, double m);.
  3. main.c reads 10 integers via fgets+sscanf and prints mean and stdev.
  4. Use nm stats.o to confirm mean and stdev are global (T) and sumsq is local (t).

Preprocessor Drill​

Write two versions of MAX(a, b):

  1. #define MAX(a, b) (a > b ? a : b) - show where it breaks with MAX(x & 0xF, 5).
  2. #define MAX(a, b) ((a) > (b) ? (a) : (b)) - show where it still breaks with MAX(i++, j++).
  3. Replace both with static inline int imax(int a, int b); and explain why it is safer.

Evidence Check​

This page is complete only if you can:

  • build a clean multi-file program with -Wall -Wextra -std=c11 and no warnings
  • explain each nm classification for your own code
  • produce correct answers on the precedence and sequence-point drill without looking them up