Search code examples
cpointersmultidimensional-arrayimplicit-conversionfunction-definition

Understanding the syntax *y[ ] passed as parameter


I am trying to understand C code and I have stumbled across the following function definitions:

int foo(int n, double *y[]);

I am having trouble understanding how to handle and interpret *y[]. This syntax is being used in several functions but handled differently. In this example, foo1() it is used as a bidimensional array:

int foo1(int n, double *y[]){
 double var0 = 0;
 double var1 = 0;
 for (i = 0; i < n; i++) {
    var1 += y[i][1] ;
    var0 += y[i][0] ;
 }
 // do stuff
 return 0;
}

And here the same syntax is used, but *y[] is used as an array, but here they use the pointer * notation:

int foo2(int n, double *y[]){
 double var0 = 0;
 for (i = 0; i < n; i++) {
    var0 += *y[i] ;
 }
 // do stuff
 return 0;
}

Could you be so kind to provide a precise explanation of what *y[] means and why it can be used so flexibly as a function parameter?


Solution

  • This parameter declaration

    double *y[]
    

    declares an array of unknown size with elements of the type double *. That is it is an array of pointers of the type double *.

    It seems the first parameter of this function

    int foo(int n, double *y[]);
    

    that is the variable n specifies the number of elements in the array.

    This expression

    y[i]
    

    gives the i-th element of the array. as the element of the array is a pointer (for example a pointer to the first element of an array with two elements) then these expressions

    y[i][1] 
    y[i][0]
    

    yield the pointed elements.

    As for this expression

    *y[i]
    

    then it is equivalent to the expression

    y[i][0]
    

    To make it more clear I will provide a demonstrated program where instead of an array of the type double * [] there is used an array of the type char * [].

    Here you are.

    #include <stdio.h>
    
    void f( size_t n, char *  s[] )
    {
        for ( size_t i = 0; i < n; i++ )
        {
            for ( size_t j = 0; s[i][j] != '\0'; j++ )
            {
                putchar( s[i][j] );
            }
            putchar( '\n' );
        }
    }
    
    int main(void) 
    {
        char * s[] =
        {
            "Hello",
            "World"
        };
        
        f( sizeof( s ) / sizeof( *s ), s );
        
        return 0;
    }
    

    The program output is

    Hello
    World