40 Basic C Tutorials

40 Basic C Tutorials

1. Hello World Program

The "Hello World" program introduces the basic structure of a C program, printing a message to the console.

Example: Printing "Hello, World!"

#include 
int main() {
printf("Hello, World!\n");
return 0;
}

Hello, World!

Note: main() is the entry point. printf() outputs text, and \n adds a newline. Always include stdio.h for I/O.

2. Variables and Data Types

Variables store data, with types like int, float, double, and char defining the kind of data.

Example: Declaring and printing variables.

#include 
int main() {
int age = 25;
float height = 5.9;
char initial = 'A';
printf("Age: %d, Height: %.1f, Initial: %c\n", age, height, initial);
return 0;
}

Age: 25, Height: 5.9, Initial: A

Note: Use %d for int, %f for float, %c for char. Variables must be declared before use.

3. Basic Input/Output

C uses printf() for output and scanf() for input to interact with the user.

Example: Reading and printing a name.

#include 
int main() {
char name[50];
printf("Enter your name: ");
scanf("%s", name);
printf("Hello, %s!\n", name);
return 0;
}

Enter your name: Alice
Hello, Alice!

Note: scanf() uses & for non-array variables. %s is for strings. Avoid spaces in scanf() for single words.

4. Arithmetic Operations

C supports arithmetic operations like addition, subtraction, multiplication, and division.

Example: Basic arithmetic calculations.

#include 
int main() {
int a = 10, b = 4;
printf("Sum: %d\n", a + b);
printf("Difference: %d\n", a - b);
printf("Product: %d\n", a * b);
printf("Quotient: %d\n", a / b);
return 0;
}

Sum: 14
Difference: 6
Product: 40
Quotient: 2

Note: Integer division truncates decimals. Use float for precise division results.

5. If-Else Statements

If-else statements execute code based on whether a condition is true or false.

Example: Checking if a number is even.

#include 
int main() {
int num = 6;
if (num % 2 == 0) {
printf("Number is even.\n");
} else {
printf("Number is odd.\n");
}
return 0;
}

Number is even.

Note: Use curly braces for multiple statements. else is optional but useful for alternatives.

6. Switch Case

Switch case selects one of multiple code blocks based on a variable’s value.

Example: Displaying a day of the week.

#include 
int main() {
int day = 2;
switch (day) {
case 1:
printf("Monday\n");
break;
case 2:
printf("Tuesday\n");
break;
default:
printf("Other day\n");
}
return 0;
}

Tuesday

Note: break prevents fall-through. default handles unmatched cases.

7. For Loop

For loops repeat code a fixed number of times, ideal for known iterations.

Example: Printing numbers 1 to 5.

#include 
int main() {
for (int i = 1; i <= 5; i++) {
printf("%d\n", i);
}
return 0;
}

1
2
3
4
5

Note: For loop includes initialization, condition, and update. Use for counted loops.

8. While Loop

While loops repeat code as long as a condition is true.

Example: Counting from 1 to 5.

#include 
int main() {
int i = 1;
while (i <= 5) {
printf("%d\n", i);
i++;
}
return 0;
}

1
2
3
4
5

Note: Update the condition variable to avoid infinite loops. Use for unknown iteration counts.

9. Do-While Loop

Do-while loops execute at least once, then repeat if a condition is true.

Example: Printing numbers 1 to 3.

#include 
int main() {
int i = 1;
do {
printf("%d\n", i);
i++;
} while (i <= 3);
return 0;
}

1
2
3

Note: The loop body executes before checking the condition, ensuring at least one iteration.

10. Arrays

Arrays store multiple values of the same type in a contiguous memory block.

Example: Storing and printing numbers.

#include 
int main() {
int arr[] = {10, 20, 30, 40};
for (int i = 0; i < 4; i++) {
printf("%d\n", arr[i]);
}
return 0;
}

10
20
30
40

Note: Arrays have fixed sizes. Access elements using 0-based indices.

11. Strings

Strings are arrays of characters ending with a null terminator (\0).

Example: Working with strings.

#include 
#include 
int main() {
char str[] = "Hello";
printf("String: %s, Length: %lu\n", str, strlen(str));
return 0;
}

String: Hello, Length: 5

Note: Use for functions like strlen(). Strings must end with \0.

12. Functions

Functions are reusable code blocks that perform specific tasks.

Example: Function to calculate square.

#include 
int square(int num) {
return num * num;
}
int main() {
int result = square(5);
printf("Square: %d\n", result);
return 0;
}

Square: 25

Note: Declare functions before main() or use prototypes. Functions improve code reusability.

13. Pointers Basics

Pointers store memory addresses, enabling direct memory access.

Example: Using pointers to access a variable.

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

Value: 15, Address: [memory address]

Note: * declares a pointer, & gets an address, *ptr accesses the value. Use void* for printing addresses.

14. Structures

Structures group related data of different types into a single unit.

Example: Defining a student structure.

#include 
struct Student {
char name[50];
int age;
};
int main() {
struct Student s1 = {"Bob", 22};
printf("Name: %s, Age: %d\n", s1.name, s1.age);
return 0;
}

Name: Bob, Age: 22

Note: Use struct to define custom types. Access members with the dot (.) operator.

15. File Input/Output

C supports file operations using FILE pointers and functions like fopen() and fprintf().

Example: Writing and reading a file.

#include 
int main() {
FILE *file = fopen("test.txt", "w");
fprintf(file, "C Programming");
fclose(file);
file = fopen("test.txt", "r");
char buffer[50];
fgets(buffer, 50, file);
printf("File content: %s\n", buffer);
fclose(file);
return 0;
}

File content: C Programming

Note: Use "w" for writing, "r" for reading. Always close files with fclose().

16. Dynamic Memory Allocation

Dynamic memory allocation uses malloc() and free() for flexible memory management.

Example: Allocating memory for an array.

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

Array: 5, 10, 15

Note: Always free allocated memory to prevent leaks. Include for malloc().

17. Preprocessor Directives

Preprocessor directives like #define and #include control code before compilation.

Example: Using #define for a constant.

#include 
#define MAX 100
int main() {
printf("Maximum value: %d\n", MAX);
return 0;
}

Maximum value: 100

Note: #define creates constants or macros. #include imports libraries like stdio.h.

18. Command Line Arguments

Command line arguments pass data to a program at runtime.

Example: Printing arguments.

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

Argument count: 2
Arg 0: program
Arg 1: test

Note: argc is the argument count, argv is an array of strings. argv[0] is the program name.

19. Enum Types

Enums define named integer constants for better code readability.

Example: Using enums for colors.

#include 
enum Color {RED, GREEN, BLUE};
int main() {
enum Color c = GREEN;
printf("Color value: %d\n", c);
return 0;
}

Color value: 1

Note: Enums assign integers starting from 0. Use for related constants like states or options.

20. Simple Calculator Project

A calculator project combines input, arithmetic, and control flow for basic operations.

Example: Calculator with user input.

#include 
int main() {
double a, b;
char op;
printf("Enter two numbers: ");
scanf("%lf %lf", &a, &b);
printf("Enter operator (+, -, *, /): ");
scanf(" %c", &op);
switch (op) {
case '+': printf("Result: %.2f\n", a + b); break;
case '-': printf("Result: %.2f\n", a - b); break;
case '*': printf("Result: %.2f\n", a * b); break;
case '/': 
if (b != 0) printf("Result: %.2f\n", a / b);
else printf("Error: Division by zero!\n");
break;
default: printf("Invalid operator!\n");
}
return 0;
}

Enter two numbers: 8 2
Enter operator (+, -, *, /): *
Result: 16.00

Note: Uses scanf() for input and switch for operations. Checks for division by zero.

21. Relational Operators

Relational operators compare values, returning true (1) or false (0).

Example: Comparing numbers.

#include 
int main() {
int a = 10, b = 5;
printf("a > b: %d\n", a > b);
printf("a == b: %d\n", a == b);
printf("a <= b: %d\n", a <= b);
return 0;
}

a > b: 1
a == b: 0
a <= b: 0

Note: Operators include >, <, ==, !=, >=, <=. Use in conditions for if or loops.

22. Logical Operators

Logical operators combine conditions using AND (&&), OR (||), and NOT (!).

Example: Combining conditions.

#include 
int main() {
int a = 10, b = 5;
if (a > 0 && b < 10) {
printf("Both conditions true.\n");
}
if (a > 0 || b > 10) {
printf("At least one condition true.\n");
}
return 0;
}

Both conditions true.
At least one condition true.

Note: && requires both conditions to be true, || requires one. ! negates a condition.

23. Bitwise Operators

Bitwise operators manipulate bits of integers (e.g., &, |, ^, ~, <<, >>).

Example: Using AND and OR operators.

#include 
int main() {
int a = 5, b = 3; // 5: 0101, 3: 0011
printf("a & b: %d\n", a & b); // 0001
printf("a | b: %d\n", a | b); // 0111
return 0;
}

a & b: 1
a | b: 7

Note: & is bitwise AND, | is OR. Use for low-level bit manipulation.

24. Nested Loops

Nested loops are loops inside other loops, useful for patterns or grids.

Example: Printing a 3x3 grid of stars.

#include 
int main() {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
printf("* ");
}
printf("\n");
}
return 0;
}

* * *
* * *
* * *

Note: Outer loop controls rows, inner loop controls columns. Avoid excessive nesting for performance.

25. Multidimensional Arrays

Multidimensional arrays store data in a grid-like structure, like a matrix.

Example: 2x2 matrix.

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

1 2
3 4

Note: Use [rows][columns] for declaration. Access elements with two indices.

26. Function Pointers

Function pointers store addresses of functions, allowing dynamic function calls.

Example: Calling a function via pointer.

#include 
void greet() {
printf("Hello!\n");
}
int main() {
void (*funcPtr)() = greet;
funcPtr();
return 0;
}

Hello!

Note: Declare with return type and parameters. Useful for callbacks or dynamic behavior.

27. Recursion

Recursion occurs when a function calls itself to solve smaller instances of a problem.

Example: Calculating factorial.

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

Factorial of 5: 120

Note: Include a base case to prevent infinite recursion. Useful for problems like factorials or tree traversals.

28. String Functions

C provides string functions like strcpy() and strcat() in for manipulation.

Example: Concatenating strings.

#include 
#include 
int main() {
char str1[20] = "Hello, ";
char str2[] = "World!";
strcat(str1, str2);
printf("Concatenated: %s\n", str1);
return 0;
}

Concatenated: Hello, World!

Note: Ensure destination array has enough space. Use strcpy() for copying, strcmp() for comparison.

29. Pointer Arithmetic

Pointer arithmetic allows navigating memory addresses, useful for arrays.

Example: Traversing an array with pointers.

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

10
20
30

Note: ptr++ moves to the next element based on the data type size. Use with arrays for efficient traversal.

30. Typedef

Typedef creates aliases for data types, improving code readability.

Example: Using typedef for a structure.

#include 
typedef struct {
int id;
char name[50];
} Person;
int main() {
Person p1 = {1, "Alice"};
printf("ID: %d, Name: %s\n", p1.id, p1.name);
return 0;
}

ID: 1, Name: Alice

Note: Typedef simplifies complex type declarations. Use for structs or pointer types.

31. Unions

Unions store different data types in the same memory location, using only one at a time.

Example: Using a union.

#include 
union Data {
int i;
float f;
};
int main() {
union Data d;
d.i = 10;
printf("Integer: %d\n", d.i);
d.f = 3.14;
printf("Float: %.2f\n", d.f);
return 0;
}

Integer: 10
Float: 3.14

Note: Only one member is valid at a time. Unions save memory compared to structs.

32. Static Variables

Static variables retain their value between function calls and have file scope.

Example: Using static in a function.

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

Count: 1
Count: 2

Note: Static variables are initialized once and persist. Use for counters or shared data.

33. Break and Continue

Break exits a loop, and continue skips to the next iteration.

Example: Using break and continue.

#include 
int main() {
for (int i = 1; i <= 5; i++) {
if (i == 3) continue;
if (i == 5) break;
printf("%d\n", i);
}
return 0;
}

1
2
4

Note: continue skips the rest of the loop body, break exits the loop entirely.

34. Goto Statement

Goto jumps to a labeled statement, useful for specific control flow but often discouraged.

Example: Using goto to skip code.

#include 
int main() {
int x = 0;
if (x == 0) {
goto label;
}
printf("This won't print.\n");
label:
printf("Jumped to label.\n");
return 0;
}

Jumped to label.

Note: Use goto sparingly; loops or functions are usually better for readability.

35. Arrays and Pointers

Arrays and pointers are closely related, as an array name acts as a pointer to its first element.

Example: Accessing array elements with pointers.

#include 
int main() {
int arr[] = {1, 2, 3};
int *ptr = arr;
printf("First element: %d\n", *ptr);
printf("Second element: %d\n", *(ptr + 1));
return 0;
}

First element: 1
Second element: 2

Note: Array name is a constant pointer. Use pointer arithmetic to access elements.

36. Passing Arrays to Functions

Arrays are passed to functions as pointers, allowing modification of the original array.

Example: Summing array elements.

#include 
int sumArray(int arr[], int size) {
int sum = 0;
for (int i = 0; i < size; i++) {
sum += arr[i];
}
return sum;
}
int main() {
int arr[] = {1, 2, 3, 4};
printf("Sum: %d\n", sumArray(arr, 4));
return 0;
}

Sum: 10

Note: Pass array size explicitly, as arrays decay to pointers in functions.

37. Variable Scope

Variable scope defines where a variable is accessible (local or global).

Example: Local and global variables.

#include 
int global = 10;
int main() {
int local = 5;
printf("Global: %d, Local: %d\n", global, local);
return 0;
}

Global: 10, Local: 5

Note: Local variables are limited to their block. Global variables are accessible everywhere but use cautiously.

38. Constants

Constants are fixed values that cannot be changed during execution.

Example: Using const and #define.

#include 
#define PI 3.14
int main() {
const int MAX = 100;
printf("PI: %.2f, MAX: %d\n", PI, MAX);
return 0;
}

PI: 3.14, MAX: 100

Note: Use const for variables, #define for macros. Both prevent value changes.

39. Error Handling

Error handling in C uses return values or errno to manage errors.

Example: Checking file open errors.

#include 
int main() {
FILE *file = fopen("nonexistent.txt", "r");
if (file == NULL) {
printf("Error: File not found.\n");
} else {
printf("File opened successfully.\n");
fclose(file);
}
return 0;
}

Error: File not found.

Note: Check for NULL or errno after operations like fopen(). Use clear error messages.

40. Simple Number Guessing Game

A number guessing game combines loops, input, and conditions for an interactive program.

Example: Guessing a number between 1 and 10.

#include 
#include 
#include 
int main() {
srand(time(NULL));
int target = rand() % 10 + 1;
int guess;
printf("Guess a number (1-10): ");
scanf("%d", &guess);
while (guess != target) {
printf("Wrong! Try again: ");
scanf("%d", &guess);
}
printf("Correct! The number was %d.\n", target);
return 0;
}

Guess a number (1-10): 5
Wrong! Try again: 7
Correct! The number was 7.

Note: Uses rand() for random numbers, seeded with time(). Combines loops and input for interactivity.

Macro Nepal Helper