Back to all posts
C Programming Practice: 15 Exercises from Basics to Pointers
DevelopmentJune 27, 202613 min read1 views

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."

Dennis Ritchie, creator of C

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 declarations

  • A 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. πŸ–₯️