Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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
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
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