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

时间:2017-11-07 20:49:05

标签: c pointers

我目前正在尝试为我的一个大学课程完成一项家庭作业,而且我被困了。

#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

3 个答案:

答案 0 :(得分:4)

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

  

7 参数声明为''数组'''应为   调整为''限定指向类型'',其中类型限定符   (如果有的话)是在数组类型的[和]内指定的那些   推导。如果关键字static也出现在[和]中   数组类型派生,然后对每个函数调用,   相应的实际参数的值应提供访问权限   数组的第一个元素,其元素至少与指定的元素一样多   按大小表达式。

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

i

并且等同于声明

sizeof

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

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

使用魔术“原始”数字作为5也是一个坏主意。

程序看起来像

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

答案 1 :(得分:3)

简短版:

更改您的功能声明和定义
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 )

版本稍长

在大多数情况下,当编译器看到类型为“{-1}}的N元素数组”的表达式时,它将用类型为“{{1的指针”的表达式替换它“和”表达式的值将是数组 1 中第一个元素的地址。

因此,在函数调用

T

每个表达式Tadd(a,b,c,5); a都是从“b的5个元素数组”转换为“指向c的指针” 。所以你的函数原型需要是

int

int

函数参数声明的上下文中,void add( int *, const int *, const int *, int ) void add( int [], const int [], const int [], int ) 被解释为T a[N] - 它们都将参数声明为指向{{}的指针1}},而不是T a[]的数组。

数组下标运算符可用于指针表达式和数组表达式,因此您不必更改T *a函数的主体 - 实际上,下标运算符是定义的< / em>就指针算术而言。表达式T被评估为T - 从该地址和解除引用中给出起始地址add,偏移a[i] 元素(不是字节!)结果。

<小时/>

  1. 此规则的例外情况是数组表达式是*(a + i)或一元a运算符的操作数。

答案 2 :(得分:1)

void add(int *a[], const int *b[], const int *c[], int size)中,像int *a[]这样的参数表示一个指向int的指针数组,而不是一个int数组。 只需声明/定义您的add - 函数为void add(int a[], const int b[], const int c[], int size) { ...,它就应该有效。