0% found this document useful (0 votes)
3 views10 pages

C Programs Exercises

The document contains C programming exercises covering various topics such as pointer arithmetic, dynamic memory management, sorting algorithms (selection, insertion, bubble, quick), searching algorithms (linear, binary), data structures (stack, queue, circular queue), postfix expression evaluation, and linked lists (singly and doubly). Each exercise includes code snippets demonstrating the implementation of the respective concepts. The exercises are designed to enhance understanding of fundamental programming techniques in C.
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)
3 views10 pages

C Programs Exercises

The document contains C programming exercises covering various topics such as pointer arithmetic, dynamic memory management, sorting algorithms (selection, insertion, bubble, quick), searching algorithms (linear, binary), data structures (stack, queue, circular queue), postfix expression evaluation, and linked lists (singly and doubly). Each exercise includes code snippets demonstrating the implementation of the respective concepts. The exercises are designed to enhance understanding of fundamental programming techniques in C.
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

C Programs: Exercises 1-15

1. Arithmetic operations on pointers


#include <stdio.h>

int main() {
int arr[] = {10, 20, 30, 40, 50};
int *p = arr; // points to arr[0]
printf("Array base address: %p\\n", (void*)arr);
printf("Pointer p points to: %p, value = %d\\n",
(void*)p, *p);

// Pointer arithmetic
p++; // next integer
printf("After p++ -> address: %p, value
= %d\\n", (void*)p, *p);

p += 2; // move two integers ahead


printf("After p += 2 -> address: %p,
value = %d\\n", (void*)p, *p);

// Difference between pointers


int *start = arr;
int diff = p -
start; // number of elements between
printf("Number of elements between p and start: %d\\n", diff);
// Access via index using pointer
printf("arr[4] via pointer: %d\\n", *(arr + 4));

return 0;
}

2. Dynamic memory management functions (malloc, calloc, realloc, free)


#include <stdio.h>
#include <stdlib.h>

int main() {
int n = 5;
int *a = (int*)malloc(n *
sizeof(int));
if (!a) { perror("malloc"); return 1; }

for (int i = 0; i < n; ++i) a[i] = (i+1) * 10;


printf("Allocated array using malloc:\\n");
for (int i = 0; i < n; ++i) printf("%d ", a[i]);
printf("\\n");

// Reallocate to larger size


n = 8;
int *b = (int*)realloc(a, n * sizeof(int));
if (!b) { perror("realloc"); free(a); return 1; }

// Initialize new elements


for (int i = 5; i < n;
++i) b[i] = (i+1) * 10;

printf("After realloc to size 8:\\n");


for (int i = 0; i < n; ++i) printf("%d
", b[i]);
printf("\\n");

// Using calloc
int m = 4;
int *c = (int*)calloc(m, sizeof(int)); //
zero-initialized
if (!c) { perror("calloc"); free(b); return 1; }
printf("Calloc array (zeros): ");
for (int i = 0; i < m; ++i) printf("%d ", c[i]);
printf("\\n");

free(b);
free(c);
return 0;
}

3. Selection sort
#include <stdio.h>

void selectionSort(int arr[], int n) {


for (int i = 0; i < n-1; ++i) {
int
min_idx = i;
for (int j = i+1; j < n; ++j)
if (arr[j] < arr[min_idx]) min_idx = j;
// swap
int tmp = arr[i]; arr[i] = arr[min_idx]; arr[min_idx] = tmp;
}
}

int main() {
int a[]
= {64, 25, 12, 22, 11};
int n = sizeof(a)/sizeof(a[0]);
selectionSort(a, n);
printf("Sorted array:
");
for (int i = 0; i < n; ++i) printf("%d ", a[i]);
printf("\\n");
return 0;
}

4. Insertion sort
#include <stdio.h>

void insertionSort(int arr[], int n) {


for (int i = 1; i < n; ++i) {
int key =
arr[i];
int j = i - 1;
while (j >= 0 && arr[j] > key) {
arr[j+1] = arr[j];
j--;
}
arr[j+1] = key;
}
}

int main() {
int a[] = {12, 11, 13, 5, 6};
int n =
sizeof(a)/sizeof(a[0]);
insertionSort(a, n);
printf("Sorted array: ");
for (int i = 0; i < n; ++i)
printf("%d ", a[i]);
printf("\\n");
return 0;
}
5. Bubble sort
#include <stdio.h>

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


for (int i = 0; i < n-1; ++i) {
int
swapped = 0;
for (int j = 0; j < n-i-1; ++j) {
if (arr[j] > arr[j+1]) {
int tmp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = tmp;
swapped = 1;
}
}
if (!swapped) break;
}
}

int main() {
int a[] = {5, 1, 4, 2, 8};
int n = sizeof(a)/sizeof(a[0]);
bubbleSort(a, n);
printf("Sorted array: ");
for (int i = 0; i < n; ++i) printf("%d ", a[i]);
printf("\\n");
return 0;
}

6. Quick sort (recursive)


#include <stdio.h>

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


int t = *a; *a = *b; *b = t;
}

int partition(int arr[],


int low, int high) {
int pivot = arr[high];
int i = low - 1;
for (int j = low; j <= high-1; ++j) {
if (arr[j] < pivot) {
++i;
swap(&arr[i], &arr[j]);
}
}
swap(&arr[i+1],
&arr[high]);
return i+1;
}

void quickSort(int arr[], int low, int high) {


if (low < high) {
int pi = partition(arr, low, high);
quickSort(arr, low, pi-1);
quickSort(arr, pi+1, high);
}
}

int main() {
int a[] = {10, 7, 8, 9, 1, 5};
int n = sizeof(a)/sizeof(a[0]);
quickSort(a, 0,
n-1);
printf("Sorted array: ");
for (int i = 0; i < n; ++i) printf("%d ", a[i]);
printf("\\n");
return 0;
}

7. Linear search
#include <stdio.h>

int linearSearch(int arr[], int n, int key) {


for (int i = 0; i < n; ++i)
if
(arr[i] == key) return i;
return -1;
}

int main() {
int a[] = {2, 3, 4, 10, 40};
int n =
sizeof(a)/sizeof(a[0]);
int key = 10;
int res = linearSearch(a, n, key);
if (res != -1)
printf("Element found at index %d\\n", res);
else printf("Element not found\\n");
return 0;
}

8. Binary search (iterative)


#include <stdio.h>

int binarySearch(int arr[], int n, int key) {


int low = 0, high = n-1;
while (low
<= high) {
int mid = low + (high - low) / 2;
if (arr[mid] == key) return mid;
else if
(arr[mid] < key) low = mid + 1;
else high = mid - 1;
}
return -1;
}

int main() {
int a[]
= {2, 3, 4, 10, 40};
int n = sizeof(a)/sizeof(a[0]);
int key = 10;
int res = binarySearch(a, n,
key);
if (res != -1) printf("Element found at index %d\\n", res);
else printf("Element not found\\n");
return 0;
}

9. Stack using arrays


#include <stdio.h>
#include <stdlib.h>
#define MAX 100

typedef struct {
int arr[MAX];
int top;
}
Stack;

void init(Stack *s) { s->top = -1; }


int isEmpty(Stack *s) { return s->top == -1; }
int isFull(Stack
*s) { return s->top == MAX-1; }

void push(Stack *s, int x) {


if (isFull(s)) { printf("Stack
overflow\\n"); return; }
s->arr[++s->top] = x;
}

int pop(Stack *s) {


if (isEmpty(s)) { printf("Stack
underflow\\n"); return -1; }
return s->arr[s->top--];
}

int peek(Stack *s) {


if (isEmpty(s)) {
printf("Stack is empty\\n"); return -1; }
return s->arr[s->top];
}

int main() {
Stack s; init(&s);
push(&s, 10); push(&s, 20); push(&s, 30);
printf("Top element: %d\\n", peek(&s));
printf("Popped:
%d\\n", pop(&s));
printf("Top after pop: %d\\n", peek(&s));
return 0;
}

10. Queue using arrays (linear queue)


#include <stdio.h>
#include <stdlib.h>
#define MAX 100

typedef struct {
int arr[MAX];
int front,
rear;
} Queue;

void init(Queue *q) { q->front = 0; q->rear = -1; }


int isEmpty(Queue *q) { return q->front >
q->rear; }
int isFull(Queue *q) { return q->rear == MAX-1; }

void enqueue(Queue *q, int x) {


if
(isFull(q)) { printf("Queue overflow\\n"); return; }
q->arr[++q->rear] = x;
}

int dequeue(Queue *q) {


if (isEmpty(q)) { printf("Queue underflow\\n"); return -1; }
return q->arr[q->front++];
}

int main() {
Queue q; init(&q);
enqueue(&q, 10); enqueue(&q, 20); enqueue(&q, 30);
printf("Dequeued: %d\\n",
dequeue(&q));
printf("Dequeued: %d\\n", dequeue(&q));
return 0;
}

11. Circular queue using arrays


#include <stdio.h>
#include <stdlib.h>
#define MAX 5

typedef struct {
int arr[MAX];
int front, rear;
int size;
} CircQueue;

void init(CircQueue *q) { q->front = 0; q->rear = -1; q->size = 0; }


int
isEmpty(CircQueue *q) { return q->size == 0; }
int isFull(CircQueue *q) { return q->size == MAX; }

void
enqueue(CircQueue *q, int x) {
if (isFull(q)) { printf("Circular Queue overflow\\n"); return; }
q->rear = (q->rear + 1) % MAX;
q->arr[q->rear] = x;
q->size++;
}

int dequeue(CircQueue *q) {


if
(isEmpty(q)) { printf("Circular Queue underflow\\n"); return -1; }
int val = q->arr[q->front];
q->front = (q->front + 1) % MAX;
q->size--;
return val;
}

int main() {
CircQueue q; init(&q);
enqueue(&q, 1); enqueue(&q, 2); enqueue(&q, 3); enqueue(&q, 4); enqueue(&q, 5);
printf("Dequeued: %d\\n",
dequeue(&q));
enqueue(&q, 6);
while (!isEmpty(&q)) printf("%d ", dequeue(&q));
printf("\\n");
return 0;
}

12. Evaluate postfix expression


#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <math.h>

#define MAX
100

typedef struct {
double st[MAX];
int top;
} Stack;

void init(Stack *s) { s->top = -1; }


void
push(Stack *s, double v) { s->st[++s->top] = v; }
double pop(Stack *s) { return s->st[s->top--]; }

double
evalPostfix(const char *expr) {
Stack s; init(&s);
int len = strlen(expr);
for (int i = 0; i <
len; ++i) {
if (expr[i] == ' ' || expr[i] == '\\t') continue;
if (isdigit(expr[i]) || (expr[i]
== '-' && isdigit(expr[i+1]))) {
char buf[64]; int k = 0;
// support multi-digit and
negative numbers
if (expr[i] == '-') buf[k++] = expr[i++];
while (i < len &&
(isdigit(expr[i]) || expr[i]=='.')) buf[k++] = expr[i++];
buf[k] = '\\0'; --i;
push(&s, atof(buf));
} else {
double b = pop(&s), a = pop(&s), r = 0;
switch
(expr[i]) {
case '+': r = a + b; break;
case '-': r = a - b; break;
case '*': r = a * b; break;
case '/': r = a / b; break;
case '^': r = pow(a,
b); break;
default: printf("Unknown operator %c\\n", expr[i]); return 0;
}
push(&s, r);
}
}
return pop(&s);
}

int main() {
const char *expr = "5 1 2 + 4 * + 3 -";
// example -> 14
printf("Postfix: %s\\n", expr);
double res = evalPostfix(expr);
printf("Result =
%g\\n", res);
return 0;
}

13. Singly linked list (insert, delete, display)


#include <stdio.h>
#include <stdlib.h>

typedef struct Node {


int data;
struct Node *next;
} Node;
Node* insertAtBeginning(Node *head, int val) {
Node *n = (Node*)malloc(sizeof(Node));
n->data = val;
n->next = head;
return n;
}

Node* deleteValue(Node *head, int val) {


Node *cur = head, *prev = NULL;
while (cur) {
if (cur->data == val) {
if (prev) prev->next = cur->next;
else
head = cur->next;
free(cur);
return head;
}
prev = cur; cur =
cur->next;
}
return head;
}

void display(Node *head) {


Node *cur = head;
while (cur) {
printf("%d -> ", cur->data); cur = cur->next; }
printf("NULL\\n");
}

int main() {
Node *head = NULL;
head = insertAtBeginning(head, 30);
head = insertAtBeginning(head, 20);
head = insertAtBeginning(head,
10);
printf("List: "); display(head);
head = deleteValue(head, 20);
printf("After deleting 20: ");
display(head);
// free remaining nodes
while (head) { Node *t = head; head = head->next; free(t); }
return 0;
}

14. Doubly linked list (insert, delete, display)


#include <stdio.h>
#include <stdlib.h>

typedef struct DNode {


int data;
struct DNode *prev, *next;
}
DNode;

DNode* insertAtFront(DNode *head, int val) {


DNode *n = (DNode*)malloc(sizeof(DNode));
n->data
= val; n->prev = NULL; n->next = head;
if (head) head->prev = n;
return n;
}

DNode* deleteValue(DNode
*head, int val) {
DNode *cur = head;
while (cur) {
if (cur->data == val) {
if
(cur->prev) cur->prev->next = cur->next;
else head = cur->next;
if (cur->next)
cur->next->prev = cur->prev;
free(cur);
return head;
}
cur =
cur->next;
}
return head;
}

void displayForward(DNode *head) {


DNode *cur = head;
while (cur)
{ printf("%d <-> ", cur->data); cur = cur->next; }
printf("NULL\\n");
}

int main() {
DNode *head =
NULL;
head = insertAtFront(head, 30);
head = insertAtFront(head, 20);
head = insertAtFront(head,
10);
printf("Doubly linked list: "); displayForward(head);
head = deleteValue(head, 20);
printf("After deleting 20: "); displayForward(head);
// free nodes
while (head) { DNode *t = head;
head = head->next; free(t); }
return 0;
}

15. Binary tree traversals (preorder, inorder, postorder)


#include <stdio.h>
#include <stdlib.h>

typedef struct TNode {


int data;
struct TNode *left, *right;
}
TNode;

TNode* newNode(int val) {


TNode *n = (TNode*)malloc(sizeof(TNode));
n->data = val; n->left =
n->right = NULL; return n;
}

void inorder(TNode *root) {


if (!root) return;
inorder(root->left);
printf("%d ", root->data);
inorder(root->right);
}

void preorder(TNode *root) {


if (!root) return;
printf("%d ", root->data);
preorder(root->left);
preorder(root->right);
}

void postorder(TNode *root)


{
if (!root) return;
postorder(root->left);
postorder(root->right);
printf("%d ", root->data);
}

int main() {
TNode *root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(4);
root->left->right = newNode(5);

printf("Preorder: "); preorder(root);


printf("\\n");
printf("Inorder: "); inorder(root); printf("\\n");
printf("Postorder: ");
postorder(root); printf("\\n");

return 0;
}

You might also like