FREE ONLINE INTERMEDIATE C TUTORIALS
40 Intermediate C Tutorials

40 Intermediate C Tutorials

1. Basic Pointers

Pointers store memory addresses for direct data access.

Example: Use a pointer to modify a variable.

#include 
int main() {
int x = 10, *p = &x;
*p = 20;
printf("Value: %d\n", x);
return 0;
}

Value: 20

Note: Use & for address, * for dereference.

2. Pointer to Array

Pointers can access array elements efficiently.

Example: Iterate array using a pointer.

#include 
int main() {
int arr[] = {1, 2, 3};
int *p = arr;
for (int i = 0; i < 3; i++) printf("%d ", *(p + i));
printf("\n");
return 0;
}

1 2 3

Note: Array name is a pointer to first element.

3. Dynamic Memory

Allocate memory at runtime with malloc.

Example: Allocate and use an array.

#include 
#include 
int main() {
int *arr = (int*)malloc(3 * sizeof(int));
arr[0] = 1; arr[1] = 2; arr[2] = 3;
printf("%d %d %d\n", arr[0], arr[1], arr[2]);
free(arr);
return 0;
}

1 2 3

Note: Always free allocated memory.

4. String Handling

Manipulate strings using standard library functions.

Example: Copy and concatenate strings.

#include 
#include 
int main() {
char s1[20] = "Hello", s2[10] = "World";
strcat(s1, s2);
printf("String: %s\n", s1);
return 0;
}

String: HelloWorld

Note: Include . Ensure buffer size.

5. Structures

Group related data using structs.

Example: Define and use a struct.

#include 
struct Point { int x, y; };
int main() {
struct Point p = {3, 4};
printf("Point: (%d, %d)\n", p.x, p.y);
return 0;
}

Point: (3, 4)

Note: Access fields with dot operator.

6. File Writing

Write data to files using FILE pointers.

Example: Write text to a file.

#include 
int main() {
FILE *f = fopen("output.txt", "w");
fprintf(f, "Hello, File!\n");
fclose(f);
printf("Written to file\n");
return 0;
}

Written to file

Note: Use "w" mode. Always close files.

7. File Reading

Read data from files using FILE pointers.

Example: Read text from a file.

#include 
int main() {
FILE *f = fopen("input.txt", "r");
char buffer[20];
fgets(buffer, 20, f);
printf("Read: %s", buffer);
fclose(f);
return 0;
}

Read: [file content]

Note: Use "r" mode. Check file existence.

8. Function Pointers

Store function addresses for dynamic calls.

Example: Call function via pointer.

#include 
int add(int a, int b) { return a + b; }
int main() {
int (*p)(int, int) = add;
printf("Sum: %d\n", p(2, 3));
return 0;
}

Sum: 5

Note: Match function signature.

9. Arrays of Pointers

Store multiple pointers in an array.

Example: Array of string pointers.

#include 
int main() {
char *arr[] = {"Hello", "World"};
printf("%s %s\n", arr[0], arr[1]);
return 0;
}

Hello World

Note: Useful for dynamic data.

10. Linked List

Dynamic structure with linked nodes.

Example: Create and print list.

#include 
#include 
struct Node { int data; struct Node* next; };
int main() {
struct Node* head = (struct Node*)malloc(sizeof(struct Node));
head->data = 1; head->next = NULL;
printf("%d\n", head->data);
free(head);
return 0;
}

1

Note: Free nodes to avoid leaks.

11. Stack Array

LIFO structure using an array.

Example: Push and pop elements.

#include 
#define MAX 3
int stack[MAX], top = -1;
void push(int v) { if (top < MAX-1) stack[++top] = v; }
int main() {
push(1);
printf("Popped: %d\n", stack[top--]);
return 0;
}

Popped: 1

Note: Check for overflow/underflow.

12. Queue Array

FIFO structure using an array.

Example: Enqueue and dequeue.

#include 
#define MAX 3
int queue[MAX], front = 0, rear = -1;
void enqueue(int v) { if (rear < MAX-1) queue[++rear] = v; }
int main() {
enqueue(1);
printf("Dequeued: %d\n", queue[front++]);
return 0;
}

Dequeued: 1

Note: Handle full/empty conditions.

13. Struct Pointers

Use pointers to access struct fields.

Example: Modify struct via pointer.

#include 
struct Point { int x, y; };
int main() {
struct Point p = {1, 2}, *ptr = &p;
ptr->x = 3;
printf("X: %d\n", p.x);
return 0;
}

X: 3

Note: Use -> for pointer access.

14. Dynamic Strings

Allocate strings dynamically with malloc.

Example: Create dynamic string.

#include 
#include 
#include 
int main() {
char *s = (char*)malloc(10 * sizeof(char));
strcpy(s, "Hello");
printf("%s\n", s);
free(s);
return 0;
}

Hello

Note: Include . Free memory.

15. Command Line Args

Access program arguments via main.

Example: Print arguments.

#include 
int main(int argc, char *argv[]) {
for (int i = 0; i < argc; i++) {
printf("Arg %d: %s\n", i, argv[i]);
}
return 0;
}

Arg 0: program
Arg 1: test

Note: argv[0] is program name.

16. Error Handling

Check for errors in file operations.

Example: Handle file open error.

#include 
int main() {
FILE *f = fopen("no.txt", "r");
if (!f) printf("File not found\n");
else fclose(f);
return 0;
}

File not found

Note: Check pointers for NULL.

17. Binary Files

Read/write raw data to files.

Example: Write/read integer.

#include 
int main() {
int x = 42;
FILE *f = fopen("data.bin", "wb");
fwrite(&x, sizeof(int), 1, f);
fclose(f);
f = fopen("data.bin", "rb");
fread(&x, sizeof(int), 1, f);
printf("Value: %d\n", x);
fclose(f);
return 0;
}

Value: 42

Note: Use "wb"/"rb" modes.

18. Enum Types

Define named integer constants.

Example: Use enums for states.

#include 
enum State { OFF, ON };
int main() {
enum State s = ON;
printf("State: %d\n", s);
return 0;
}

State: 1

Note: Enums improve code readability.

19. Union Types

Store different types in same memory.

Example: Use union for int/char.

#include 
union Data { int i; char c; };
int main() {
union Data d;
d.i = 65;
printf("Char: %c\n", d.c);
return 0;
}

Char: A

Note: Shares memory; use one field at a time.

20. Recursion

Functions that call themselves.

Example: Calculate factorial.

#include 
int factorial(int n) {
if (n <= 1) return 1;
return n * factorial(n - 1);
}
int main() {
printf("Factorial 5: %d\n", factorial(5));
return 0;
}

Factorial 5: 120

Note: Ensure base case to avoid stack overflow.

21. String Tokenizing

Split strings into tokens.

Example: Tokenize a string.

#include 
#include 
int main() {
char str[] = "A,B";
char *token = strtok(str, ",");
printf("Token: %s\n", token);
return 0;
}

Token: A

Note: strtok modifies input string.

22. Dynamic 2D Array

Allocate 2D arrays dynamically.

Example: Create 2x2 array.

#include 
#include 
int main() {
int **arr = (int**)malloc(2 * sizeof(int*));
for (int i = 0; i < 2; i++) arr[i] = (int*)malloc(2 * sizeof(int));
arr[0][0] = 1;
printf("%d\n", arr[0][0]);
for (int i = 0; i < 2; i++) free(arr[i]);
free(arr);
return 0;
}

1

Note: Free each row and array.

23. Void Pointers

Generic pointers for any data type.

Example: Use void pointer.

#include 
int main() {
int x = 10;
void *p = &x;
printf("Value: %d\n", *(int*)p);
return 0;
}

Value: 10

Note: Cast before dereferencing.

24. Const Qualifiers

Prevent modification of variables.

Example: Use const pointer.

#include 
int main() {
const int x = 10;
const int *p = &x;
printf("Value: %d\n", *p);
return 0;
}

Value: 10

Note: Const ensures read-only access.

25. Static Variables

Retain value between function calls.

Example: Count function calls.

#include 
void count() {
static int c = 0;
printf("Count: %d\n", ++c);
}
int main() {
count(); count();
return 0;
}

Count: 1
Count: 2

Note: Static retains value across calls.

26. Preprocessor Macros

Define constants or simple functions.

Example: Use macro for square.

#include 
#define SQUARE(x) ((x) * (x))
int main() {
printf("Square: %d\n", SQUARE(5));
return 0;
}

Square: 25

Note: Parentheses prevent operator issues.

27. Bitwise Operators

Manipulate bits for efficient operations.

Example: Set a bit.

#include 
int main() {
int x = 0;
x |= (1 << 2);
printf("Value: %d\n", x);
return 0;
}

Value: 4

Note: Use <<, |, & for bit operations.

28. File Positioning

Move file pointer for specific access.

Example: Seek and read.

#include 
int main() {
FILE *f = fopen("input.txt", "r");
fseek(f, 2, SEEK_SET);
char c = fgetc(f);
printf("Char: %c\n", c);
fclose(f);
return 0;
}

Char: [third char]

Note: Use SEEK_SET, SEEK_CUR, SEEK_END.

29. Array Sorting

Sort arrays using standard library.

Example: Sort integers.

#include 
#include 
int cmp(const void *a, const void *b) { return (*(int*)a - *(int*)b); }
int main() {
int arr[] = {3, 1, 2};
qsort(arr, 3, sizeof(int), cmp);
printf("%d %d %d\n", arr[0], arr[1], arr[2]);
return 0;
}

1 2 3

Note: Define comparison function.

30. Linked List Insert

Insert nodes into linked list.

Example: Insert at head.

#include 
#include 
struct Node { int data; struct Node* next; };
int main() {
struct Node* head = (struct Node*)malloc(sizeof(struct Node));
head->data = 2; head->next = NULL;
struct Node* new = (struct Node*)malloc(sizeof(struct Node));
new->data = 1; new->next = head;
printf("%d\n", new->data);
free(new); free(head);
return 0;
}

1

Note: Update pointers carefully.

31. Struct Arrays

Store multiple structs in an array.

Example: Array of structs.

#include 
struct Point { int x, y; };
int main() {
struct Point arr[2] = {{1, 2}, {3, 4}};
printf("Point 0: (%d, %d)\n", arr[0].x, arr[0].y);
return 0;
}

Point 0: (1, 2)

Note: Access with index and dot.

32. String Formatting

Format strings with sprintf.

Example: Create formatted string.

#include 
int main() {
char buffer[20];
int x = 42;
sprintf(buffer, "Value: %d", x);
printf("%s\n", buffer);
return 0;
}

Value: 42

Note: Ensure buffer size is sufficient.

33. Pass by Reference

Modify variables using pointers.

Example: Swap two numbers.

#include 
void swap(int *a, int *b) {
int temp = *a; *a = *b; *b = temp;
}
int main() {
int x = 1, y = 2;
swap(&x, &y);
printf("%d %d\n", x, y);
return 0;
}

2 1

Note: Use pointers for modification.

34. Dynamic Memory Free

Properly free allocated memory.

Example: Allocate and free.

#include 
#include 
int main() {
int *p = (int*)malloc(sizeof(int));
*p = 10;
printf("Value: %d\n", *p);
free(p);
return 0;
}

Value: 10

Note: Avoid dangling pointers.

35. Simple Stack

Implement stack with dynamic memory.

Example: Push to stack.

#include 
#include 
struct Stack { int *data; int top; };
int main() {
struct Stack s = {(int*)malloc(2 * sizeof(int)), -1};
s.data[++s.top] = 1;
printf("Top: %d\n", s.data[s.top]);
free(s.data);
return 0;
}

Top: 1

Note: Manage stack size dynamically.

36. Simple Queue

Implement queue with dynamic memory.

Example: Enqueue and dequeue.

#include 
#include 
struct Queue { int *data; int front, rear; };
int main() {
struct Queue q = {(int*)malloc(2 * sizeof(int)), 0, -1};
q.data[++q.rear] = 1;
printf("Dequeued: %d\n", q.data[q.front++]);
free(q.data);
return 0;
}

Dequeued: 1

Note: Track front and rear indices.

37. Nested Structures

Structures containing other structures.

Example: Nested struct access.

#include 
struct Point { int x, y; };
struct Rect { struct Point topLeft; int width; };
int main() {
struct Rect r = {{1, 2}, 10};
printf("X: %d\n", r.topLeft.x);
return 0;
}

X: 1

Note: Use dot for nested access.

38. Array of Functions

Store function pointers in array.

Example: Call functions dynamically.

#include 
int add(int a) { return a + 1; }
int main() {
int (*funcs[1])(int) = {add};
printf("Result: %d\n", funcs[0](5));
return 0;
}

Result: 6

Note: Match function signatures.

39. File Append

Add data to existing file.

Example: Append text.

#include 
int main() {
FILE *f = fopen("output.txt", "a");
fprintf(f, "More text\n");
fclose(f);
printf("Appended\n");
return 0;
}

Appended

Note: Use "a" mode for append.

40. Basic Binary Tree

Tree with left and right nodes.

Example: Create simple tree.

#include 
#include 
struct Node { int data; struct Node *left, *right; };
int main() {
struct Node* root = (struct Node*)malloc(sizeof(struct Node));
root->data = 1; root->left = root->right = NULL;
printf("Root: %d\n", root->data);
free(root);
return 0;
}

Root: 1

Note: Free nodes to avoid leaks.

Leave a Reply

Your email address will not be published. Required fields are marked *


Macro Nepal Helper