C Programming

Arrays and Functions

C Programming Exercise 5 of 7

Arrays and Functions

Master this concept with detailed explanations and interactive coding examples.

7 Questions
15 Minutes
0% Completed
#include <stdio.h> int main() { printf("Hello"); return 0; }

Interview Questions & Answers

Technical Interview

Arrays and Functions in C

When you start writing real programs, you rarely deal with just one value. Most of the time, you work with a collection of values. That is where arrays come in. And when arrays are combined with functions, your programs become structured, reusable, and clean.

Let’s understand everything step by step with clear explanations and practical examples.


1. How to Pass an Array to a Function?

In C, when you pass an array to a function, you are actually passing the base address of the array. That means changes inside the function will affect the original array.

Example: Print Array Elements Using Function


#include <stdio.h>

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

int main() {
    int numbers[] = {10, 20, 30, 40, 50};
    int size = sizeof(numbers) / sizeof(numbers[0]);

    printArray(numbers, size);

    return 0;
}

Explanation: The array numbers is passed to printArray(). The function receives the starting address and prints all elements.


2. How to Modify an Array Inside a Function?

Since arrays are passed by reference (address), any modification inside the function will change the original array.

Example: Multiply Each Element by 2


#include <stdio.h>

void modifyArray(int arr[], int size) {
    for(int i = 0; i < size; i++) {
        arr[i] = arr[i] * 2;
    }
}

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

    modifyArray(numbers, size);

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

    return 0;
}

Output: 2 4 6 8 10


3. Passing One-Dimensional Array to a Function

There are multiple valid ways to declare an array parameter:

  • int arr[]
  • int arr[10]
  • int *arr

Example Using Pointer Syntax


#include <stdio.h>

void display(int *arr, int size) {
    for(int i = 0; i < size; i++) {
        printf("%d ", *(arr + i));
    }
}

int main() {
    int data[] = {5, 10, 15, 20};
    int size = sizeof(data) / sizeof(data[0]);

    display(data, size);

    return 0;
}

4. Passing Two-Dimensional Array to a Function

When passing a 2D array, you must specify the number of columns.

Example: Print 2D Array


#include <stdio.h>

void printMatrix(int arr[][3], int rows) {
    for(int i = 0; i < rows; i++) {
        for(int j = 0; j < 3; j++) {
            printf("%d ", arr[i][j]);
        }
        printf("\n");
    }
}

int main() {
    int matrix[2][3] = {
        {1, 2, 3},
        {4, 5, 6}
    };

    printMatrix(matrix, 2);

    return 0;
}

Important: Column size must be specified in function parameter.


5. How to Return an Array from a Function?

You cannot directly return a local array because it gets destroyed after function execution. Instead, you can:

  • Return a pointer to a static array
  • Use dynamic memory allocation

Example: Return Static Array


#include <stdio.h>

int* getArray() {
    static int arr[3] = {100, 200, 300};
    return arr;
}

int main() {
    int *ptr = getArray();

    for(int i = 0; i < 3; i++) {
        printf("%d ", ptr[i]);
    }

    return 0;
}

6. Example Programs (Important for Practice)

Q1: Write a Function to Find Sum of Array Elements


#include <stdio.h>

int sumArray(int arr[], int size) {
    int sum = 0;
    for(int i = 0; i < size; i++) {
        sum += arr[i];
    }
    return sum;
}

int main() {
    int numbers[] = {10, 20, 30, 40};
    int size = sizeof(numbers) / sizeof(numbers[0]);

    printf("Sum = %d", sumArray(numbers, size));

    return 0;
}

Q2: Write a Function to Find Maximum Element in Array


#include <stdio.h>

int findMax(int arr[], int size) {
    int max = arr[0];
    for(int i = 1; i < size; i++) {
        if(arr[i] > max) {
            max = arr[i];
        }
    }
    return max;
}

int main() {
    int data[] = {5, 8, 2, 15, 9};
    int size = sizeof(data) / sizeof(data[0]);

    printf("Maximum = %d", findMax(data, size));

    return 0;
}

Q3: Write a Recursive Function to Print Array in Reverse


#include <stdio.h>

void printReverse(int arr[], int size) {
    if(size <= 0)
        return;

    printf("%d ", arr[size - 1]);
    printReverse(arr, size - 1);
}

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

    printReverse(arr, size);

    return 0;
}

Important Interview Concepts

  • Arrays are passed as pointers to functions.
  • Changes inside function affect original array.
  • 2D arrays require column size in parameter.
  • Returning local arrays directly is unsafe.
  • Dynamic memory can be used for flexible array returns.

0% read

Interactive Code Playground

Live Coding
main.c
1
$ Ready to run your code...
Tips:
  • Use Ctrl + Enter to run code
  • Include <stdio.h> for printf/scanf
  • main() function must return int
Sample Snippets:

Detailed Explanation

Arrays and Functions

Working with Arrays and Functions in C

Arrays and functions are fundamental building blocks in C programming. Understanding how arrays interact with functions is crucial for writing efficient and maintainable code. When passing arrays to functions, C uses a special mechanism where the array name decays to a pointer to its first element, making array passing efficient but requiring careful handling.

  • Array Decay - When passed to a function, an array name decays to a pointer to its first element. The size information is lost.
  • Pass by Reference - Arrays are effectively passed by reference - functions can modify the original array elements.
  • Size Parameter - Since size information is lost, you typically need to pass the array size as a separate parameter.
  • Multi-dimensional Arrays - All dimensions except the first must be specified when passing to functions.
  • Array of Pointers - Alternative way to pass arrays, especially for strings or dynamic arrays.
  • Returning Arrays - Functions cannot directly return arrays; you return pointers (usually to dynamically allocated memory).

Key Points to Remember:

Array Decay to Pointer

int arr[5]; When passed to function: void func(int *arr) or void func(int arr[]). Both are equivalent.

Size Information Lost

sizeof(arr) inside function gives pointer size (4/8 bytes), not array size. Always pass size separately.

In-Place Modification

Arrays are passed by reference, so functions can modify the original array elements directly.

2D Array Parameter

void func(int arr[][COLS]) or void func(int (*arr)[COLS]) - column size must be specified.

Expert Interview Tips:

When explaining array passing, emphasize the efficiency aspect: 'Only the pointer is copied, not the entire array, making it O(1) regardless of array size.'

2 min read 5,800 views Performance Focus

Common mistake: Using sizeof(arr) inside function thinking it returns array size. Demonstrate with code why this fails and how to fix with separate size parameter.

2 min read 4,300 views Common Pitfall

Pro tip: Use const qualifier for input arrays: void func(const int arr[], int size). This prevents accidental modification and makes code self-documenting.

1 min read 3,500 views Best Practice

Common Follow-up Questions:

How are arrays passed to functions in C? Explain with an example.
Basic

Arrays are passed to functions by reference (actually via pointer to first element). When you pass an array name as an argument, it decays to a pointer to its first element. This means:

  • The function receives the address of the array, not a copy
  • Changes made to array elements inside the function affect the original array
  • The size information is lost, so you must pass the size separately
#include <stdio.h>

// Three equivalent ways to receive array parameter
void printArray(int *arr, int size) {
    for(int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    // sizeof(arr) here would give pointer size, not array size
}

void modifyArray(int arr[], int size) {
    for(int i = 0; i < size; i++) {
        arr[i] *= 2; // Modifies original array
    }
}

int main() {
    int numbers[] = {1, 2, 3, 4, 5};
    int size = sizeof(numbers) / sizeof(numbers[0]);
    
    printf("Original: ");
    printArray(numbers, size);
    
    modifyArray(numbers, size);
    
    printf("After modify: ");
    printArray(numbers, size);
    
    return 0;
}
πŸ’‘ The array name 'numbers' is equivalent to '&numbers[0]' when passed to a function.
What is array decay? Why does it happen and what are its implications?
Intermediate

Array decay refers to the automatic conversion of an array name to a pointer to its first element in most contexts (except when used with sizeof, & operator, or during array initialization).

Why it happens: For historical efficiency reasons. Passing entire arrays by value would be expensive in terms of time and memory. Passing a pointer is O(1).

Implications:

  • Size information is lost - must track size separately
  • Arrays are effectively passed by reference
  • The function can modify the original array
  • Cannot use sizeof to get array size inside functions
#include <stdio.h>

void demonstrateDecay(int arr[]) {
    // arr has decayed to a pointer
    printf("Inside function, sizeof(arr) = %zu bytes\n", sizeof(arr));
    printf("Inside function, arr = %p\n", (void*)arr);
}

int main() {
    int arr[10] = {0};
    
    printf("In main, sizeof(arr) = %zu bytes\n", sizeof(arr));
    printf("In main, arr = %p\n", (void*)arr);
    
    demonstrateDecay(arr);
    
    // Exception: &arr gives pointer to entire array
    int (*ptr_to_array)[10] = &arr;
    printf("&arr gives pointer to entire array: %p\n", (void*)ptr_to_array);
    
    return 0;
}
πŸ’‘ Array decay is why you can't pass arrays by value in C. The array name 'becomes' a pointer.
How do you pass multi-dimensional arrays to functions?
Intermediate

When passing multi-dimensional arrays, you must specify all dimensions except the first. This is because the compiler needs to know the size of each row to calculate correct memory offsets.

Ways to pass:

  • void func(int arr[][COLS], int rows) - Specify column size
  • void func(int (*arr)[COLS], int rows) - Pointer to array of COLS ints
  • void func(int *arr, int rows, int cols) - Flattened array (manual indexing)
#include <stdio.h>

#define COLS 3

// Method 1: Specify column size
void printMatrix(int arr[][COLS], int rows) {
    for(int i = 0; i < rows; i++) {
        for(int j = 0; j < COLS; j++) {
            printf("%d ", arr[i][j]);
        }
        printf("\n");
    }
}

// Method 2: Pointer to array
void modifyMatrix(int (*arr)[COLS], int rows) {
    for(int i = 0; i < rows; i++) {
        for(int j = 0; j < COLS; j++) {
            arr[i][j] *= 2;
        }
    }
}

// Method 3: Flattened array (for variable columns)
void printFlattened(int *arr, int rows, int cols) {
    for(int i = 0; i < rows; i++) {
        for(int j = 0; j < cols; j++) {
            printf("%d ", arr[i * cols + j]);
        }
        printf("\n");
    }
}

int main() {
    int matrix[2][COLS] = {{1, 2, 3}, {4, 5, 6}};
    
    printf("Original:\n");
    printMatrix(matrix, 2);
    
    modifyMatrix(matrix, 2);
    
    printf("\nAfter modification:\n");
    printMatrix(matrix, 2);
    
    printf("\nAs flattened array:\n");
    printFlattened((int*)matrix, 2, 3);
    
    return 0;
}
πŸ’‘ In int (*arr)[COLS], arr is a pointer to an array of COLS integers, not an array of pointers.
Can a function return an array in C? If not, what are the alternatives?
Advanced

C functions cannot directly return arrays. The alternatives are:

  1. Return a pointer to dynamically allocated memory: Use malloc inside function, return pointer. Caller must free it.
  2. Pass array as parameter (output parameter): Caller allocates array, passes it to function to fill.
  3. Return a pointer to static array: Function uses static local array. Not thread-safe and size fixed.
  4. Wrap array in struct and return struct: Works but copies entire array (inefficient for large arrays).
#include <stdio.h>
#include <stdlib.h>

// Method 1: Return pointer to dynamic memory
int* createArray(int size) {
    int *arr = (int*)malloc(size * sizeof(int));
    for(int i = 0; i < size; i++) {
        arr[i] = i * 10;
    }
    return arr; // Caller must free()
}

// Method 2: Output parameter
void fillArray(int *arr, int size) {
    for(int i = 0; i < size; i++) {
        arr[i] = i * 20;
    }
}

// Method 3: Static array (NOT recommended for production)
int* getStaticArray() {
    static int arr[5] = {100, 200, 300, 400, 500};
    return arr; // Returns pointer to static data
}

// Method 4: Wrap in struct (C99+)
typedef struct {
    int data[5];
} ArrayWrapper;

ArrayWrapper createWrappedArray() {
    ArrayWrapper aw = {{1, 2, 3, 4, 5}};
    return aw; // Returns copy of entire struct
}

int main() {
    // Method 1 usage
    int *dynamicArr = createArray(3);
    printf("Dynamic: %d, %d, %d\n", dynamicArr[0], dynamicArr[1], dynamicArr[2]);
    free(dynamicArr);
    
    // Method 2 usage
    int outputArr[3];
    fillArray(outputArr, 3);
    printf("Output param: %d, %d, %d\n", outputArr[0], outputArr[1], outputArr[2]);
    
    // Method 3 usage
    int *staticArr = getStaticArray();
    printf("Static: %d, %d, %d\n", staticArr[0], staticArr[1], staticArr[2]);
    
    // Method 4 usage
    ArrayWrapper aw = createWrappedArray();
    printf("Wrapped: %d, %d, %d\n", aw.data[0], aw.data[1], aw.data[2]);
    
    return 0;
}
πŸ’‘ Returning a pointer to a local array is a fatal error (dangling pointer) - never do that!
How do you pass an array of strings to a function?
Intermediate

There are two common ways to handle arrays of strings:

  1. 2D char array: char arr[ROWS][COLS] - Fixed maximum string length
  2. Array of char pointers: char *arr[] - Variable string lengths, can point to string literals or dynamic memory
#include <stdio.h>

// Passing 2D char array (fixed column size)
void printFixedStrings(char arr[][20], int count) {
    for(int i = 0; i < count; i++) {
        printf("%s\n", arr[i]);
    }
}

// Passing array of pointers (more flexible)
void printStringArray(char *arr[], int count) {
    for(int i = 0; i < count; i++) {
        printf("%s\n", arr[i]);
    }
}

// Sorting array of strings
#include <string.h>
void sortStrings(char *arr[], int count) {
    for(int i = 0; i < count-1; i++) {
        for(int j = i+1; j < count; j++) {
            if(strcmp(arr[i], arr[j]) > 0) {
                char *temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }
        }
    }
}

int main() {
    // 2D array (fixed size)
    char fixed[3][20] = {"Banana", "Apple", "Cherry"};
    printFixedStrings(fixed, 3);
    
    // Array of pointers (variable size)
    char *fruits[] = {"Banana", "Apple", "Cherry", "Date"};
    printf("\nBefore sorting:\n");
    printStringArray(fruits, 4);
    
    sortStrings(fruits, 4);
    
    printf("\nAfter sorting:\n");
    printStringArray(fruits, 4);
    
    return 0;
}
πŸ’‘ Array of pointers is more memory-efficient for strings of varying lengths and allows easy swapping (just pointers, not entire strings).
What is the difference between int *arr and int arr[] in function parameters?
Intermediate

In function parameters, int *arr and int arr[] are identical. Both declare arr as a pointer to int. The array notation is syntactic sugar for readability, but internally it's always a pointer.

However, there are nuances:

  • int arr[] suggests to readers that this parameter expects an array
  • int *arr makes it clear it's a pointer (could point to single int or array)
  • Both allow pointer arithmetic: arr[i] works the same
  • Both lose size information
#include <stdio.h>

// These three are EXACTLY equivalent:
void func1(int *arr, int size) {
    printf("func1: arr[0] = %d\n", arr[0]);
}

void func2(int arr[], int size) {
    printf("func2: arr[0] = %d\n", arr[0]);
}

void func3(int arr[10], int size) { // Size 10 is ignored!
    printf("func3: arr[0] = %d\n", arr[0]);
    printf("func3: sizeof(arr) = %zu (still pointer!)\n", sizeof(arr));
}

int main() {
    int nums[5] = {1, 2, 3, 4, 5};
    
    func1(nums, 5);
    func2(nums, 5);
    func3(nums, 5); // Size [10] in declaration is ignored
    
    return 0;
}
πŸ’‘ In function parameters, int arr[10] is treated as int *arr. The 10 is completely ignored by the compiler!
How can you protect array contents from modification inside a function?
Basic

Use the const qualifier to indicate that the function will not modify the array elements. This provides:

  • Protection: Compiler error if you try to modify
  • Documentation: Clear intent that array is read-only
  • Optimization: Compiler can make better assumptions
#include <stdio.h>

// Read-only array parameter
void printArray(const int arr[], int size) {
    for(int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
        // arr[i] = 100; // ERROR! Cannot modify const
    }
    printf("\n");
}

// Search function - array is read-only
int findValue(const int arr[], int size, int target) {
    for(int i = 0; i < size; i++) {
        if(arr[i] == target) {
            return i;
        }
    }
    return -1;
}

int main() {
    int numbers[] = {10, 20, 30, 40, 50};
    
    printf("Array contents: ");
    printArray(numbers, 5);
    
    int index = findValue(numbers, 5, 30);
    printf("Found 30 at index: %d\n", index);
    
    return 0;
}
πŸ’‘ Always use const for input arrays. It's a contract that says 'I promise not to modify your data'.
Question 5 of 7