(gcc)用于无警告编译的多点阵列或双指针

时间:2010-03-26 01:01:37

标签: c arrays pointers

我有一个函数,有时使用常规的,有时是动态的数组调用。

如果我将函数定义为

function_name(int[10][10] a)

并发送int **作为参数,我收到警告。相反,如果我宣布

function_name(int** a)

并发送int [] []作为参数(在转换后)我无法访问函数内的数组元素。

最正确的方法是什么?

2 个答案:

答案 0 :(得分:1)

int **int [][]不一样。 前者是pointer to pointer to int,而第二个是int的二维数组。

int[][] decays to int (*)[] when you pass it as argument to function.

void func(int arr[][10]) { //decays to `int (*arr)[10]` 
  printf("%d correct", arr[1][9]); //10th element of 2nd row
  //printf("%d correct", (*(arr + 1))[9]); //same as above
}

int main() {
  int (*arr)[10]; //pointer to array of ints
  arr = malloc(sizeof(int (*)[]) * 2); //2 rows & malloc will do implicit cast.

  arr[1][9] = 19;
  func(arr);

  return 0;
}

答案 1 :(得分:1)

当一个数组传递给一个函数时,它“衰减”到指向它的第一个元素的指针。所以,给定:

T a[10];
f(a);

在通话f(a)中,a实际上是&a[0],即指针,类型为T *&a[0]的类型)。

如果有数组数组,则应用相同的规则:

T a[10][5];
f(a);

a再次衰减指针,等于&a[0]a[0]的类型为“T的数组[5]”。所以,&a[0]的类型为“T的数组[5]的指针”,即,如果要将指针p声明为等于&a[0],则会这样做:

T (*p)[5]; /* parentheses because [] binds tighter than * */
p = &a[0];

鉴于上述情况,并假设您的数组在调用代码中声明为int a[10][10];,您应该将您的函数声明为:

function_name(int (*a)[10]);

有关详情,请参阅this

function_name(int[10][10] a)中存在语法错误 - 您需要在“变量”名称后指定数组大小:function_name(int a[10][10])。事实上,由于上​​面提到的“腐朽”,上述内容相当于function_name(int (*a)[10])

编辑:啊,我想我现在明白了。由于上面提到的原因,你不能声明一个同时采用“二维”数组和指向指针的函数(指针的“衰减”只发生一次)。指向指针的指针可能不指向连续数据,并且可能在每个“行”中具有不同数量的元素。数组数组不能具有这些属性。它们根本不同。