Passing Arrays

From C

Jump to: navigation, search

Array types as arguments

Objects with an array type can't be passed to functions as array types, when such an object is being used as an argument in a function call it's being implicitly converted to a pointer type to the first element of the array type. In the following code sample both of the function calls are exactly the same.

Note: expressions that have an array type are being implicitly converted to a pointer type to the first element of the array, there are exceptions to this rule (for example, when it's the type of the operand of the operators sizeof and &).

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

void func(int *p) {
    printf("%d %d %d\n", p[0], p[1], p[2]);
}

int main(void) {
    int array[3] = { 1, 2, 3 };
    
    func(array);     //this function call is exactly the same
    func(&array[0]); //as this function call.
    
    return 0;
}

Array types in prototypes

In this code sample the prototype of 'func' makes it rather clear that the expected type of the argument is a pointer type and not an array type. But the prototype could've used an array type for its parameter 'p' just the same, and the meaning would've been identical. Both of the following functions expect a pointer type as the type of their arguments:

void func1(int *p) {
    printf("%d %d %d\n", p[0], p[1], p[2]);
}

void func2(int p[3]) {
    printf("%d %d %d\n", p[0], p[1], p[2]);
}

Passing the length of the array

We can't pass array types to functions, and we can't return array types. The main difference between accessing objects with their array types, and accessing them with a pointer to their first member is that we can't compute the number of elements the array has. The common convention is to pass the number of the elements the array has as a secondary argument.

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

#define array_len(a) (sizeof a / sizeof *a)

void func(int *p, size_t n) {
    for (size_t i = 0; i < n; i++)
        printf("%d ", p[i]);
}

int main(void) {
    int array[3] = { 1, 2, 3 };
    
    func(array, array_len(array));
    
    return 0;
}

The function-like macro array_len() should be used only with objects with an array type, and shouldn't be used with pointer types. Which means that within this code sample we can only use it in main() because 'array' has an array type, and we can't use it in func() because there 'p' has a pointer type.

Passing multidimensional arrays

When we pass an object with an array of arrays type (multidimensional) we still pass a pointer to the first element of the array type, but the first element of 'array' is not an 'int', it's an array type of 4 int elements, and therefore its type is: int (*)[4].

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

void func(int (*p)[4]) {
    printf("%d\n", p[1][3]);
}

int main(void) {
    int array[2][4] = { 0 };
    
    array [1][3] = 123;
    
    func(array);
    
    return 0;
}

Encapsulating array types inside structure types

Unlike array types, structure types can be passed to functions as arguments- and can be returned from functions. It's possible to encapsulate an array type within a struct for the purpose of passing it to a function, but it's not a common convention.

Personal tools