Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to have a function recieve pointers as arguments?

I am currently trying to complete a Homework Assignment for one of my college courses, and am stuck.

#include <stdio.h>

void add(int *a[], const int *b[], const int *c[], int size); /* Function Prototype */

int main() {
  int a[5];
  const int b[] = {1,2,3,4,5};
  const int c[] = {1,1,1,1,1};
  add(a,b,c,5);

  for(int i=0; i < 5; i++) {
    printf("%d\t", a[i]);
  }
  return 0;
}

void add(int *a[], const int *b[], const int *c[], int size) {
  for (int i = 0; i < size; i++) {
  a[i]=b[i]+c[i];
 }
}

I am trying to have the function add receive its arguments as pointers instead of as int arrays. I have consulted the textbook, and some of my peers but I am still generally confused. If anyone could please shine some light on why my above implementation does not work?

These are the errors I get:

main.c: In function 'main':
main.c:9:7: warning: passing argument 1 of 'add' from incompatible pointer 
type [-Wincompatible-pointer-types]
   add(a,b,c,5);
   ^
main.c:3:6: note: expected 'int **' but argument is of type 'int *'
 void add(int *a[], const int *b[], const int *c[], int size); /* Function 
Prototype */
  ^~~
main.c:9:9: warning: passing argument 2 of 'add' from incompatible pointer 
type [-Wincompatible-pointer-types]
   add(a,b,c,5);
     ^
main.c:3:6: note: expected 'const int **' but argument is of type 'const int *'
 void add(int *a[], const int *b[], const int *c[], int size); /* Function 
Prototype */
  ^~~
main.c:9:11: warning: passing argument 3 of 'add' from incompatible pointer type [-Wincompatible-pointer-types]
   add(a,b,c,5);
       ^
main.c:3:6: note: expected 'const int **' but argument is of type 'const int *'
 void add(int *a[], const int *b[], const int *c[], int size); /* Function 
Prototype */
  ^~~
main.c: In function 'add':
main.c:19:14: error: invalid operands to binary + (have 'const int *' and 'const int *')
     a[i]=b[i]+c[i];
      ~~~~^~~~~

exit status 1
like image 288
RobertLD Avatar asked Feb 13 '26 08:02

RobertLD


2 Answers

According to the C Standard (6.7.6.3 Function declarators (including prototypes))

7 A declaration of a parameter as ‘‘array of type’’ shall be adjusted to ‘‘qualified pointer to type’’, where the type qualifiers (if any) are those specified within the [ and ] of the array type derivation. If the keyword static also appears within the [ and ] of the array type derivation, then for each call to the function, the value of the corresponding actual argument shall provide access to the first element of an array with at least as many elements as specified by the size expression.

So these function declarations declare the same one function

void add(int a[5], const int b[5], const int c[5], int size); 
void add(int a[5], const int b[10], const int c[15], int size); 
void add(int a[], const int b[], const int c[], int size); 

and are equivalent to the declaration

void add(int *a, const int *b, const int *c, int size); 

Take into account that according to the same C standard the function main without parameters shall be declared like

int main( void )

Also it is a bad idea to use magic "raw" numbers as 5.

The program can look like

#include <stdio.h>

void add( int *a, const int *b, const int *c, size_t size); /* Function Prototype */

#define N   5

int main( void ) 
{
    int a[N];
    const int b[N] = { 1, 2, 3, 4, 5 };
    const int c[N] = { 1, 1, 1, 1, 1 };

    add( a, b, c, N );

    for ( size_t i = 0; i < N; i++ ) 
    {
        printf( "%d\t", a[i] );
    }

    return 0;
}

void add( int *a, const int *b, const int *c, size_t size ) 
{
    for ( size_t i = 0; i < size; i++ ) 
    {
        a[i] = b[i] + c[i];
    }
}
like image 126
Vlad from Moscow Avatar answered Feb 14 '26 21:02

Vlad from Moscow


Short version:

Change your function declaration and definition from

void add(int *a[], const int *b[], const int *c[], int size)

to either

void add(int *a, const int *b, const int *c, int size)

or

void add( int a[], const int b[], const int c[], int size )

Slightly longer version

Under most circumstances, when the compiler sees an expression of type "N-element array of T", it will replace it with an expression of type "pointer to T" and the value of the expression will be the address of the first element in the array1.

Thus, in the function call

add(a,b,c,5);

each of the expressions a, b, and c is converted from "5-element array of int" to "pointer to int". So your function prototype needs to be either

void add( int *, const int *, const int *, int )

or

void add( int [], const int [], const int [], int )

In the context of a function parameter declaration, T a[N] and T a[] are interpreted as T *a - they all declare the parameter as a pointer to T, not an array of T.

The array subscript operator can be used on pointer expressions as well as array expressions, so you don't have to change the body of your add function - in fact, the subscript operator is defined in terms of pointer arithmetic. The expression a[i] is evaluated as *(a + i) - given a starting address a, offset i elements (not bytes!) from that address and dereference the result.


  1. The exception to this rule is when the array expression is the operand of the sizeof or unary & operators.

like image 44
John Bode Avatar answered Feb 14 '26 23:02

John Bode



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!