Skip to content

4.1 C Revision

1. Basic Syntax and Variables

Variables and Data Types

Variables are used to store data. C provides several built-in data types, such as int, char, float, double.

#include <stdio.h>
int main() {
int a = 5;
char b = 'A';
float c = 3.14f;
double d = 6.28;
printf("Integer: %d\n", a);
printf("Character: %c\n", b);
printf("Float: %.2f\n", c);
printf("Double: %.2f\n", d);
return 0;
}

Output:

Integer: 5
Character: A
Float: 3.14
Double: 6.28

2. Control Structures

If-Else Statement

The if-else statement is used to execute a block of code based on a condition.

#include <stdio.h>
int main() {
int num = 10;
if (num > 0) {
printf("Positive number\n");
} else {
printf("Non-positive number\n");
}
return 0;
}

Output:

Positive number

Switch-Case Statement

A switch statement is used to select one of many code blocks to execute based on a variable’s value.

#include <stdio.h>
int main() {
int day = 3;
switch (day) {
case 1: printf("Monday\n"); break;
case 2: printf("Tuesday\n"); break;
case 3: printf("Wednesday\n"); break;
default: printf("Invalid day\n");
}
return 0;
}

Output:

Wednesday

3. Loops

For Loop

The for loop is used for iterating a fixed number of times.

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

Output:

Iteration 0
Iteration 1
Iteration 2
Iteration 3
Iteration 4

While Loop

The while loop repeats a block of code as long as a condition is true.

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

Output:

Iteration 0
Iteration 1
Iteration 2
Iteration 3
Iteration 4

Do-While Loop

The do-while loop executes the block of code at least once before checking the condition.

#include <stdio.h>
int main() {
int i = 0;
do {
printf("Iteration %d\n", i);
i++;
} while (i < 5);
return 0;
}

Output:

Iteration 0
Iteration 1
Iteration 2
Iteration 3
Iteration 4

4. Functions

Defining and Calling Functions

Functions allow you to group code and make it reusable.

#include <stdio.h>
// Function declaration
void greet() {
printf("Hello, world!\n");
}
int main() {
greet(); // Function call
return 0;
}

Output:

Hello, world!

Function with Return Value and Parameters

Functions can also accept parameters and return a value.

#include <stdio.h>
// Function to add two integers
int add(int a, int b) {
return a + b;
}
int main() {
int sum = add(3, 4);
printf("Sum: %d\n", sum);
return 0;
}

Output:

Sum: 7

5. Pointers

Pointer Basics

Pointers store the memory address of a variable.

#include <stdio.h>
int main() {
int num = 5;
int *ptr = &num; // Pointer to the memory address of num
printf("Value of num: %d\n", num);
printf("Address of num: %p\n", &num);
printf("Value stored at ptr: %d\n", *ptr); // Dereferencing the pointer
return 0;
}

Output:

Value of num: 5
Address of num: 0x7ffee194d4a8 (This address may vary)
Value stored at ptr: 5

Pointer to Function

Pointers can also point to functions.

#include <stdio.h>
// Function to add two numbers
int add(int a, int b) {
return a + b;
}
int main() {
int (*func_ptr)(int, int) = add; // Pointer to the add function
printf("Sum: %d\n", func_ptr(3, 4)); // Call function through pointer
return 0;
}

Output:

Sum: 7

6. Arrays

Array Basics

An array stores a collection of variables of the same type.

#include <stdio.h>
int main() {
int arr[5] = {1, 2, 3, 4, 5};
for (int i = 0; i < 5; i++) {
printf("Element at index %d: %d\n", i, arr[i]);
}
return 0;
}

Output:

Element at index 0: 1
Element at index 1: 2
Element at index 2: 3
Element at index 3: 4
Element at index 4: 5

7. Structs

Structure Basics

A struct is a user-defined data type that groups different types of variables.

#include <stdio.h>
// Define a structure
struct Person {
char name[50];
int age;
};
int main() {
struct Person person1 = {"John", 30};
printf("Name: %s, Age: %d\n", person1.name, person1.age);
return 0;
}

Output:

Name: John, Age: 30

8. Dynamic Memory Allocation

malloc() and free()

malloc allocates memory at runtime, and free deallocates it.

#include <stdio.h>
#include <stdlib.h>
int main() {
int *ptr = (int *)malloc(sizeof(int)); // Allocate memory
if (ptr == NULL) {
printf("Memory allocation failed\n");
return 1;
}
*ptr = 42; // Assign value
printf("Value: %d\n", *ptr);
free(ptr); // Free allocated memory
return 0;
}

Output:

Value: 42

9. File I/O

Reading from a File

You can read from files using functions like fopen(), fscanf(), and fclose().

#include <stdio.h>
int main() {
FILE *file = fopen("example.txt", "r");
if (file == NULL) {
printf("File not found\n");
return 1;
}
char buffer[100];
while (fgets(buffer, 100, file) != NULL) {
printf("%s", buffer);
}
fclose(file);
return 0;
}

Writing to a File

To write data to a file, you can use fopen(), fprintf(), and fclose().

#include <stdio.h>
int main() {
FILE *file = fopen("example.txt", "w");
if (file == NULL) {
printf("File opening failed\n");
return 1;
}
fprintf(file, "Hello, File!\n");
fclose(file);
printf("Data written to file\n");
return 0;
}

10. Makefile

Following is a Makefile, with some new concepts with in-built variables. Here is an example of typical makefile we learned in Unix and C Programming

Terminal window
CC = gcc
CFLAGS = -g -Wall -ansi -pedantic
OBJ = main.o file1.o file2.o
EXEC = prog
$(EXEC): $(OBJ)
$(CC) -lm $(OBJ) -o $(EXEC)
main.o: main.c file1.h file2.h
$(CC) $(CFLAGS) -c main.c
file1.o: file1.c file1.h
$(CC) $(CFLAGS) -c file1.c
file2.o: file2.c file2.h
$(CC) $(CFLAGS) -c file2.c
clean:
rm $(EXEC) $(OBJ)

The next example is slightly expanded here. This one is not using any in-built variables yet, but we create more custom variables here:

Terminal window
CC = gcc
LD = gcc
CFLAGS = -g -Wall
LFLAGS = -lm
RM = /bin/rm -f
OBJ = main.o file1.o file2.o
EXEC = prog
ALL: $(EXEC)
$(EXEC): $(OBJ)
$(LD) $(LFLAGS) $(OBJ) -o $(EXEC)
main.o: main.c file1.h file2.h
$(CC) $(CFLAGS) -c main.c
file1.o: file1.c file1.h
$(CC) $(CFLAGS) -c file1.c
file2.o: file2.c file2.h
$(CC) $(CFLAGS) -c file2.c
clean:
$(RM) $(EXEC) $(OBJ)

Lastly, the next example uses some of the in-built variables:

Terminal window
CC = gcc
LD = gcc
CFLAGS = -g -Wall
LFLAGS = -lm
RM = /bin/rm -f
OBJ = main.o file1.o file2.o
EXEC = prog
$(EXEC): $(OBJ)
$(LD) $(LFLAGS) $(OBJ) -o $(EXEC)
%.o: %.c
$(CC) $(CFLAGS) -c $<
clean:
$(RM) $(EXEC) $(OBJ)