0% found this document useful (0 votes)
2 views

Lab1 C Programs

This document presents 15 C programs aimed at teaching fundamental programming concepts, data structures, and pointers. Each program includes a description, source code, compilation instructions, and key concepts. Topics covered range from basic syntax and input/output to advanced concepts like dynamic memory allocation and data structures such as linked lists, stacks, and queues.

Uploaded by

112114006
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

Lab1 C Programs

This document presents 15 C programs aimed at teaching fundamental programming concepts, data structures, and pointers. Each program includes a description, source code, compilation instructions, and key concepts. Topics covered range from basic syntax and input/output to advanced concepts like dynamic memory allocation and data structures such as linked lists, stacks, and queues.

Uploaded by

112114006
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 14

C Programs for Learning Basics, Data Structures, and

Pointers
DS2040, Satyajit Das
January 9, 2025

1 Introduction
This document contains 15 C programs designed to help you understand fundamental C
programming concepts, basic data structures, and pointers. Each program is accompanied
by:
• A short description
• The source code
• Instructions for compilation and execution
• Key concepts

2 Programs
2.1 1. Hello World
Purpose: The classic introductory program—verifies your environment is set up and
shows basic C syntax.
Listing 1: hello.c
1 #include <stdio.h>
2

3 int main(void) {
4 printf("Hello, World!\n");
5 return 0;
6 }
Instructions:
• Compile: gcc hello.c -o hello
• Run: ./hello
Key Concepts:
• Basic structure of a C program (#include, main(), return 0;)
• Printing output to the console.

1
2.2 2. Simple Input and Output
Purpose: Demonstrates reading integers from the user and printing results.
Listing 2: simple_io.c
1 #include <stdio.h>
2

3 int main(void) {
4 int number;
5 printf("Enter an integer: ");
6 scanf("%d", &number);
7 printf("You entered: %d\n", number);
8 return 0;
9 }
Instructions:
• Compile: gcc simple_io.c -o simple_io

• Run: ./simple_io
Key Concepts:
• Using scanf() and printf().

• Relationship between format specifiers (e.g., %d) and variable types.

2.3 3. If-Else and Loops


Purpose: Illustrates conditional logic and basic loops in C.
Listing 3: control_flow.c
1 #include <stdio.h>
2

3 int main(void) {
4 int i, sum = 0;
5

6 for (i = 1; i <= 5; i++) {


7 if (i % 2 == 0) {
8 printf("%d is even\n", i);
9 } else {
10 printf("%d is odd\n", i);
11 }
12 sum += i;
13 }
14

15 printf("Sum of numbers 1 to 5 is %d\n", sum);


16 return 0;
17 }
Instructions:
• Compile: gcc control_flow.c -o control_flow

• Run: ./control_flow

2
Key Concepts:

• for loop, if statement, % operator for checking even/odd.

• Accumulating a sum in a loop.

2.4 4. Arrays and Summation


Purpose: Shows how to handle arrays, sum their elements, and print results.
Listing 4: array_sum.c
1 #include <stdio.h>
2

3 #define SIZE 5
4

5 int main(void) {
6 int arr[SIZE] = {1, 2, 3, 4, 5};
7 int sum = 0;
8

9 for (int i = 0; i < SIZE; i++) {


10 sum += arr[i];
11 }
12

13 printf("Sum of array elements = %d\n", sum);


14 return 0;
15 }
Instructions:

• Compile: gcc array_sum.c -o array_sum

• Run: ./array_sum

Key Concepts:

• Declaring and initializing arrays.

• Iterating through arrays with a loop.

• Accumulating values.

2.5 5. Pointer Basics


Purpose: Demonstrates how to use pointers to print variable addresses and values.
Listing 5: pointer_basics.c
1 #include <stdio.h>
2

3 int main(void) {
4 int x = 10;
5 int *ptr = &x; // pointer to x
6

7 printf("Value of x: %d\n", x);

3
8 printf("Address of x: %p\n", (void*)&x);
9 printf("Value of ptr: %p\n", (void*)ptr);
10 printf("Value pointed by ptr: %d\n", *ptr);
11

12 return 0;
13 }
Instructions:

• Compile: gcc pointer_basics.c -o pointer_basics

• Run: ./pointer_basics

Key Concepts:

• Declaring pointers (int *ptr).

• Dereferencing (*ptr).

• Difference between address and value.

2.6 6. Pointer Arithmetic


Purpose: Explores how incrementing pointers relates to the size of their data type.
Listing 6: pointer_arithmetic.c
1 #include <stdio.h>
2

3 int main(void) {
4 int arr[3] = {10, 20, 30};
5 int *p = arr; // points to arr[0]
6

7 printf("p points to arr[0]: value = %d\n", *p);


8 p++; // Move to arr[1]
9 printf("p now points to arr[1]: value = %d\n", *p);
10 p++; // Move to arr[2]
11 printf("p now points to arr[2]: value = %d\n", *p);
12

13 return 0;
14 }
Instructions:

• Compile: gcc pointer_arithmetic.c -o pointer_arithmetic

• Run: ./pointer_arithmetic

Key Concepts:

• Relationship between pointer increments and array indexing.

• Each increment of an int * moves sizeof(int) bytes in memory.

4
2.7 7. Swapping Values with Pointers
Purpose: Demonstrates using pointers in function calls to swap two variables.
Listing 7: swap.c
1 #include <stdio.h>
2

3 void swap(int *a, int *b) {


4 int temp = *a;
5 *a = *b;
6 *b = temp;
7 }
8

9 int main(void) {
10 int x = 5, y = 10;
11 printf("Before swap: x = %d, y = %d\n", x, y);
12 swap(&x, &y);
13 printf("After swap: x = %d, y = %d\n", x, y);
14 return 0;
15 }
Instructions:

• Compile: gcc swap.c -o swap

• Run: ./swap

Key Concepts:

• Passing addresses to a function.

• Dereferencing to modify original variables.

2.8 8. Dynamic Memory Allocation


Purpose: Explores malloc() and free() to dynamically manage memory for arrays.
Listing 8: dynamic_allocation.c
1 #include <stdio.h>
2 #include <stdlib.h>
3

4 int main(void) {
5 int n;
6 printf("Enter the number of elements: ");
7 scanf("%d", &n);
8

9 int *arr = (int *)malloc(n * sizeof(int));


10 if (arr == NULL) {
11 printf("Memory allocation failed!\n");
12 return 1;
13 }
14

15 // Store values

5
16 for (int i = 0; i < n; i++) {
17 arr[i] = i + 1;
18 }
19

20 // Print values
21 printf("Allocated array elements:\n");
22 for (int i = 0; i < n; i++) {
23 printf("%d ", arr[i]);
24 }
25 printf("\n");
26

27 free(arr); // Release the allocated memory


28 return 0;
29 }
Instructions:
• Compile: gcc dynamic_allocation.c -o dynamic_allocation

• Run: ./dynamic_allocation
Key Concepts:
• malloc() for dynamic memory allocation.

• Checking for NULL to avoid segmentation faults.

• free() to release allocated memory.

2.9 9. Structure Basics


Purpose: Shows how to define and use a struct in C.
Listing 9: structure_basics.c
1 #include <stdio.h>
2 #include <string.h>
3

4 struct Student {
5 char name[50];
6 int age;
7 };
8

9 int main(void) {
10 struct Student s1;
11

12 strcpy(s1.name, "Alice");
13 s1.age = 20;
14

15 printf("Student Name: %s, Age: %d\n", s1.name, s1.age);


16

17 return 0;
18 }
Instructions:

6
• Compile: gcc structure_basics.c -o structure_basics

• Run: ./structure_basics

Key Concepts:

• Declaring a structure.

• Accessing structure members using the dot (.) operator.

• Using library functions (strcpy) to manipulate strings within structures.

2.10 10. Singly Linked List (Insertion & Print)


Purpose: Provides a foundational data structure using pointers—linked lists.
Listing 10: linked_list.c
1 #include <stdio.h>
2 #include <stdlib.h>
3

4 struct Node {
5 int data;
6 struct Node *next;
7 };
8

9 void insertAtHead(struct Node **head, int value) {


10 struct Node *newNode = (struct Node*)malloc(sizeof(struct Node));
11 newNode->data = value;
12 newNode->next = *head;
13 *head = newNode;
14 }
15

16 void printList(struct Node *head) {


17 struct Node *current = head;
18 while (current != NULL) {
19 printf("%d -> ", current->data);
20 current = current->next;
21 }
22 printf("NULL\n");
23 }
24

25 int main(void) {
26 struct Node *head = NULL;
27

28 insertAtHead(&head, 30);
29 insertAtHead(&head, 20);
30 insertAtHead(&head, 10);
31

32 printList(head);
33 return 0;
34 }
Instructions:

7
• Compile: gcc linked_list.c -o linked_list

• Run: ./linked_list

Key Concepts:

• Dynamic allocation for nodes.

• Maintaining a head pointer to a linked list.

• Inserting new nodes at the head of the list.

2.11 11. Stack (Array Implementation)


Purpose: Implements a simple stack using an array.
Listing 11: stack_array.c
1 #include <stdio.h>
2 #include <stdlib.h>
3

4 #define MAX_SIZE 5
5

6 typedef struct {
7 int top;
8 int arr[MAX_SIZE];
9 } Stack;
10

11 void initStack(Stack *s) {


12 s->top = -1;
13 }
14

15 int isFull(Stack *s) {


16 return s->top == MAX_SIZE - 1;
17 }
18

19 int isEmpty(Stack *s) {


20 return s->top == -1;
21 }
22

23 void push(Stack *s, int value) {


24 if (isFull(s)) {
25 printf("Stack overflow!\n");
26 return;
27 }
28 s->arr[++(s->top)] = value;
29 }
30

31 int pop(Stack *s) {


32 if (isEmpty(s)) {
33 printf("Stack underflow!\n");
34 return -1;
35 }

8
36 return s->arr[(s->top)--];
37 }
38

39 int main(void) {
40 Stack myStack;
41 initStack(&myStack);
42

43 push(&myStack, 10);
44 push(&myStack, 20);
45 push(&myStack, 30);
46

47 printf("Popped: %d\n", pop(&myStack));


48 printf("Popped: %d\n", pop(&myStack));
49

50 return 0;
51 }
Instructions:

• Compile: gcc stack_array.c -o stack_array

• Run: ./stack_array

Key Concepts:

• LIFO (Last-In, First-Out) principle.

• Array-based stack with top index.

• Overflow and underflow checks.

2.12 12. Queue (Array Implementation)


Purpose: Implements a simple queue using an array.
Listing 12: queue_array.c
1 #include <stdio.h>
2 #include <stdlib.h>
3

4 #define MAX_SIZE 5
5

6 typedef struct {
7 int front, rear;
8 int arr[MAX_SIZE];
9 } Queue;
10

11 void initQueue(Queue *q) {


12 q->front = -1;
13 q->rear = -1;
14 }
15

16 int isEmpty(Queue *q) {


17 return q->front == -1;

9
18 }
19

20 int isFull(Queue *q) {


21 return (q->rear + 1) % MAX_SIZE == q->front;
22 }
23

24 void enqueue(Queue *q, int value) {


25 if (isFull(q)) {
26 printf("Queue is full!\n");
27 return;
28 }
29 if (q->front == -1)
30 q->front = 0;
31 q->rear = (q->rear + 1) % MAX_SIZE;
32 q->arr[q->rear] = value;
33 }
34

35 int dequeue(Queue *q) {


36 if (isEmpty(q)) {
37 printf("Queue is empty!\n");
38 return -1;
39 }
40 int result = q->arr[q->front];
41 if (q->front == q->rear) {
42 // Only one element
43 q->front = -1;
44 q->rear = -1;
45 } else {
46 q->front = (q->front + 1) % MAX_SIZE;
47 }
48 return result;
49 }
50

51 int main(void) {
52 Queue myQueue;
53 initQueue(&myQueue);
54

55 enqueue(&myQueue, 1);
56 enqueue(&myQueue, 2);
57 enqueue(&myQueue, 3);
58

59 printf("Dequeued: %d\n", dequeue(&myQueue));


60 printf("Dequeued: %d\n", dequeue(&myQueue));
61

62 return 0;
63 }
Instructions:

• Compile: gcc queue_array.c -o queue_array

• Run: ./queue_array

10
Key Concepts:

• FIFO (First-In, First-Out) principle.

• Circular indexing using (rear + 1) % MAX_SIZE.

• Checking for empty and full conditions.

2.13 13. Bubble Sort


Purpose: Illustrates a simple sorting algorithm operating on an array in-place.
Listing 13: bubble_sort.c
1 #include <stdio.h>
2

3 void bubbleSort(int arr[], int n) {


4 for (int i = 0; i < n - 1; i++) {
5 for (int j = 0; j < n - i - 1; j++) {
6 if (arr[j] > arr[j + 1]) {
7 // Swap
8 int temp = arr[j];
9 arr[j] = arr[j + 1];
10 arr[j + 1] = temp;
11 }
12 }
13 }
14 }
15

16 int main(void) {
17 int arr[] = {64, 34, 25, 12, 22, 11, 90};
18 int n = sizeof(arr) / sizeof(arr[0]);
19

20 printf("Original array:\n");
21 for(int i = 0; i < n; i++) {
22 printf("%d ", arr[i]);
23 }
24 printf("\n");
25

26 bubbleSort(arr, n);
27

28 printf("Sorted array:\n");
29 for(int i = 0; i < n; i++) {
30 printf("%d ", arr[i]);
31 }
32 printf("\n");
33

34 return 0;
35 }
Instructions:

• Compile: gcc bubble_sort.c -o bubble_sort

11
• Run: ./bubble_sort

Key Concepts:

• Nested loops and swapping adjacent elements.

• Time complexity: O(n2 ) average/worst case.

2.14 14. Binary Search (Iterative)


Purpose: Demonstrates searching a sorted array in O(log n) time.
Listing 14: binary_search.c
1 #include <stdio.h>
2

3 int binarySearch(int arr[], int size, int target) {


4 int low = 0;
5 int high = size - 1;
6

7 while (low <= high) {


8 int mid = (low + high) / 2;
9

10 if (arr[mid] == target) {
11 return mid;
12 } else if (arr[mid] < target) {
13 low = mid + 1;
14 } else {
15 high = mid - 1;
16 }
17 }
18 return -1;
19 }
20

21 int main(void) {
22 int arr[] = {2, 4, 6, 8, 10, 12};
23 int size = sizeof(arr) / sizeof(arr[0]);
24 int target = 8;
25

26 int result = binarySearch(arr, size, target);


27 if (result != -1) {
28 printf("Element %d found at index %d.\n", target, result);
29 } else {
30 printf("Element %d not found.\n", target);
31 }
32

33 return 0;
34 }
Instructions:

• Compile: gcc binary_search.c -o binary_search

• Run: ./binary_search

12
Key Concepts:

• Requires sorted array for correctness.

• Iterative approach to finding a target in O(log n).

2.15 15. File I/O (Read and Write)


Purpose: Demonstrates reading from and writing to a file in C.
Listing 15: file_io.c
1 #include <stdio.h>
2 #include <stdlib.h>
3

4 int main(void) {
5 FILE *fp = fopen("output.txt", "w");
6 if (fp == NULL) {
7 printf("Error opening file for writing.\n");
8 return 1;
9 }
10 fprintf(fp, "Hello, file!\n");
11 fclose(fp);
12

13 fp = fopen("output.txt", "r");
14 if (fp == NULL) {
15 printf("Error opening file for reading.\n");
16 return 1;
17 }
18

19 char buffer[100];
20 while (fgets(buffer, sizeof(buffer), fp) != NULL) {
21 printf("%s", buffer);
22 }
23 fclose(fp);
24

25 return 0;
26 }
Instructions:

1. Compile: gcc file_io.c -o file_io

2. Run: ./file_io

3. This will write "Hello, file!" to output.txt and then read it back.

Key Concepts:

• Using FILE * to handle file streams.

• fopen, fprintf, fgets, fclose.

• Error checking when opening/reading/writing files.

13
3 Tips for Running and Understanding the Programs
• Compilation: Use gcc filename.c -o outputname on Linux or macOS. On
Windows, the command is similar, though you may end up with an .exe file.

• Execution: On UNIX-like systems, run ./outputname. On Windows, run outputname.exe


or outputname.

• Experimentation: Modify values, change array sizes, or add additional printf


statements to see how behavior changes. Insert debugging printouts to trace loops
or pointer operations.

• Common Pitfalls:

– Not checking the return of malloc() for NULL.


– Off-by-one errors in loops and array indexing.
– Forgetting to free dynamically allocated memory, leading to leaks.
– Mixing scanf and fgets without clearing input buffers.

• Further Exploration:

– Explore advanced data structures (trees, graphs, hash tables).


– Implement additional sorting algorithms (insertion sort, merge sort, quicksort).
– Add error handling and input validation.
– Use debuggers like gdb to step through code line by line.

14

You might also like