
C Programming Practice: 15 Exercises from Basics to Pointers
Learning C is one of the best investments you can make as a programmer. It forces you to think about how memory works, how data is stored, and why every byte matters β concepts that make you a better developer in any lan...
C Programming Practice: 15 Exercises from Basics to Pointers
Learning C is one of the best investments you can make as a programmer. It forces you to think about how memory works, how data is stored, and why every byte matters β concepts that make you a better developer in any language.
This post is a hands-on practice set covering the fundamentals: variables, data types, strings, structs, unions, enums, pointers, and conditional logic. There are 15 exercises, ordered from easy to hard. The idea is simple: read the problem, write the code yourself, then check the answer.
No fluff. Just practice.
"The only way to learn a new programming language is by writing programs in it."
What you need to know before starting:
A C compiler (GCC recommended β
gcc file.c -o out && ./out)Basic familiarity with
printf,scanf, and variable declarationsA general understanding of variables, data types, strings, structs, pointers, and conditionals
Each exercise includes the expected input/output so you know what to aim for. Answers are hidden β open them only after you've tried.
Coin Change Counter
Take an integer input representing an amount in "cent" (e.g. 485). Calculate how many 25cent, 10cent, 5cent, and 1cent coins are needed. Pass the remainder to the next denomination.
Input : 485
Output:
25 cent: 19
10 cent: 1
5 cent: 1
1 cent: 0
---
#include <stdio.h>
int main() {
int amount;
printf("Enter amount in cent: ");
scanf("%d", &amount);
printf("25 cent: %d\n", amount / 25); amount %= 25;
printf("10 cent: %d\n", amount / 10); amount %= 10;
printf(" 5 cent: %d\n", amount / 5); amount %= 5;
printf(" 1 cent: %d\n", amount);
return 0;
}
Temperature Converter
Read a temperature in Celsius. Print the Fahrenheit and Kelvin equivalents.
F = C Γ 9/5 + 32
K = C + 273.15
Input : 100
Output:
Fahrenheit: 212.00
Kelvin : 373.15
---
#include <stdio.h>
int main() {
float c, f, k;
printf("Celsius: ");
scanf("%f", &c);
f = c * 9.0f / 5.0f + 32;
k = c + 273.15f;
printf("Fahrenheit: %.2f\n", f);
printf("Kelvin : %.2f\n", k);
return 0;
}
ASCII Neighbors
Read a single character. Print its ASCII value, the character before it, and the character after it.
Input : M
Output:
Character : M
ASCII : 77
Previous : L (76)
Next : N (78)
---
#include <stdio.h>
int main() {
char c;
printf("Character: ");
scanf(" %c", &c);
printf("Character : %c\n", c);
printf("ASCII : %d\n", c);
printf("Previous : %c (%d)\n", c-1, c-1);
printf("Next : %c (%d)\n", c+1, c+1);
return 0;
}
Digit Sum
Read a 3-digit integer. Extract each digit and print their sum.
Input : 357
Output:
Hundreds : 3
Tens : 5
Units : 7
Sum : 15
---
#include <stdio.h>
int main() {
int n, h, t, u;
printf("3-digit number: ");
scanf("%d", &n);
h = n / 100;
t = (n / 10) % 10;
u = n % 10;
printf("Hundreds : %d\n", h);
printf("Tens : %d\n", t);
printf("Units : %d\n", u);
printf("Sum : %d\n", h + t + u);
return 0;
}
String Comparison
Read two words. Print the length of each, which comes first alphabetically, and whether they are identical.
Input : masa kasa
Output:
masa : 4 chars
kasa : 4 chars
Alphabetically first: kasa
Same word: No
---
#include <stdio.h>
#include <string.h>
int main() {
char a[50], b[50];
printf("Word 1: "); scanf("%s", a);
printf("Word 2: "); scanf("%s", b);
printf("%s : %zu chars\n", a, strlen(a));
printf("%s : %zu chars\n", b, strlen(b));
int cmp = strcmp(a, b);
if (cmp < 0) printf("Alphabetically first: %s\n", a);
else if (cmp > 0) printf("Alphabetically first: %s\n", b);
else printf("They are in the same position\n");
printf("Same word: %s\n", cmp == 0 ? "Yes" : "No");
return 0;
}
Grade Calculator
Read 5 exam scores (0β100). Calculate the average, assign a letter grade, and count passed/failed subjects. Passing score is 50.
Letter grades: 90+ AA, 80+ BA, 70+ BB, 60+ CB, 50+ CC, below β FF
Input : 75 88 42 95 60
Output:
Average: 72.00
Grade : BB
Passed : 4
Failed : 1
---
#include <stdio.h>
int main() {
int scores[5], i, passed = 0;
float total = 0, avg;
for (i = 0; i < 5; i++) {
printf("Score %d: ", i+1);
scanf("%d", &scores[i]);
total += scores[i];
if (scores[i] >= 50) passed++;
}
avg = total / 5;
printf("Average: %.2f\n", avg);
if (avg >= 90) printf("Grade: AA\n");
else if (avg >= 80) printf("Grade: BA\n");
else if (avg >= 70) printf("Grade: BB\n");
else if (avg >= 60) printf("Grade: CB\n");
else if (avg >= 50) printf("Grade: CC\n");
else printf("Grade: FF\n");
printf("Passed: %d\nFailed: %d\n", passed, 5 - passed);
return 0;
}
Reverse a String In-Place
Read a word. Write a function that reverses it in-place using pointer parameters β no extra array. Print the original and the reversed version.
Input : programming
Output:
Original : programming
Reversed : gnimmargorp
---
#include <stdio.h>
#include <string.h>
void reverse(char *s) {
char *start = s;
char *end = s + strlen(s) - 1;
char tmp;
while (start < end) {
tmp = *start;
start = end;
*end = tmp;
start++;
end--;
}
}
int main() {
char word[100];
printf("Word: ");
scanf("%s", word);
printf("Original : %s\n", word);
reverse(word);
printf("Reversed : %s\n", word);
return 0;
}
Product Inventory with Struct
Define a struct for a product: name, price, and stock. Read 4 products. Calculate the total inventory value (price Γ stock), find the most expensive product, and list any with stock below 5.
Output:
Total value : 694.50
Most expensive : Cheese (45.00)
Low stock (<5) :
Milk (3)
Yogurt (4)
---
#include <stdio.h>
typedef struct {
char name[30];
float price;
int stock;
} Product;
int main() {
Product p[4];
int i, maxIdx = 0;
float total = 0;
for (i = 0; i < 4; i++) {
printf("\nName : "); scanf("%s", p[i].name);
printf("Price : "); scanf("%f", &p[i].price);
printf("Stock : "); scanf("%d", &p[i].stock);
total += p[i].price * p[i].stock;
if (p[i].price > p[maxIdx].price) maxIdx = i;
}
printf("\nTotal value : %.2f\n", total);
printf("Most expensive : %s (%.2f)\n", p[maxIdx].name, p[maxIdx].price);
printf("Low stock (<5) :\n");
for (i = 0; i < 4; i++)
if (p[i].stock < 5)
printf(" %s (%d)\n", p[i].name, p[i].stock);
return 0;
}
Min & Max via Pointer Return
Read 6 integers into an array. Write two functions β int* find_max(int arr, int n) and int find_min(int *arr, int n) β each returning a pointer to the target element. Print the values and their index positions.
Input : 4 9 2 7 1 6
Output:
Max: 9 (index 1)
Min: 1 (index 4)
---
#include <stdio.h>
int* find_max(int *a, int n) {
int *m = a;
for (int i = 1; i < n; i++)
if (*(a+i) > *m) m = a+i;
return m;
}
int* find_min(int *a, int n) {
int *m = a;
for (int i = 1; i < n; i++)
if (*(a+i) < *m) m = a+i;
return m;
}
int main() {
int arr[6], i;
for (i = 0; i < 6; i++) {
printf("Number %d: ", i+1);
scanf("%d", &arr[i]);
}
int *mx = find_max(arr, 6);
int *mn = find_min(arr, 6);
printf("Max: %d (index %ld)\n", *mx, mx - arr);
printf("Min: %d (index %ld)\n", *mn, mn - arr);
return 0;
}
Traffic Light with Enum & Switch
Define an enum for three traffic light colors. The user picks one (1/2/3). Print what the light means and what comes next.
Input : 2
Output:
Meaning : Prepare
Next : Green
---
#include <stdio.h>
typedef enum { RED=1, YELLOW, GREEN } Light;
int main() {
int choice;
printf("1-Red 2-Yellow 3-Green\nChoice: ");
scanf("%d", &choice);
Light l = (Light)choice;
const char meaning, next;
switch (l) {
case RED: meaning="Stop"; next="Yellow"; break;
case YELLOW: meaning="Prepare"; next="Green"; break;
case GREEN: meaning="Go"; next="Red"; break;
default: meaning="Invalid"; next="-";
}
printf("Meaning : %s\n", meaning);
printf("Next : %s\n", next);
return 0;
}
Matrix Transpose with Pointer Arithmetic
Read a 3Γ3 matrix. Compute its transpose. Use pointer arithmetic syntax ((A+i)+j) in your loops β no plain bracket notation inside the loops.
Input: Output (Transpose):
1 2 3 1 4 7
4 5 6 2 5 8
7 8 9 3 6 9
---
#include <stdio.h>
int main() {
int A[3][3], T[3][3], i, j;
printf("Enter 3x3 matrix (row by row):\n");
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++)
scanf("%d", *(A+i)+j);
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++)
T[j][i] = A[i][j];
printf("\nOriginal:\n");
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) printf("%3d", ((A+i)+j));
printf("\n");
}
printf("\nTranspose:\n");
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) printf("%3d", T[i][j]);
printf("\n");
}
return 0;
}
Palindrome Check with Two Pointers
Read a word. Write a function that checks if it's a palindrome using two pointers walking inward from both ends. The check must be case-insensitive.
Input: Kayak β Palindrome!
Input: Elma β Not a palindrome.
---
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int is_palindrome(char *s) {
char *left = s;
char *right = s + strlen(s) - 1;
while (left < right) {
if (tolower(*left) != tolower(*right)) return 0;
left++;
right--;
}
return 1;
}
int main() {
char word[100];
printf("Word: ");
scanf("%s", word);
if (is_palindrome(word))
printf("Palindrome!\n");
else
printf("Not a palindrome.\n");
return 0;
}
IP Address Packing with Union
Define a union that stores 4 bytes as both an unsigned int and a 4-element unsigned char array. Read an IPv4 address, store each octet in the char array, print the packed integer value, then reconstruct the IP from it.
Input : 192.168.1.1
Output:
Packed : 16885952
Unpacked: 192.168.1.1
---
#include <stdio.h>
union IP {
unsigned int packed;
unsigned char octet[4];
};
int main() {
union IP ip;
int a, b, c, d;
printf("IP address (a.b.c.d): ");
scanf("%d.%d.%d.%d", &a, &b, &c, &d);
ip.octet[0] = (unsigned char)a;
ip.octet[1] = (unsigned char)b;
ip.octet[2] = (unsigned char)c;
ip.octet[3] = (unsigned char)d;
printf("Packed : %u\n", ip.packed);
printf("Unpacked: %d.%d.%d.%d\n",
ip.octet[0], ip.octet[1],
ip.octet[2], ip.octet[3]);
return 0;
}
Fibonacci β Iterative vs Recursive
Write two functions to compute the Nth Fibonacci number: one iterative, one recursive. Read N (1β20), validate the range, print both results and how many steps/calls each method used.
N: 10
Output:
Iterative : 55 (9 steps)
Recursive : 55 (109 calls)
---
#include <stdio.h>
int call_count = 0;
long rec_fib(int n) {
call_count++;
if (n <= 1) return n;
return rec_fib(n-1) + rec_fib(n-2);
}
long iter_fib(int n, int *steps) {
if (n <= 1) { *steps = 0; return n; }
long a = 0, b = 1, c;
*steps = 0;
for (int i = 2; i <= n; i++) {
c = a + b; a = b; b = c;
(*steps)++;
}
return b;
}
int main() {
int n, steps;
printf("N (1-20): ");
scanf("%d", &n);
if (n < 1 || n > 20) {
printf("Invalid range!\n");
return 1;
}
long it = iter_fib(n, &steps);
long rec = rec_fib(n);
printf("Iterative : %ld (%d steps)\n", it, steps);
printf("Recursive : %ld (%d calls)\n", rec, call_count);
return 0;
}
Student Records β Struct + Pointer + Conditional
Define a student struct with a name and 3 exam scores. Write a function that receives a pointer, computes the average, assigns the letter grade, and flags students needing a resit (average below 60). Run for 5 students, then list only those who need a resit.
Output:
Students needing resit:
- Ahmet (Avg: 45.00 | FF)
---
#include <stdio.h>
#include <string.h>
typedef struct {
char name[30];
float s1, s2, s3;
float avg;
char grade[3];
int resit;
} Student;
void evaluate(Student *s) {
s->avg = (s->s1 + s->s2 + s->s3) / 3.0f;
if (s->avg >= 90) strcpy(s->grade, "AA");
else if (s->avg >= 80) strcpy(s->grade, "BA");
else if (s->avg >= 70) strcpy(s->grade, "BB");
else if (s->avg >= 60) strcpy(s->grade, "CB");
else strcpy(s->grade, "FF");
s->resit = (s->avg < 60) ? 1 : 0;
}
int main() {
Student students[5];
int i;
for (i = 0; i < 5; i++) {
printf("\n--- Student %d ---\n", i+1);
printf("Name : "); scanf("%s", students[i].name);
printf("Exam 1: "); scanf("%f", &students[i].s1);
printf("Exam 2: "); scanf("%f", &students[i].s2);
printf("Exam 3: "); scanf("%f", &students[i].s3);
evaluate(&students[i]);
printf("Avg: %.2f Grade: %s\n",
students[i].avg, students[i].grade);
}
printf("\nStudents needing resit:\n");
int any = 0;
for (i = 0; i < 5; i++) {
if (students[i].resit) {
printf(" - %s (Avg: %.2f | %s)\n",
students[i].name,
students[i].avg,
students[i].grade);
any++;
}
}
if (!any) printf(" None\n");
return 0;
}
That's all 15. If you got through the hard section without peeking at the answers, you have a solid foundation in C. If you did peek β that's fine too. Reading good code is also learning.
The next step is writing your own problems. Take any exercise above, change the constraints, and solve it again. That's how the concepts stick.
Good luck. π₯οΈ