C1 ASSIGNMENT1 (OPERATING SYSTEM) IEC2021086 LATANSHU VARSHNEY Q1. What is the difference between pointers and array in C? Explain it. Ans1. In C, arrays and pointers are closely related concepts but have some important differences: Arrays: An array is a collection of elements of the same data type stored in contiguous memory locations. The array name represents the address of the first element in memory and can be used to access all elements of the array by indexing. Pointers: A pointer is a variable that stores the memory address of another variable. Pointers allow you to dynamically allocate memory and modify the data stored at a memory address. Pointers can be used to access individual elements of an array, but they can also be used to dynamically allocate memory and manipulate other data structures. In summary, arrays provide a way to organize and access data in contiguous memory locations, while pointers provide a way to dynamically manipulate memory. Q2. Explain each of these algorithms with computational complexity. Also, write a C program using pointer and swap operation for following algorithms. a) Bubble sort b) Merge sort c) Insertion sort d) Quicksort e) Heap sort g) Selection sort Ans2. a) void Bubblesort(int *a, int n){ for(int i=0; i<n; i++){ for(int j=i+1; j<n; j++){ if(a[i]>a[j]){ int temp = a[j]; a[j] = a[i]; a[i] = temp; } } } } b) void merge(int *a, int l, int mid, int r){ int left_size = mid - l + 1; int right_size = r - (mid+1) + 1; int L[left_size], R[right_size]; for(int i=0; i<left_size; i++){ L[i] = a[i+l]; } for(int i=0; i<right_size; i++){ R[i] = a[i+mid+1]; } int left_index = 0, right_index = 0; int i=l; while(left_index<left_size && right_index<right_size){ if(L[left_index]<R[right_index]){ a[i++] = L[left_index++]; } else{ a[i++] = R[right_index++]; } } while(left_index<left_size){ a[i++] = L[left_index++]; } while(right_index<right_size){ a[i++] = R[right_index++]; } } void Mergesort(int *a, int l, int r){ if(l==r){ return; } int mid = (l+r)/2; Mergesort(a, l, mid); Mergesort(a, mid+1, r); merge(a, l, mid, r); } c) void Insertionsort(int *a, int n){ for(int i=1; i<n; i++){ int x = a[i]; int j = i-1; while(j>=0 && a[j]>x){ a[j+1] = a[j]; j--; } a[j+1] = x; } } d) int partitionindex(int *a, int start, int end){ int partition_index = 0; int pivot = a[end]; for(int i=0; i<end; i++){ if(a[i]<=pivot){ swap(a[i], a[partition_index]); partition_index++; } } swap(a[partition_index], a[end]); return partition_index; } void QuickSort(int *a, int start, int end){ if(start<end){ int partition_index = partitionindex(a, start, end); QuickSort(a, start, partition_index-1); QuickSort(a, partition_index+1, end); } } e) void heapify(int *arr, int n, int i) { int largest = i; int left = 2*i + 1; int right = 2*i + 2; if (left < n && arr[left] > arr[largest]){ largest = left; } if (right < n && arr[right] > arr[largest]){ largest = right; } if (largest != i) { swap(arr[i], arr[largest]); heapify(arr, n, largest); } } void heapSort(int *arr, int n) { for (int i = n / 2 - 1; i >= 0; i--){ heapify(arr, n, i); } for (int i = n-1; i >= 0; i--) { swap(arr[0], arr[i]); heapify(arr, i, 0); } } f) void selectionSort(int *arr, int n) { int i, j, minIndex, temp; for (i = 0; i < n-1; i++) { minIndex = i; for (j = i+1; j < n; j++) { if (arr[j] < arr[minIndex]) { minIndex = j; } } temp = arr[minIndex]; arr[minIndex] = arr[i]; arr[i] = temp; } } Q3. Explain use functions in C Program? Use function operation and write C program for Dijkstra’s algorithm. Ans3. Functions in C are reusable blocks of code that perform a specific task. They can take inputs in the form of parameters and return a value as output. Functions help to organize the code and make it more readable, modular and maintainable. Return_datatype function(parameters){ operations return statement } Regarding the Dijkstra's algorithm, here's a simple implementation in C: #include <stdio.h> #include <stdlib.h> #include <limits.h> #define MAX 1000 #define NOT_A_VERTEX -1 int n; // number of vertices int d[MAX]; // shortest distances int v[MAX]; // if the shortest distance is final int g[MAX][MAX]; // graph int min_distance() { int min_d = INT_MAX; int min_v = NOT_A_VERTEX; for (int i = 0; i < n; i++) { if (v[i] == 0 && d[i] < min_d) { min_d = d[i]; min_v = i; } } return min_v; } void dijkstra(int start) { for (int i = 0; i < n; i++) { d[i] = INT_MAX; v[i] = 0; } d[start] = 0; for (int i = 0; i < n - 1; i++) { int u = min_distance(); if (u == NOT_A_VERTEX) break; v[u] = 1; for (int j = 0; j < n; j++) { if (!v[j] && g[u][j] && d[u] != INT_MAX && d[u] + g[u][j] < d[j]) { d[j] = d[u] + g[u][j]; } } } } int main() { // Read input values scanf("%d", &n); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { scanf("%d", &g[i][j]); } } dijkstra(0); // 0 is the start vertex // Print the shortest distances for (int i = 0; i < n; i++) { printf("%d ", d[i]); } printf("\n"); return 0; } Q4. Explain the structure in the C program? Suppose you are working for Amazon and you want to use the structure operation of a C program, then how will you use it? Explain this with an example. Ans4. A structure in C is a composite data type that groups together variables of different data types under a single name. Structures can be used to represent complex data such as records, objects, or nodes in a data structure. Here's an example of how you might use a structure in a C program while working at Amazon: #include <stdio.h> struct product { int id; char name[50]; float price; }; int main() { struct product p1; p1.id = 1001; strcpy(p1.name, "Kindle"); p1.price = 89.99; printf("Product ID: %d\n", p1.id); printf("Product Name: %s\n", p1.name); printf("Product Price: $%.2f\n", p1.price); return 0; } In this example, we defined a structure named product with three members: an int named id, a char array named name, and a float named price. We then created a variable p1 of type struct product, initialized its members, and displayed their values using the printf function. Q5. Explain the file descriptors and low level input/output read and write program for the Unix system Ans5. File descriptors in Unix are integers used to identify open files in a process. The operating system uses file descriptors to access the corresponding file, and every process has access to its own set of file descriptors. Low-level input/output in Unix is performed through the read() and write() system calls. These system calls allow a process to read from or write to an open file represented by a file descriptor. The read() call takes the file descriptor, a buffer, and the number of bytes to read as arguments and returns the number of bytes actually read. The write() call takes the file descriptor, a buffer, and the number of bytes to write as arguments and returns the number of bytes actually written.