如何让函数接收指针作为参数?

How to have a function recieve pointers as arguments?

我目前正在尝试完成我的一门大学课程的家庭作业,但卡住了。

#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];
 }
}

我正在尝试让函数 add 接收其参数作为指针而不是 int 数组。我已经查阅了教科书和我的一些同行,但我仍然普遍感到困惑。如果有人可以阐明为什么我的上述实现不起作用?

这些是我得到的错误:

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

void add(int *a[], const int *b[], const int *c[], int size)中,像int *a[]这样的参数表示指向整数的指针数组,而不是整数数组。 简单地 declare/define 你的 add-函数就像 void add(int a[], const int b[], const int c[], int size) { ... 一样,它应该可以工作。

短版:

更改您的函数声明和定义
void add(int *a[], const int *b[], const int *c[], int size)

要么

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

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

稍长的版本

在大多数情况下,当编译器看到 表达式 类型 "N-element array of T" 时,它会用类型 "pointer to T" 和值的表达式替换它表达式的将是数组中第一个元素的地址1.

因此,在函数调用

add(a,b,c,5);

每个表达式 abc 都从“int 的 5 元素数组”转换为 "pointer to int"。所以你的函数原型需要是

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

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

函数参数声明的上下文中 T a[N]T a[] 被解释为 T *a - 它们都将参数声明为指向 T 的指针,而不是 T.

的数组

数组下标运算符可用于指针表达式和数组表达式,因此您不必更改 add 函数的主体 - 事实上,下标运算符是 根据指针算法定义。表达式 a[i] 被评估为 *(a + i) - 给定起始地址 a,偏移量 i elements(不是字节!)处理并取消引用结果。


  1. 此规则的例外情况是数组表达式是 sizeof 或一元 & 运算符的操作数。

根据 C 标准(6.7.6.3 函数声明符(包括原型))

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.

所以这些函数声明声明了同一个函数

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); 

并且等同于声明

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

考虑到根据相同的 C 标准,不带参数的函数 main 应声明为

int main( void )

此外,将魔术 "raw" 数字用作 5 也是一个坏主意。

程序可以看起来像

#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];
    }
}