0% found this document useful (0 votes)
19 views63 pages

Arrays in C Programming - A Comprehensive Guide

This document is a comprehensive guide on arrays in C programming, detailing their fundamental concepts, implementation techniques, and practical applications. It covers array declaration, initialization, memory management, and operations, including multi-dimensional arrays and dynamic memory allocation, supported by over 30 example programs. Readers will learn efficient array programming through detailed explanations and practical problem-solving approaches.

Uploaded by

Swastik Biswas
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)
19 views63 pages

Arrays in C Programming - A Comprehensive Guide

This document is a comprehensive guide on arrays in C programming, detailing their fundamental concepts, implementation techniques, and practical applications. It covers array declaration, initialization, memory management, and operations, including multi-dimensional arrays and dynamic memory allocation, supported by over 30 example programs. Readers will learn efficient array programming through detailed explanations and practical problem-solving approaches.

Uploaded by

Swastik Biswas
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/ 63

Arrays in C Programming: A

Comprehensive Guide
Abstract
This document provides an exhaustive exploration of arrays in C programming, covering
fundamental concepts, implementation techniques, memory management, and practical
applications. Arrays represent one of the most essential data structures in C, enabling
efficient storage and manipulation of collections of homogeneous data. This guide
examines array declaration, initialization, operations, multi-dimensional arrays, dynamic
memory allocation, pointer arithmetic, and common algorithms. Through detailed
explanations, code examples, and practical problem-solving approaches, readers will gain
comprehensive understanding of array programming in C. The document includes over 30
example programs demonstrating various array operations, from basic traversal to
advanced manipulation techniques including searching, sorting, merging, and matrix
operations.

1. Introduction to Arrays
1.1 What is an Array?
An array in C is a collection of elements of the same data type stored in contiguous
memory locations[1]. This fundamental data structure allows programmers to store
multiple values under a single variable name, accessible through indices. Arrays provide
efficient memory utilization and rapid element access, making them indispensable for
managing collections of data.
The concept of contiguous memory storage is crucial: when an array is declared, the
system allocates a continuous block of memory where elements are placed sequentially[2].
This arrangement enables direct access to any element using its index position, resulting in
O(1) time complexity for element retrieval.

1.2 Why Use Arrays?


Arrays offer several compelling advantages in C programming:

• Efficient Memory Management: Arrays use contiguous memory locations,


optimizing cache performance and reducing memory fragmentation[3]
• Direct Element Access: Random access capability allows retrieval of any element in
constant time using index notation
• Code Simplicity: Managing multiple related variables becomes straightforward with
a single array name rather than numerous individual variables
• Algorithm Implementation: Many fundamental algorithms (sorting, searching,
dynamic programming) rely heavily on array structures[8]
• Cache Locality: Sequential memory layout enhances CPU cache utilization,
improving performance for iterative operations[12]
1.3 Array Characteristics
Understanding array properties is essential for effective usage:
• Fixed Size: In standard C arrays, size must be determined at compile time or
declaration and cannot change during execution[3]
• Homogeneous Elements: All array elements must share the same data type (int,
float, char, etc.)
• Zero-Based Indexing: The first element is accessed at index 0, and the last at index
(size-1)
• Contiguous Storage: Elements occupy consecutive memory addresses
• Pass by Reference: When passed to functions, arrays are passed by reference
(address of first element), not by value[3]
• No Automatic Bounds Checking: C does not validate index boundaries, making out-
of-bounds access a potential source of undefined behavior[10]

2. Array Declaration and Initialization


2.1 Basic Declaration Syntax
The fundamental syntax for declaring an array in C follows this pattern:

data_type array_name[array_size];
Where:
data_type specifies the type of elements (int, float, char, double, etc.)
array_name is the identifier for the array
array_size is a constant expression indicating the number of elements

Examples:
int numbers[10]; // Array of 10 integers
float temperatures[7]; // Array of 7 floating-point values
char name[50]; // Character array (string) with 50 characters
double salaries[100]; // Array of 100 double-precision values

2.2 Array Initialization


C provides multiple methods for initializing arrays at declaration time.

2.2.1 Complete Initialization


#include <stdio.h>
int main() {
// Initialize all elements explicitly
int arr1[5] = {10, 20, 30, 40, 50};

// Size can be omitted when initializing


int arr2[] = {1, 2, 3, 4, 5, 6}; // Size automatically becomes 6
// Partial initialization (remaining elements become 0)
int arr3[10] = {1, 2, 3}; // First 3 elements initialized, rest are 0

// Initialize all elements to zero


int arr4[100] = {0}; // All elements set to 0

printf("arr1[0] = %d\n", arr1[0]);


printf("arr2 size = %lu\n", sizeof(arr2)/sizeof(arr2[0]));
printf("arr3[5] = %d\n", arr3[5]); // Prints 0

return 0;

Output:
arr1[0] = 10
arr2 size = 6
arr3[5] = 0

2.2.2 Runtime Initialization


Arrays can be populated during program execution using loops:
#include <stdio.h>
int main() {
int numbers[10];
int i;

// Initialize using a for loop


for (i = 0; i < 10; i++) {
numbers[i] = i * i; // Store squares
}

// Display array contents


printf("Square values:\n");
for (i = 0; i < 10; i++) {
printf("%d ", numbers[i]);
}
printf("\n");

return 0;
}

2.3 Memory Allocation


When an array is declared, the compiler allocates memory equal to:
Total Memory = size_of_data_type × number_of_elements

Example Memory Calculation:


#include <stdio.h>
int main() {
int arr1[10];
float arr2[5];
char arr3[20];
double arr4[8];

printf("Size of int array (10 elements): %lu bytes\n", sizeof(arr1));


printf("Size of float array (5 elements): %lu bytes\n", sizeof(arr2));
printf("Size of char array (20 elements): %lu bytes\n", sizeof(arr3));
printf("Size of double array (8 elements): %lu bytes\n", sizeof(arr4));

// Calculate number of elements


int count = sizeof(arr1) / sizeof(arr1[0]);
printf("Number of elements in arr1: %d\n", count);

return 0;

}
Output (on typical 64-bit system):
Size of int array (10 elements): 40 bytes
Size of float array (5 elements): 20 bytes
Size of char array (20 elements): 20 bytes
Size of double array (8 elements): 64 bytes
Number of elements in arr1: 10

3. Accessing and Modifying Array Elements


3.1 Array Indexing
Array elements are accessed using the subscript operator [] with the index position:
#include <stdio.h>
int main() {
int data[5] = {100, 200, 300, 400, 500};
// Accessing individual elements
printf("First element: %d\n", data[0]);
printf("Third element: %d\n", data[2]);
printf("Last element: %d\n", data[4]);

// Modifying elements
data[1] = 250; // Change second element
data[3] += 50; // Increment fourth element

printf("Modified second element: %d\n", data[1]);


printf("Modified fourth element: %d\n", data[3]);

return 0;

3.2 Array Traversal


Traversal refers to visiting each element of an array sequentially. This is fundamental for
most array operations.

3.2.1 Forward Traversal


#include <stdio.h>

int main() {
int arr[] = {5, 10, 15, 20, 25, 30};
int size = sizeof(arr) / sizeof(arr[0]);
int i;

printf("Array elements (forward): ");


for (i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");

return 0;

}
3.2.2 Reverse Traversal
#include <stdio.h>
int main() {
int arr[] = {5, 10, 15, 20, 25, 30};
int size = sizeof(arr) / sizeof(arr[0]);
int i;

printf("Array elements (backward): ");


for (i = size - 1; i >= 0; i--) {
printf("%d ", arr[i]);
}
printf("\n");

return 0;

3.3 Taking Input from User


#include <stdio.h>
int main() {
int n, i;

printf("Enter the number of elements: ");


scanf("%d", &n);

int arr[n]; // Variable Length Array (VLA) - C99 feature

printf("Enter %d elements:\n", n);


for (i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}

printf("You entered: ");


for (i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;

4. Arrays and Pointers


4.1 Array-Pointer Relationship
In C, arrays and pointers share a close relationship. The array name itself acts as a pointer
to the first element[15].

#include <stdio.h>
int main() {
int arr[] = {10, 20, 30, 40, 50};

// Array name is a pointer to first element


printf("Address of arr: %p\n", (void*)arr);
printf("Address of arr[0]: %p\n", (void*)&arr[0]);
printf("Value at arr: %d\n", *arr);

// These are equivalent:


printf("arr[2] = %d\n", arr[2]);
printf("*(arr+2) = %d\n", *(arr + 2));

return 0;

4.2 Pointer Arithmetic with Arrays


#include <stdio.h>
int main() {
int arr[] = {100, 200, 300, 400, 500};
int *ptr = arr; // Pointer to first element
int i;

printf("Using pointer arithmetic:\n");


for (i = 0; i < 5; i++) {
printf("Element %d: %d (Address: %p)\n",
i, *(ptr + i), (void*)(ptr + i));
}
// Incrementing pointer
printf("\nIncrementing pointer:\n");
ptr = arr; // Reset pointer
for (i = 0; i < 5; i++) {
printf("%d ", *ptr);
ptr++; // Move to next element
}
printf("\n");

return 0;

4.3 Accessing Arrays via Pointers


#include <stdio.h>

// Function to modify array elements using pointer


void doubleElements(int *arr, int size) {
int i;
for (i = 0; i < size; i++) {
*(arr + i) *= 2; // Double each element
}
}
int main() {
int numbers[] = {1, 2, 3, 4, 5};
int size = sizeof(numbers) / sizeof(numbers[0]);
int i;

printf("Original array: ");


for (i = 0; i < size; i++) {
printf("%d ", numbers[i]);
}
printf("\n");

doubleElements(numbers, size);

printf("Modified array: ");


for (i = 0; i < size; i++) {
printf("%d ", numbers[i]);
}
printf("\n");

return 0;

5. Passing Arrays to Functions


5.1 Array as Function Parameter
When arrays are passed to functions, only the address of the first element is passed, not the
entire array[3]. This is efficient but means modifications affect the original array.

#include <stdio.h>
// Method 1: Unsized array
void printArray1(int arr[], int size) {
int i;
for (i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
// Method 2: Pointer notation
void printArray2(int *arr, int size) {
int i;
for (i = 0; i < size; i++) {
printf("%d ", *(arr + i));
}
printf("\n");
}

// Method 3: Sized array (size ignored except for documentation)


void printArray3(int arr[10], int size) {
int i;
for (i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
int main() {
int data[] = {5, 10, 15, 20, 25};
int size = sizeof(data) / sizeof(data[0]);

printf("Method 1: ");
printArray1(data, size);
printf("Method 2: ");
printArray2(data, size);

printf("Method 3: ");
printArray3(data, size);

return 0;

5.2 Modifying Array in Function


#include <stdio.h>

void incrementArray(int arr[], int size, int value) {


int i;
for (i = 0; i < size; i++) {
arr[i] += value;
}
}
int main() {
int numbers[] = {10, 20, 30, 40, 50};
int size = sizeof(numbers) / sizeof(numbers[0]);
int i;

printf("Before: ");
for (i = 0; i < size; i++) {
printf("%d ", numbers[i]);
}
printf("\n");

incrementArray(numbers, size, 5);

printf("After: ");
for (i = 0; i < size; i++) {
printf("%d ", numbers[i]);
}
printf("\n");

return 0;
}

5.3 Returning Arrays from Functions


C does not allow returning complete arrays directly. Instead, return a pointer or use
static/dynamic allocation:
#include <stdio.h>
#include <stdlib.h>

// Method 1: Return pointer to static array (persistent across calls)


int* getSquares(int n) {
static int squares[100]; // Static array
int i;

for (i = 0; i < n && i < 100; i++) {


squares[i] = i * i;
}
return squares;

// Method 2: Return dynamically allocated array


int* createArray(int size) {
int arr = (int)malloc(size * sizeof(int));
int i;

for (i = 0; i < size; i++) {


arr[i] = i + 1;
}
return arr;

int main() {
int i;

// Using static array


int *squares = getSquares(5);
printf("Squares: ");
for (i = 0; i < 5; i++) {
printf("%d ", squares[i]);
}
printf("\n");
// Using dynamic array
int *dynamic = createArray(5);
printf("Dynamic: ");
for (i = 0; i < 5; i++) {
printf("%d ", dynamic[i]);
}
printf("\n");

free(dynamic); // Important: free allocated memory

return 0;

6. Multi-Dimensional Arrays
6.1 Two-Dimensional Arrays
Two-dimensional arrays represent data in rows and columns, similar to matrices or
tables[3].

6.1.1 Declaration and Initialization


#include <stdio.h>

int main() {
// Method 1: Full initialization
int matrix1[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};

// Method 2: Linear initialization


int matrix2[2][4] = {1, 2, 3, 4, 5, 6, 7, 8};

// Method 3: Partial initialization


int matrix3[3][3] = {{1}, {2}, {3}}; // First column initialized

// Display matrix1
int i, j;
printf("Matrix 1:\n");
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
printf("%d ", matrix1[i][j]);
}
printf("\n");
}

return 0;

6.1.2 Accessing 2D Array Elements


#include <stdio.h>

int main() {
int matrix[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};

int rows = 3, cols = 4;


int i, j;

printf("Accessing elements:\n");
printf("Element at [0][0]: %d\n", matrix[0][0]);
printf("Element at [1][2]: %d\n", matrix[1][2]);
printf("Element at [2][3]: %d\n", matrix[2][3]);

// Traversing 2D array
printf("\nComplete matrix:\n");
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) {
printf("%3d ", matrix[i][j]);
}
printf("\n");
}

return 0;
}

6.2 Matrix Operations


6.2.1 Matrix Addition
#include <stdio.h>
#define ROWS 3
#define COLS 3
void addMatrices(int a[ROWS][COLS], int b[ROWS][COLS], int result[ROWS][COLS]) {
int i, j;
for (i = 0; i < ROWS; i++) {
for (j = 0; j < COLS; j++) {
result[i][j] = a[i][j] + b[i][j];
}
}
}

void printMatrix(int matrix[ROWS][COLS]) {


int i, j;
for (i = 0; i < ROWS; i++) {
for (j = 0; j < COLS; j++) {
printf("%3d ", matrix[i][j]);
}
printf("\n");
}
}
int main() {
int matrix1[ROWS][COLS] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
int matrix2[ROWS][COLS] = {{9, 8, 7}, {6, 5, 4}, {3, 2, 1}};
int result[ROWS][COLS];

printf("Matrix 1:\n");
printMatrix(matrix1);

printf("\nMatrix 2:\n");
printMatrix(matrix2);

addMatrices(matrix1, matrix2, result);

printf("\nSum:\n");
printMatrix(result);

return 0;
}

6.2.2 Matrix Multiplication


#include <stdio.h>
#define R1 2
#define C1 3
#define R2 3
#define C2 2

void multiplyMatrices(int a[R1][C1], int b[R2][C2], int result[R1][C2]) {


int i, j, k;

// Initialize result matrix to 0


for (i = 0; i < R1; i++) {
for (j = 0; j < C2; j++) {
result[i][j] = 0;
}
}

// Perform multiplication
for (i = 0; i < R1; i++) {
for (j = 0; j < C2; j++) {
for (k = 0; k < C1; k++) {
result[i][j] += a[i][k] * b[k][j];
}
}
}

void printMatrix2x2(int matrix[R1][C2]) {


int i, j;
for (i = 0; i < R1; i++) {
for (j = 0; j < C2; j++) {
printf("%4d ", matrix[i][j]);
}
printf("\n");
}
}
int main() {
int a[R1][C1] = {{1, 2, 3}, {4, 5, 6}};
int b[R2][C2] = {{7, 8}, {9, 10}, {11, 12}};
int result[R1][C2];
printf("Matrix A (2x3):\n");
int i, j;
for (i = 0; i < R1; i++) {
for (j = 0; j < C1; j++) {
printf("%3d ", a[i][j]);
}
printf("\n");
}

printf("\nMatrix B (3x2):\n");
for (i = 0; i < R2; i++) {
for (j = 0; j < C2; j++) {
printf("%3d ", b[i][j]);
}
printf("\n");
}

multiplyMatrices(a, b, result);

printf("\nProduct (2x2):\n");
printMatrix2x2(result);

return 0;

6.2.3 Matrix Transpose


#include <stdio.h>

#define ROWS 3
#define COLS 4
void transpose(int matrix[ROWS][COLS], int result[COLS][ROWS]) {
int i, j;
for (i = 0; i < ROWS; i++) {
for (j = 0; j < COLS; j++) {
result[j][i] = matrix[i][j];
}
}
}
int main() {
int matrix[ROWS][COLS] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
int transposed[COLS][ROWS];
int i, j;

printf("Original Matrix (%dx%d):\n", ROWS, COLS);


for (i = 0; i < ROWS; i++) {
for (j = 0; j < COLS; j++) {
printf("%3d ", matrix[i][j]);
}
printf("\n");
}

transpose(matrix, transposed);

printf("\nTransposed Matrix (%dx%d):\n", COLS, ROWS);


for (i = 0; i < COLS; i++) {
for (j = 0; j < ROWS; j++) {
printf("%3d ", transposed[i][j]);
}
printf("\n");
}

return 0;

6.3 Three-Dimensional Arrays


Three-dimensional arrays can be visualized as arrays of 2D arrays, useful for representing
3D spaces or multi-layered data.
#include <stdio.h>
int main() {
// 3D array: [layers][rows][columns]
int cube[2][3][4] = {
{
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
},
{
{13, 14, 15, 16},
{17, 18, 19, 20},
{21, 22, 23, 24}
}
};

int layer, row, col;

printf("3D Array Contents:\n");


for (layer = 0; layer < 2; layer++) {
printf("Layer %d:\n", layer);
for (row = 0; row < 3; row++) {
for (col = 0; col < 4; col++) {
printf("%3d ", cube[layer][row][col]);
}
printf("\n");
}
printf("\n");
}

return 0;

7. Dynamic Arrays
7.1 Dynamic Memory Allocation
Static arrays have fixed sizes determined at compile time. Dynamic arrays allow runtime
size determination using memory allocation functions[6].

7.1.1 Using malloc()


#include <stdio.h>
#include <stdlib.h>
int main() {
int n, i;
int *arr;
printf("Enter the number of elements: ");
scanf("%d", &n);

// Allocate memory dynamically


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

// Check if memory allocation was successful


if (arr == NULL) {
printf("Memory allocation failed!\n");
return 1;
}

// Input elements
printf("Enter %d elements:\n", n);
for (i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}

// Display elements
printf("Array elements: ");
for (i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");

// Free allocated memory


free(arr);

return 0;

7.1.2 Using calloc()


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

int main() {
int n, i;
int *arr;
printf("Enter size: ");
scanf("%d", &n);

// Allocate and initialize to zero


arr = (int*)calloc(n, sizeof(int));

if (arr == NULL) {
printf("Memory allocation failed!\n");
return 1;
}

// Display (all zeros initially)


printf("Initial values (calloc): ");
for (i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");

// Assign values
for (i = 0; i < n; i++) {
arr[i] = (i + 1) * 10;
}

printf("After assignment: ");


for (i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");

free(arr);

return 0;

}
7.1.3 Using realloc()
#include <stdio.h>
#include <stdlib.h>
int main() {
int *arr;
int i, size = 5, newSize = 10;

// Initial allocation
arr = (int*)malloc(size * sizeof(int));
if (arr == NULL) {
printf("Allocation failed!\n");
return 1;
}

// Initialize initial array


printf("Initial array (size %d): ", size);
for (i = 0; i < size; i++) {
arr[i] = i + 1;
printf("%d ", arr[i]);
}
printf("\n");

// Resize array
arr = (int*)realloc(arr, newSize * sizeof(int));
if (arr == NULL) {
printf("Reallocation failed!\n");
return 1;
}

// Initialize new elements


for (i = size; i < newSize; i++) {
arr[i] = i + 1;
}

printf("Resized array (size %d): ", newSize);


for (i = 0; i < newSize; i++) {
printf("%d ", arr[i]);
}
printf("\n");

free(arr);

return 0;

7.2 Dynamic 2D Arrays


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

int main() {
int **matrix;
int rows = 3, cols = 4;
int i, j;

// Allocate memory for row pointers


matrix = (int**)malloc(rows * sizeof(int*));

// Allocate memory for each row


for (i = 0; i < rows; i++) {
matrix[i] = (int*)malloc(cols * sizeof(int));
}

// Initialize matrix
int value = 1;
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) {
matrix[i][j] = value++;
}
}

// Display matrix
printf("Dynamic 2D Array:\n");
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) {
printf("%3d ", matrix[i][j]);
}
printf("\n");
}

// Free memory
for (i = 0; i < rows; i++) {
free(matrix[i]);
}
free(matrix);

return 0;

8. Common Array Operations


8.1 Finding Maximum and Minimum
#include <stdio.h>
#include <limits.h>

void findMinMax(int arr[], int size, int *min, int *max) {


int i;
*min = INT_MAX;
*max = INT_MIN;

for (i = 0; i < size; i++) {


if (arr[i] < *min) {
*min = arr[i];
}
if (arr[i] > *max) {
*max = arr[i];
}
}

int main() {
int arr[] = {45, 12, 78, 23, 67, 89, 34, 56};
int size = sizeof(arr) / sizeof(arr[0]);
int min, max;

findMinMax(arr, size, &min, &max);


printf("Array: ");
int i;
for (i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");

printf("Minimum: %d\n", min);


printf("Maximum: %d\n", max);

return 0;

8.2 Calculating Sum and Average


#include <stdio.h>

int calculateSum(int arr[], int size) {


int sum = 0;
int i;
for (i = 0; i < size; i++) {
sum += arr[i];
}
return sum;
}
double calculateAverage(int arr[], int size) {
int sum = calculateSum(arr, size);
return (double)sum / size;
}
int main() {
int arr[] = {10, 20, 30, 40, 50};
int size = sizeof(arr) / sizeof(arr[0]);

int sum = calculateSum(arr, size);


double avg = calculateAverage(arr, size);

printf("Array: ");
int i;
for (i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");

printf("Sum: %d\n", sum);


printf("Average: %.2f\n", avg);

return 0;

8.3 Reversing an Array


#include <stdio.h>

void reverseArray(int arr[], int size) {


int start = 0;
int end = size - 1;
int temp;

while (start < end) {


// Swap elements
temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;

start++;
end--;
}

int main() {
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int size = sizeof(arr) / sizeof(arr[0]);
int i;

printf("Original array: ");


for (i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");

reverseArray(arr, size);
printf("Reversed array: ");
for (i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");

return 0;

8.4 Copying Arrays


#include <stdio.h>
#include <string.h>

// Method 1: Manual copying


void copyArray1(int source[], int dest[], int size) {
int i;
for (i = 0; i < size; i++) {
dest[i] = source[i];
}
}
// Method 2: Using memcpy
void copyArray2(int source[], int dest[], int size) {
memcpy(dest, source, size * sizeof(int));
}
int main() {
int source[] = {10, 20, 30, 40, 50};
int dest1[5], dest2[5];
int size = sizeof(source) / sizeof(source[0]);
int i;

copyArray1(source, dest1, size);


copyArray2(source, dest2, size);

printf("Source: ");
for (i = 0; i < size; i++) printf("%d ", source[i]);
printf("\n");

printf("Dest1: ");
for (i = 0; i < size; i++) printf("%d ", dest1[i]);
printf("\n");
printf("Dest2: ");
for (i = 0; i < size; i++) printf("%d ", dest2[i]);
printf("\n");

return 0;

8.5 Inserting an Element


#include <stdio.h>

void insertElement(int arr[], int *size, int element, int position) {


int i;

// Shift elements to the right


for (i = *size; i > position; i--) {
arr[i] = arr[i - 1];
}

// Insert new element


arr[position] = element;
(*size)++;

int main() {
int arr[100] = {10, 20, 30, 40, 50};
int size = 5;
int element = 25;
int position = 2;
int i;

printf("Original array: ");


for (i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");

insertElement(arr, &size, element, position);


printf("After inserting %d at position %d: ", element, position);
for (i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");

return 0;

8.6 Deleting an Element


#include <stdio.h>

void deleteElement(int arr[], int *size, int position) {


int i;

// Shift elements to the left


for (i = position; i < *size - 1; i++) {
arr[i] = arr[i + 1];
}

(*size)--;

int main() {
int arr[] = {10, 20, 30, 40, 50, 60};
int size = 6;
int position = 3;
int i;

printf("Original array: ");


for (i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");

printf("Deleting element at position %d\n", position);


deleteElement(arr, &size, position);
printf("After deletion: ");
for (i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");

return 0;

8.7 Array Rotation


8.7.1 Left Rotation
#include <stdio.h>
void leftRotateByOne(int arr[], int size) {
int temp = arr[0];
int i;

for (i = 0; i < size - 1; i++) {


arr[i] = arr[i + 1];
}
arr[size - 1] = temp;

}
void leftRotate(int arr[], int size, int d) {
int i;
for (i = 0; i < d; i++) {
leftRotateByOne(arr, size);
}
}

int main() {
int arr[] = {1, 2, 3, 4, 5, 6, 7};
int size = sizeof(arr) / sizeof(arr[0]);
int d = 2;
int i;

printf("Original array: ");


for (i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");

leftRotate(arr, size, d);

printf("After %d left rotations: ", d);


for (i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");

return 0;

8.7.2 Right Rotation


#include <stdio.h>

void rightRotateByOne(int arr[], int size) {


int temp = arr[size - 1];
int i;

for (i = size - 1; i > 0; i--) {


arr[i] = arr[i - 1];
}
arr[0] = temp;

void rightRotate(int arr[], int size, int d) {


int i;
for (i = 0; i < d; i++) {
rightRotateByOne(arr, size);
}
}
int main() {
int arr[] = {1, 2, 3, 4, 5, 6, 7};
int size = sizeof(arr) / sizeof(arr[0]);
int d = 3;
int i;

printf("Original array: ");


for (i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");

rightRotate(arr, size, d);

printf("After %d right rotations: ", d);


for (i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");

return 0;

9. Searching Algorithms
9.1 Linear Search
Linear search sequentially checks each element until the target is found or the array ends.
Time complexity: O(n)[8].

#include <stdio.h>
int linearSearch(int arr[], int size, int target) {
int i;
for (i = 0; i < size; i++) {
if (arr[i] == target) {
return i; // Return index if found
}
}
return -1; // Return -1 if not found
}
int main() {
int arr[] = {64, 34, 25, 12, 22, 11, 90};
int size = sizeof(arr) / sizeof(arr[0]);
int target, result;
int i;

printf("Array: ");
for (i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");

printf("Enter element to search: ");


scanf("%d", &target);

result = linearSearch(arr, size, target);

if (result != -1) {
printf("Element %d found at index %d\n", target, result);
} else {
printf("Element %d not found in array\n", target);
}

return 0;

9.2 Binary Search


Binary search efficiently finds elements in sorted arrays by repeatedly dividing the search
interval in half. Time complexity: O(log n)[8].

#include <stdio.h>
int binarySearch(int arr[], int size, int target) {
int left = 0;
int right = size - 1;

while (left <= right) {


int mid = left + (right - left) / 2;

// Check if target is at mid


if (arr[mid] == target) {
return mid;
}

// If target is greater, ignore left half


if (arr[mid] < target) {
left = mid + 1;
}
// If target is smaller, ignore right half
else {
right = mid - 1;
}
}

return -1; // Element not found

int main() {
int arr[] = {2, 5, 8, 12, 16, 23, 38, 45, 56, 67, 78};
int size = sizeof(arr) / sizeof(arr[0]);
int target, result;
int i;

printf("Sorted Array: ");


for (i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");

printf("Enter element to search: ");


scanf("%d", &target);

result = binarySearch(arr, size, target);

if (result != -1) {
printf("Element %d found at index %d\n", target, result);
} else {
printf("Element %d not found in array\n", target);
}

return 0;

}
9.3 Recursive Binary Search
#include <stdio.h>
int binarySearchRecursive(int arr[], int left, int right, int target) {
if (right >= left) {
int mid = left + (right - left) / 2;

// Element found at mid


if (arr[mid] == target) {
return mid;
}

// Search in left half


if (arr[mid] > target) {
return binarySearchRecursive(arr, left, mid - 1, target);
}

// Search in right half


return binarySearchRecursive(arr, mid + 1, right, target);
}

return -1; // Element not found

}
int main() {
int arr[] = {3, 7, 11, 19, 23, 31, 42, 55, 68, 79};
int size = sizeof(arr) / sizeof(arr[0]);
int target = 31;

int result = binarySearchRecursive(arr, 0, size - 1, target);

if (result != -1) {
printf("Element %d found at index %d\n", target, result);
} else {
printf("Element %d not found\n", target);
}

return 0;
}

10. Sorting Algorithms


10.1 Bubble Sort
Bubble sort repeatedly swaps adjacent elements if they are in wrong order. Time
complexity: O(n²)[12].
#include <stdio.h>

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


int i, j, temp;
int swapped;

for (i = 0; i < size - 1; i++) {


swapped = 0;

for (j = 0; j < size - i - 1; j++) {


if (arr[j] > arr[j + 1]) {
// Swap arr[j] and arr[j+1]
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
swapped = 1;
}
}

// If no swapping occurred, array is sorted


if (swapped == 0) {
break;
}
}

int main() {
int arr[] = {64, 34, 25, 12, 22, 11, 90};
int size = sizeof(arr) / sizeof(arr[0]);
int i;

printf("Original array: ");


for (i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");

bubbleSort(arr, size);

printf("Sorted array: ");


for (i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");

return 0;

10.2 Selection Sort


Selection sort divides the array into sorted and unsorted regions, repeatedly selecting the
minimum element from unsorted region. Time complexity: O(n²)[12].

#include <stdio.h>
void selectionSort(int arr[], int size) {
int i, j, minIdx, temp;

for (i = 0; i < size - 1; i++) {


// Find minimum element in unsorted portion
minIdx = i;
for (j = i + 1; j < size; j++) {
if (arr[j] < arr[minIdx]) {
minIdx = j;
}
}

// Swap minimum element with first element of unsorted portion


if (minIdx != i) {
temp = arr[i];
arr[i] = arr[minIdx];
arr[minIdx] = temp;
}
}

int main() {
int arr[] = {64, 25, 12, 22, 11};
int size = sizeof(arr) / sizeof(arr[0]);
int i;

printf("Original array: ");


for (i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");

selectionSort(arr, size);

printf("Sorted array: ");


for (i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");

return 0;

10.3 Insertion Sort


Insertion sort builds the final sorted array one element at a time by inserting elements into
their correct position. Time complexity: O(n²), but efficient for small or nearly sorted
arrays[12].

#include <stdio.h>
void insertionSort(int arr[], int size) {
int i, j, key;

for (i = 1; i < size; i++) {


key = arr[i];
j = i - 1;
// Move elements greater than key one position ahead
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
}

int main() {
int arr[] = {12, 11, 13, 5, 6};
int size = sizeof(arr) / sizeof(arr[0]);
int i;

printf("Original array: ");


for (i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");

insertionSort(arr, size);

printf("Sorted array: ");


for (i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");

return 0;

10.4 Merge Sort


Merge sort uses divide-and-conquer strategy to sort arrays efficiently. Time complexity:
O(n log n)[14].

#include <stdio.h>
#include <stdlib.h>
void merge(int arr[], int left, int mid, int right) {
int i, j, k;
int n1 = mid - left + 1;
int n2 = right - mid;

// Create temporary arrays


int *L = (int*)malloc(n1 * sizeof(int));
int *R = (int*)malloc(n2 * sizeof(int));

// Copy data to temporary arrays


for (i = 0; i < n1; i++) {
L[i] = arr[left + i];
}
for (j = 0; j < n2; j++) {
R[j] = arr[mid + 1 + j];
}

// Merge the temporary arrays back


i = 0;
j = 0;
k = left;

while (i < n1 && j < n2) {


if (L[i] <= R[j]) {
arr[k] = L[i];
i++;
} else {
arr[k] = R[j];
j++;
}
k++;
}

// Copy remaining elements


while (i < n1) {
arr[k] = L[i];
i++;
k++;
}
while (j < n2) {
arr[k] = R[j];
j++;
k++;
}

free(L);
free(R);

void mergeSort(int arr[], int left, int right) {


if (left < right) {
int mid = left + (right - left) / 2;

// Sort first and second halves


mergeSort(arr, left, mid);
mergeSort(arr, mid + 1, right);

// Merge the sorted halves


merge(arr, left, mid, right);
}

int main() {
int arr[] = {38, 27, 43, 3, 9, 82, 10};
int size = sizeof(arr) / sizeof(arr[0]);
int i;

printf("Original array: ");


for (i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");

mergeSort(arr, 0, size - 1);

printf("Sorted array: ");


for (i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");

return 0;

10.5 Quick Sort


Quick sort is a highly efficient sorting algorithm using divide-and-conquer. Average time
complexity: O(n log n)[12].

#include <stdio.h>
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
int partition(int arr[], int low, int high) {
int pivot = arr[high]; // Choose last element as pivot
int i = low - 1; // Index of smaller element
int j;

for (j = low; j < high; j++) {


// If current element is smaller than pivot
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) {
// Partition index
int pi = partition(arr, low, high);
// Recursively sort elements before and after partition
quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}

int main() {
int arr[] = {10, 7, 8, 9, 1, 5};
int size = sizeof(arr) / sizeof(arr[0]);
int i;

printf("Original array: ");


for (i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");

quickSort(arr, 0, size - 1);

printf("Sorted array: ");


for (i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");

return 0;

11. Advanced Array Problems


11.1 Finding Duplicates
#include <stdio.h>

void findDuplicates(int arr[], int size) {


int i, j;
int found = 0;
printf("Duplicate elements: ");

for (i = 0; i < size; i++) {


for (j = i + 1; j < size; j++) {
if (arr[i] == arr[j]) {
// Check if already printed
int k, alreadyPrinted = 0;
for (k = 0; k < i; k++) {
if (arr[k] == arr[i]) {
alreadyPrinted = 1;
break;
}
}

if (!alreadyPrinted) {
printf("%d ", arr[i]);
found = 1;
}
break;
}
}
}

if (!found) {
printf("None");
}
printf("\n");

int main() {
int arr[] = {1, 3, 4, 2, 2, 5, 3, 7};
int size = sizeof(arr) / sizeof(arr[0]);
int i;

printf("Array: ");
for (i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");

findDuplicates(arr, size);

return 0;

11.2 Removing Duplicates from Sorted Array


#include <stdio.h>

int removeDuplicates(int arr[], int size) {


if (size == 0 || size == 1) {
return size;
}

int j = 0; // Index for unique elements


int i;

for (i = 0; i < size - 1; i++) {


if (arr[i] != arr[i + 1]) {
arr[j++] = arr[i];
}
}
arr[j++] = arr[size - 1];

return j;

int main() {
int arr[] = {1, 1, 2, 2, 2, 3, 4, 4, 5, 5, 5, 6};
int size = sizeof(arr) / sizeof(arr[0]);
int i;

printf("Original sorted array: ");


for (i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
int newSize = removeDuplicates(arr, size);

printf("Array after removing duplicates: ");


for (i = 0; i < newSize; i++) {
printf("%d ", arr[i]);
}
printf("\n");

return 0;

11.3 Finding Missing Number


#include <stdio.h>

// Find missing number in array containing 1 to n


int findMissingNumber(int arr[], int size) {
int n = size + 1; // Array should have n elements
int totalSum = (n * (n + 1)) / 2;
int arraySum = 0;
int i;

for (i = 0; i < size; i++) {


arraySum += arr[i];
}

return totalSum - arraySum;

int main() {
int arr[] = {1, 2, 4, 5, 6, 7, 8, 9, 10};
int size = sizeof(arr) / sizeof(arr[0]);
int i;

printf("Array (1 to %d with one missing): ", size + 1);


for (i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
int missing = findMissingNumber(arr, size);
printf("Missing number: %d\n", missing);

return 0;

11.4 Two Sum Problem


#include <stdio.h>

// Find two numbers in array that sum to target


int findTwoSum(int arr[], int size, int target, int result[]) {
int i, j;

for (i = 0; i < size - 1; i++) {


for (j = i + 1; j < size; j++) {
if (arr[i] + arr[j] == target) {
result[0] = i;
result[1] = j;
return 1; // Found
}
}
}

return 0; // Not found

int main() {
int arr[] = {2, 7, 11, 15, 23};
int size = sizeof(arr) / sizeof(arr[0]);
int target = 26;
int result[2];
int i;

printf("Array: ");
for (i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\nTarget sum: %d\n", target);
if (findTwoSum(arr, size, target, result)) {
printf("Pair found: arr[%d] + arr[%d] = %d + %d = %d\n",
result[0], result[1], arr[result[0]], arr[result[1]], target);
} else {
printf("No pair found\n");
}

return 0;

11.5 Maximum Subarray Sum (Kadane's Algorithm)


#include <stdio.h>

int maxSubarraySum(int arr[], int size) {


int maxSoFar = arr[0];
int maxEndingHere = arr[0];
int i;

for (i = 1; i < size; i++) {


maxEndingHere = (arr[i] > maxEndingHere + arr[i]) ?
arr[i] : maxEndingHere + arr[i];
maxSoFar = (maxSoFar > maxEndingHere) ? maxSoFar : maxEndingHere;
}

return maxSoFar;

int main() {
int arr[] = {-2, 1, -3, 4, -1, 2, 1, -5, 4};
int size = sizeof(arr) / sizeof(arr[0]);
int i;

printf("Array: ");
for (i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
int maxSum = maxSubarraySum(arr, size);
printf("Maximum subarray sum: %d\n", maxSum);

return 0;

11.6 Leaders in Array


An element is a leader if it is greater than all elements to its right[12].

#include <stdio.h>
void findLeaders(int arr[], int size) {
int i, j;
int isLeader;

printf("Leaders in array: ");

for (i = 0; i < size; i++) {


isLeader = 1;

// Check if arr[i] is greater than all elements to its right


for (j = i + 1; j < size; j++) {
if (arr[i] <= arr[j]) {
isLeader = 0;
break;
}
}

if (isLeader) {
printf("%d ", arr[i]);
}
}
printf("\n");

}
int main() {
int arr[] = {16, 17, 4, 3, 5, 2};
int size = sizeof(arr) / sizeof(arr[0]);
int i;
printf("Array: ");
for (i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");

findLeaders(arr, size);

return 0;

11.7 Move Zeroes to End


#include <stdio.h>

void moveZeroesToEnd(int arr[], int size) {


int count = 0; // Count of non-zero elements
int i;

// Traverse array and move non-zero elements to front


for (i = 0; i < size; i++) {
if (arr[i] != 0) {
arr[count++] = arr[i];
}
}

// Fill remaining positions with zeros


while (count < size) {
arr[count++] = 0;
}

int main() {
int arr[] = {1, 9, 8, 4, 0, 0, 2, 7, 0, 6, 0, 9};
int size = sizeof(arr) / sizeof(arr[0]);
int i;

printf("Original array: ");


for (i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");

moveZeroesToEnd(arr, size);

printf("After moving zeros: ");


for (i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");

return 0;

11.8 Majority Element


Find element appearing more than n/2 times (Boyer-Moore Voting Algorithm)[12].

#include <stdio.h>
int findMajorityElement(int arr[], int size) {
int candidate = -1;
int count = 0;
int i;

// Find candidate
for (i = 0; i < size; i++) {
if (count == 0) {
candidate = arr[i];
count = 1;
} else if (arr[i] == candidate) {
count++;
} else {
count--;
}
}

// Verify candidate
count = 0;
for (i = 0; i < size; i++) {
if (arr[i] == candidate) {
count++;
}
}

if (count > size / 2) {


return candidate;
}

return -1; // No majority element

int main() {
int arr[] = {3, 3, 4, 2, 4, 4, 2, 4, 4};
int size = sizeof(arr) / sizeof(arr[0]);
int i;

printf("Array: ");
for (i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");

int majority = findMajorityElement(arr, size);

if (majority != -1) {
printf("Majority element: %d\n", majority);
} else {
printf("No majority element found\n");
}

return 0;

}
11.9 Stock Buy and Sell Problem
#include <stdio.h>
void maxProfit(int prices[], int size) {
int i;
int minPrice = prices[0];
int maxProfit = 0;
int buyDay = 0, sellDay = 0;
int tempBuyDay = 0;

for (i = 1; i < size; i++) {


if (prices[i] < minPrice) {
minPrice = prices[i];
tempBuyDay = i;
}

int profit = prices[i] - minPrice;


if (profit > maxProfit) {
maxProfit = profit;
buyDay = tempBuyDay;
sellDay = i;
}
}

printf("Maximum profit: %d\n", maxProfit);


printf("Buy on day %d (price: %d)\n", buyDay, prices[buyDay]);
printf("Sell on day %d (price: %d)\n", sellDay, prices[sellDay]);

}
int main() {
int prices[] = {7, 1, 5, 3, 6, 4};
int size = sizeof(prices) / sizeof(prices[0]);
int i;

printf("Stock prices: ");


for (i = 0; i < size; i++) {
printf("%d ", prices[i]);
}
printf("\n");
maxProfit(prices, size);

return 0;

11.10 Trapping Rain Water


#include <stdio.h>

int trapRainWater(int height[], int size) {


if (size <= 2) return 0;

int left = 0, right = size - 1;


int leftMax = 0, rightMax = 0;
int water = 0;

while (left < right) {


if (height[left] < height[right]) {
if (height[left] >= leftMax) {
leftMax = height[left];
} else {
water += leftMax - height[left];
}
left++;
} else {
if (height[right] >= rightMax) {
rightMax = height[right];
} else {
water += rightMax - height[right];
}
right--;
}
}

return water;

int main() {
int height[] = {0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1};
int size = sizeof(height) / sizeof(height[0]);
int i;

printf("Height array: ");


for (i = 0; i < size; i++) {
printf("%d ", height[i]);
}
printf("\n");

int water = trapRainWater(height, size);


printf("Total water trapped: %d units\n", water);

return 0;

12. String Arrays and Character Arrays


12.1 String Basics
In C, strings are character arrays terminated with null character '\0'[1].
#include <stdio.h>
#include <string.h>
int main() {
// Method 1: Character array
char str1[20] = "Hello";

// Method 2: Array initialization


char str2[] = {'W', 'o', 'r', 'l', 'd', '\0'};

// Method 3: Using strcpy


char str3[20];
strcpy(str3, "Programming");

printf("String 1: %s\n", str1);


printf("String 2: %s\n", str2);
printf("String 3: %s\n", str3);

printf("Length of str1: %lu\n", strlen(str1));


return 0;

12.2 String Operations


#include <stdio.h>
#include <string.h>

int main() {
char str1[50] = "Hello";
char str2[] = " World";
char str3[50];

// String concatenation
strcat(str1, str2);
printf("Concatenated: %s\n", str1);

// String copy
strcpy(str3, str1);
printf("Copied: %s\n", str3);

// String comparison
if (strcmp(str1, str3) == 0) {
printf("Strings are equal\n");
}

// String length
printf("Length: %lu\n", strlen(str1));

return 0;

12.3 Array of Strings


#include <stdio.h>
#include <string.h>
int main() {
// 2D character array for storing multiple strings
char names[5][20] = {
"Alice",
"Bob",
"Charlie",
"David",
"Eve"
};

int i;
printf("List of names:\n");
for (i = 0; i < 5; i++) {
printf("%d. %s\n", i + 1, names[i]);
}

// Search for a name


char search[20];
printf("\nEnter name to search: ");
scanf("%s", search);

int found = 0;
for (i = 0; i < 5; i++) {
if (strcmp(names[i], search) == 0) {
printf("Found %s at position %d\n", search, i + 1);
found = 1;
break;
}
}

if (!found) {
printf("%s not found\n", search);
}

return 0;

12.4 String Reversal


#include <stdio.h>
#include <string.h>
void reverseString(char str[]) {
int start = 0;
int end = strlen(str) - 1;
char temp;

while (start < end) {


temp = str[start];
str[start] = str[end];
str[end] = temp;
start++;
end--;
}

}
int main() {
char str[100];

printf("Enter a string: ");


scanf("%s", str);

printf("Original string: %s\n", str);

reverseString(str);

printf("Reversed string: %s\n", str);

return 0;

12.5 Palindrome Check


#include <stdio.h>
#include <string.h>
#include <ctype.h>
int isPalindrome(char str[]) {
int start = 0;
int end = strlen(str) - 1;

while (start < end) {


// Skip non-alphanumeric characters
while (start < end && !isalnum(str[start])) {
start++;
}
while (start < end && !isalnum(str[end])) {
end--;
}

// Compare characters (case-insensitive)


if (tolower(str[start]) != tolower(str[end])) {
return 0; // Not a palindrome
}

start++;
end--;
}

return 1; // Is a palindrome

int main() {
char str[100];

printf("Enter a string: ");


fgets(str, sizeof(str), stdin);

// Remove newline if present


str[strcspn(str, "\n")] = '\0';

if (isPalindrome(str)) {
printf("\"%s\" is a palindrome\n", str);
} else {
printf("\"%s\" is not a palindrome\n", str);
}

return 0;

}
13. Best Practices and Common Pitfalls
13.1 Best Practices
• Always Initialize Arrays: Uninitialized arrays contain garbage values
• Check Array Bounds: C does not perform automatic bounds checking; accessing
out-of-bounds indices causes undefined behavior[10]
• Use sizeof for Array Length: Calculate array size dynamically: size = sizeof(arr) /
sizeof(arr[0])
• Pass Size to Functions: Always pass array size as a separate parameter since array
parameters decay to pointers
• Free Dynamic Memory: Always free() dynamically allocated arrays to prevent
memory leaks
• Use const for Read-Only Arrays: Declare function parameters as const when array
should not be modified
• Validate User Input: Check array indices from user input before accessing elements
• Consider Cache Performance: Sequential access patterns are more cache-friendly
than random access[12]

13.2 Common Pitfalls


13.2.1 Array Index Out of Bounds
// WRONG - accessing beyond array bounds
int arr[5] = {1, 2, 3, 4, 5};
printf("%d", arr[5]); // Undefined behavior!
// CORRECT
int size = 5;
if (index >= 0 && index < size) {
printf("%d", arr[index]);
}

13.2.2 Not Freeing Dynamic Memory


// WRONG - memory leak
int arr = (int)malloc(100 * sizeof(int));
// Use array...
// Function ends without free()
// CORRECT
int arr = (int)malloc(100 * sizeof(int));
// Use array...
free(arr); // Always free!

13.2.3 Array Decay in Functions


// Arrays decay to pointers in function parameters
void func(int arr[10]) {
// sizeof(arr) gives pointer size, not array size!
printf("%lu", sizeof(arr)); // Prints 8 (on 64-bit), not 40
}
// CORRECT - pass size separately
void func(int arr[], int size) {
printf("%d", size);
}

13.2.4 Returning Local Array


// WRONG - returning pointer to local array
int* createArray() {
int arr[5] = {1, 2, 3, 4, 5};
return arr; // Undefined behavior!
}
// CORRECT - use dynamic allocation
int* createArray(int size) {
int arr = (int)malloc(size * sizeof(int));
return arr;
}

14. Performance Considerations


14.1 Time Complexity Summary
Operation Time Complexity
Access element by index O(1)
Search (unsorted) O(n)
Search (sorted, binary) O(log n)
Insert at end O(1)
Insert at beginning/middle O(n)
Delete from end O(1)
Delete from beginning/middle O(n)
Bubble Sort O(n²)
Selection Sort O(n²)
Insertion Sort O(n²)
Merge Sort O(n log n)
Quick Sort (average) O(n log n)

Table 1: Time complexity of common array operations[8][12]

14.2 Space Complexity


• Static Arrays: O(n) space, allocated at compile time
• Dynamic Arrays: O(n) space, allocated at runtime
• In-place Algorithms: O(1) extra space (modifying original array)
• Sorting with Temporary Arrays: O(n) extra space (e.g., merge sort)
14.3 Optimization Techniques
Loop Unrolling:
// Standard loop
for (i = 0; i < n; i++) {
sum += arr[i];
}
// Unrolled loop (faster for large arrays)
for (i = 0; i < n - 3; i += 4) {
sum += arr[i] + arr[i+1] + arr[i+2] + arr[i+3];
}
Cache-Friendly Access:
// Row-major order (cache-friendly)
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) {
process(matrix[i][j]);
}
}

// Column-major order (cache-unfriendly)


for (j = 0; j < cols; j++) {
for (i = 0; i < rows; i++) {
process(matrix[i][j]); // Jumps through memory
}
}

15. Conclusion
Arrays form the foundation of data structure programming in C, offering efficient memory
management and direct element access[1][3]. This comprehensive guide has covered array
fundamentals including declaration, initialization, memory management, multi-
dimensional arrays, dynamic allocation, and pointer arithmetic. We explored essential
operations like searching, sorting, insertion, deletion, and rotation, along with advanced
problem-solving techniques including finding duplicates, two-sum problems, maximum
subarray sums, and more.
Understanding array mechanics is crucial for algorithm implementation and
optimization[8][12]. The contiguous memory layout enables cache-friendly operations and
O(1) random access, though modifications require careful consideration of time
complexity. Dynamic memory allocation extends array flexibility beyond compile-time
constraints, though proper memory management remains essential.

Mastery of arrays provides the foundation for understanding more complex data
structures like linked lists, stacks, queues, trees, and graphs. The patterns and algorithms
presented here—particularly searching and sorting—represent fundamental computer
science concepts applicable across all programming domains. Through practice with the
examples and problems in this document, programmers can develop robust skills in array
manipulation essential for competitive programming, technical interviews, and
production software development.
References
[1] Arrays in C - GeeksforGeeks. (2015, May 13). GeeksforGeeks. https://www.geeksforgeeks.o
rg/c/c-arrays/
[2] C Arrays (With Examples) - Programiz. (2024, November 9). Programiz. https://www.prog
ramiz.com/c-programming/c-arrays

[3] Array in C: Types, Examples, and Advantages Explained. (2025, April 8). Simplilearn. http
s://www.simplilearn.com/tutorials/c-tutorial/array-in-c
[4] C Arrays - W3Schools. (2025, September 8). W3Schools.
https://www.w3schools.com/c/c_arrays.php
[5] Arrays in C Programming. (2025, April 24). Scribd. https://www.scribd.com/document/522
800930/ARRAYS-IN-C-PROGRAMMING

[6] Types of Array in C: Properties, Uses, Types, and More. (2024, January 30). Internshala. ht
tps://trainings.internshala.com/blog/types-of-array-in-c/
[7] An In-depth Exploration of Arrays in C. (2023, April 5). Datapro. https://www.datapro.in/b
log_details/an-in-depth-exploration-of-arrays-in-c
[8] Array cheatsheet for coding interviews. Tech Interview Handbook. https://www.techinte
rviewhandbook.org/algorithms/array/

[9] Arrays in C Language (Explained With Types & Examples). (2025, August 28). WsCube
Tech. https://www.wscubetech.com/resources/c-programming/arrays
[10] Arrays in C Programming: Operations on Arrays. (2025, August 1). ScholarHat. https://w
ww.scholarhat.com/tutorial/c/array-in-c
[11] C Program Practice: Array Manipulation Techniques. (2024, March 14). Studocu. https://
www.studocu.com/in/document/gujarat-technological-university/programming-in-c/c-prac
tice-pgms/87318021

[12] Array Data Structure. (2024, May 21). GeeksforGeeks. https://www.geeksforgeeks.org/ds


a/array-data-structure-guide/
[13] Arrays and function basic c programming notes. (2024, March 12). SlideShare. https://w
ww.slideshare.net/slideshow/arrays-and-function-basic-c-programming-notes/266763886
[14] C Programs on Arrays. (2023, August 4). Sanfoundry. https://www.sanfoundry.com/c-pro
gramming-examples-arrays/

[15] C Program to Access Array Elements Using Pointer. (2024, September 26). Vultr Docs. htt
ps://docs.vultr.com/clang/examples/access-array-elements-using-pointer
[16] Mastering Array Manipulation in DSA using JavaScript. (2024, September 5). Dev.to. htt
ps://dev.to/manojspace/mastering-array-manipulation-in-dsa-using-javascript-from-basics-
to-advanced-3i6j
[17] C Programming Course Notes - Arrays. (1994, December 31). UIC. https://www.cs.uic.edu/
~jbell/CourseNotes/C_Programming/Arrays.html
[18] Arrays in C (With Examples and Practice). CodeChef. https://www.codechef.com/blogs/a
rrays-in-c
[19] Manipulating Arrays. (2023, December 31). NV5GeospatialSoftware.com. https://www.n
v5geospatialsoftware.com/docs/Manipulating_Arrays.html

[20] Top 15 DSA Questions Using Arrays and Strings. (2025, January 23). Gets De Ready. http
s://getsdeready.com/top-15-dsa-questions-using-arrays-and-strings-for-coding-interviews/

You might also like