Arrays as Arguments

Arrays can be passed as arguments to functions and subroutines. When doing so, we need to also send the dimensions of the array. We will need the size in order to properly set up loops inside the subprogram that access the array.

In C, a one-dimensional array argument need not be given a size. This allows a function to work with arrays of any size, so long as it is told the size of each array when it is called.

#define     MAX_TEMPS   1000

int     main()

{
    double  temps[MAX_TEMPS];
    
    print_list(temp, MAX_TEMPS);
    return EX_OK;
}


void    print_list(double list[], size_t list_size)

{
}
        

Note that we we pass an array to a function, we are not copying the array to the function's argument variable. Passing an array itself by value would mean duplicating the entire contents of the array, which would be very inefficient for large arrays.

Remember that an array name in C is a pointer constant. It represents the address of the array, whereas a scalar variable name represents the value contained in it. When we use an array name as an argument to a function, we are passing the address of the array, much like we did explicitly with our swap() function example:

int     a, b;

swap(&a, &b);
        

In fact, we could declare the function argument variable as a pointer rather than an array. The following would be essentially identical to the example above:

void    print_list(double * const list, size_t list_size)

{
}
        

Note

The trick to understanding the use of const with pointers is to read it backwards. The above says "list is a constant pointer to a double".

Since we are passing the address of an array, the array contents are not protected from side effects. When we pass an array to a function, the function may be able to modify it.

We can protect against this by declaring the argument variable as an array of constants:

void    print_list(const double list[], size_t list_size)

{
}
        

Note

Again, reading this backwards, we see that "list is a pointer to a double constant", meaning that the data it points to is constant. Since list is declared as an array, the address is also constant. We can neither make change where list points, nor change the content of what it points to.

If we inadvertently try to modify the contents of list[] in the print_list() function, we will now get a compiler error.

Fortran does require a size for an array argument. However, since arguments are never without a value, the array size argument can be used to declare the array in Fortran. Array dimensions can be variables, as long as they have a known value. We must also declare the size argument before the array, so that the compiler has seen it before it encounters the array declaration.

program array_arguments

    double precision, allocatable :: temps(:)
    integer :: num_temps
    
    ...
    
    call print_list(temps, num_temps)
    
    ...
    
end program

subroutine print_list(list, list_size)

    ! Define list_size before list
    integer, intent(in) :: list_size
    double precision, intent(in) :: list(1:list_size)
    
    integer :: i
    
    do i = 1, list_size
        print *, list(i)
    enddo

end subroutine