C Fundamental Practice Problems: Complete Guide
C Fundamental Practice Problems: A Comprehensive Tutorial
Learning C is not about memorizing syntax—it’s about building muscle memory through practice. This tutorial is a structured practice guide covering the fundamental concepts every C programmer must master: variables, data types, input/output, format specifiers, operators, conditional statements, and loops.
Each section explains the concept, then walks through a representative practice problem with a complete, portable C99/C11 solution and expected output.
Conceptual Introduction & Fundamentals
Why Practice Fundamentals?
Fundamentals are the foundation of every C program, whether it’s 20 lines or 20,000. Weak fundamentals show up as:
- Off-by-one errors in loops.
- Format specifier mismatches causing undefined behavior.
- Buffer overflows from unsafe input functions.
- Silent type conversion bugs in arithmetic.
- Incorrect edge-case handling in conditionals.
The Fundamental Topics
| Topic | Purpose |
|---|---|
| Variables | Named storage for values |
| Data Types | Size and interpretation of values |
| Input / Output | Communicating with the user |
| Format Specifiers | Controlling how data is printed or read |
| Operators | Arithmetic, relational, logical, bitwise |
| Conditional Statements | Branching logic (if, switch) |
| Loops | Repetition (for, while, do-while) |
Difficulty Progression
- Easy: Printing, variables, simple arithmetic, I/O.
- Medium: Control flow, digit manipulation, number theory basics.
Syntax & Core Mechanics
1. Variables and Data Types
c
int age = 25; double price = 19.99; char grade = 'A';
Use int for whole numbers, double for decimals, char for single characters. Prefer double over float for computation; use long long when values may exceed int.
2. Input with fgets and Parsing
Never use scanf("%s", ...) or gets for strings. Prefer fgets plus strtol/strtod for robust parsing.
c
char buffer[64]; if (fgets(buffer, sizeof(buffer), stdin) == NULL) return 1; int value = (int)strtol(buffer, NULL, 10);
3. Output with printf
Match the specifier to the type:
| Type | Specifier |
|---|---|
int | %d |
unsigned int | %u |
long long | %lld |
double | %f, %lf, %g |
char | %c |
| String | %s |
size_t | %zu |
| Pointer | %p |
4. Operators
c
int a = 7, b = 3; int q = a / b; /* 2 — integer division */ int r = a % b; /* 1 */ double f = (double)a / b; /* 2.333... */
Use casting to force floating-point division.
5. Conditionals and Loops
c
if (a > b) { /* ... */ } else if (a == b) { /* ... */ } else { /* ... */ } for (int i = 0; i < n; i++) { /* ... */ } while (cond) { /* ... */ } do { /* ... */ } while (cond); Full Practical Code Example with Explanation
Below are eight representative problems covering the fundamentals, each a self-contained C99 program with verified output.
Problem 1: Print “GeeksforGeeks” with Quotes
Goal: Print a string including literal double quotes.
c
#include <stdio.h> int main(void) { /* Escape double quotes with backslash */ printf("\"GeeksforGeeks\"\n"); return 0; } Expected output:
text
"GeeksforGeeks"
Notes: \" inside a string literal produces a literal ".
Problem 2: Swap Two Numbers (Without Temp for Integers)
Goal: Swap a and b.
c
#include <stdio.h> int main(void) { int a = 5, b = 7; /* Arithmetic swap (works for ints; watch overflow) */ a = a + b; b = a - b; a = a - b; printf("a = %d, b = %d\n", a, b); return 0; } Expected output:
text
a = 7, b = 5
Notes: For large values, prefer a temporary variable or XOR swap. XOR is safe for equal values but not for aliasing.
Problem 3: Convert double to int
Goal: Truncate a floating-point number.
c
#include <stdio.h> int main(void) { double d = 3.99; int i = (int)d; /* explicit cast truncates toward zero */ printf("%d\n", i); return 0; } Expected output:
text
3
Notes: (int) truncates; round() from <math.h> rounds to nearest.
Problem 4: Last Digit of a Number
Goal: Extract the last decimal digit.
c
#include <stdio.h> #include <stdlib.h> int main(void) { int n = 12345; int last = n % 10; /* Works for non-negative; see notes for negatives */ printf("%d\n", last); return 0; } Expected output:
text
5
Notes: For negative n, % in C99 yields a non-positive remainder. Use abs(n) % 10 or n % 10 + 10 (mod 10) for a non-negative digit.
Problem 5: Compare Two Numbers
Goal: Print which of two numbers is greater.
c
#include <stdio.h> int main(void) { int a = 10, b = 20; if (a > b) printf("%d is greater\n", a); else if (b > a) printf("%d is greater\n", b); else printf("Both are equal\n"); return 0; } Expected output:
text
20 is greater
Problem 6: FizzBuzz (1 to N)
Goal: Print Fizz, Buzz, or FizzBuzz per divisibility rule.
c
#include <stdio.h> void fizzbuzz(int n) { for (int i = 1; i <= n; i++) { if (i % 15 == 0) printf("FizzBuzz "); else if (i % 3 == 0) printf("Fizz "); else if (i % 5 == 0) printf("Buzz "); else printf("%d ", i); } printf("\n"); } int main(void) { fizzbuzz(15); return 0; } Expected output:
text
1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz
Notes: Check i % 15 == 0 first, otherwise the individual cases shadow the combined one.
Problem 7: Multiplication Table
Goal: Print an n × n multiplication table.
c
#include <stdio.h> int main(void) { int n = 5; for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { printf("%4d", i * j); } printf("\n"); } return 0; } Expected output:
text
1 2 3 4 5 2 4 6 8 10 3 6 9 12 15 4 8 12 16 20 5 10 15 20 25
Problem 8: Sum of N Numbers with Safe Input
Goal: Read n integers from stdin, sum them.
c
#include <stdio.h> #include <stdlib.h> #include <errno.h> #include <limits.h> int readInteger(const char *prompt, int *outValue) { char buffer[64]; char *endPtr; long val; printf("%s", prompt); fflush(stdout); if (fgets(buffer, sizeof(buffer), stdin) == NULL) return -1; errno = 0; val = strtol(buffer, &endPtr, 10); if (endPtr == buffer || (*endPtr != '\n' && *endPtr != '\0')) return -1; if (errno == ERANGE || val < INT_MIN || val > INT_MAX) return -1; *outValue = (int)val; return 0; } int main(void) { int n; if (readInteger("How many numbers? ", &n) != 0 || n <= 0) { fprintf(stderr, "Invalid count.\n"); return 1; } long long sum = 0; for (int i = 0; i < n; i++) { int x; char prompt[40]; snprintf(prompt, sizeof(prompt), "Number %d: ", i + 1); if (readInteger(prompt, &x) != 0) { fprintf(stderr, "Invalid number.\n"); return 1; } sum += x; } printf("Sum = %lld\n", sum); return 0; } Sample run:
text
How many numbers? 3 Number 1: 10 Number 2: 20 Number 3: 30 Sum = 60
Notes: Uses long long for the sum to prevent overflow; strtol for robust parsing.
Bonus Problem: Medium — Count Digits of an Integer
c
#include <stdio.h> #include <stdlib.h> int countDigits(long long n) { if (n == 0) return 1; if (n < 0) n = -n; int count = 0; while (n > 0) { count++; n /= 10; } return count; } int main(void) { printf("%d\n", countDigits(0)); /* 1 */ printf("%d\n", countDigits(12345)); /* 5 */ printf("%d\n", countDigits(-9876)); /* 4 */ return 0; } Expected output:
text
1 5 4
Bonus Problem: Medium — Leap Year
c
#include <stdio.h> int isLeapYear(int year) { /* A year is leap if divisible by 4 but not 100, unless divisible by 400 */ return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); } int main(void) { int years[] = {1900, 2000, 2024, 2023, 2100}; for (int i = 0; i < 5; i++) { printf("%d → %s\n", years[i], isLeapYear(years[i]) ? "Leap" : "Not Leap"); } return 0; } Expected output:
text
1900 → Not Leap 2000 → Leap 2024 → Leap 2023 → Not Leap 2100 → Not Leap
Common Pitfalls, Edge Cases & Memory Considerations
1. Integer Division Truncation
5 / 2 is 2, not 2.5. Cast one operand.
c
double r = (double)a / b;
2. Format Specifier Mismatch
printf("%d", 3.14) is undefined behavior. Match specifiers to types.
3. Negative Remainders
In C99, -7 % 3 == -1, not 2. Use (n % m + m) % m for a non-negative result.
4. Off-by-One in Loops
for (i = 0; i <= n; i++) iterates n+1 times. Use < unless you need inclusive bounds.
5. Unsafe Input
Never use gets (removed in C11). Prefer fgets with size limits.
6. Uninitialized Variables
Reading before assignment is undefined behavior.
c
int x; printf("%d\n", x); /* BUG */ 7. Signed/Unsigned Confusion
Mixing signed and unsigned in comparisons yields surprising results.
c
int a = -1; unsigned int b = 1; if (a < b) { /* may be FALSE due to conversion */ } 8. Overflow
int overflows for large sums. Use long long.
c
long long sum = 0;
9. Character Classifications
Use <ctype.h> functions for portability.
c
if (isdigit((unsigned char)c)) { /* ... */ } Cast to unsigned char before passing.
10. Memory Considerations
- Fundamental programs rarely allocate memory.
- When they do, prefer dynamic allocation for large inputs.
- Free everything you
malloc. - Never return pointers to stack variables.
Summary & Best Practices
Fundamentals are the platform on which all C skill is built. Practice them until they become reflexive.
Key Takeaways
- Variables and types define what can be stored.
- Format specifiers define how data is printed/read.
- Operators and control flow define how programs compute.
- Safe input requires
fgets+strtol/strtod. - Every bug you encounter at scale is a fundamentals bug in disguise.
Best Practices
- Compile with
-Wall -Wextra -pedantic -std=c11on every exercise. - Match format specifiers to types.
- Use
long longfor sums;doublefor decimals. - Prefer
fgetsoverscanf("%s", ...). - Cast before division when you need floating-point results.
- Initialize all variables.
- Handle negative remainders explicitly.
- Cast
chartounsigned charfor<ctype.h>functions. - Test boundary cases: zero, negatives, maxima, empty input.
- Practice daily — fundamentals are perishable without repetition.
Recommended Practice Progression
- Easy: Print GeeksforGeeks; Global Variable; Swap Numbers; Convert double to int; Input Integer; Print with Space/Without/Separator/New Line; Be Precise; Print with Quotes; Last Digit; Compute a/b; Compare Two Numbers; Sign Check; Big Number; Sum of N; Multiplication Table.
- Medium: AP Term; GP Term; Even Odd Game; Greatest of Three; Leap Year; FizzBuzz; Calculator; First Digit; Count Digits; Days Before n Days; Prime Factorization; Next Prime.
Work through each exercise with the templates and safety rules above. By the time you finish, fundamentals become second nature.











