传递2d数组函数时单指针和双指针有什么区别?

时间:2015-02-24 08:35:48

标签: c arrays function pointers

我们可以将2d数组作为单个指针传递,也可以传递双指针。但在第二种情况下,输出不如预期。那么第二个代码有什么问题呢?

方法1:

#include <stdio.h>
void print(int *arr, int m, int n)
{
    int i, j;
    for (i = 0; i < m; i++)
      for (j = 0; j < n; j++)
        printf("%d ", *((arr+i*n) + j));
}

int main()
{
    int arr[][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
    int m = 3, n = 3;
    print((int *)arr, m, n);
    return 0;
}

输出:

1 2 3 4 5 6 7 8 9

方法2:

#include <stdio.h>
void print(int *arr[], int m, int n)
{
    int i, j;
    for (i = 0; i < m; i++)
      for (j = 0; j < n; j++)
        printf("%d ", *((arr+i*n) + j));
}

int main()
{
    int arr[][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
    int m = 3;
    int n = 3;
    print((int **)arr, m, n);
    return 0;
}

输出:

1 3 5 7 9 3 0 -1990071075 0

2 个答案:

答案 0 :(得分:5)

第一个是未定义的行为:Accesing a 2D array using a single pointer

第二个是完全错误的,你不能将2D数组(arr[][3])传递给int指针数组*arr[]),看看{{3 }}:

void print(int *arr[], int m, int n)

必须

void print(int arr[][3], int n) /* You don't need the last dimesion */

void print(int (*arr)[3], int n) /* A pointer to an array of integers */
  

但是这样,arr [] [3]中的列必须是全局定义的。是不是   任何其他解决方法?

在C99下你可以使用VLA(可变长度数组):

void print(int rows, int cols, int arr[rows][cols])

答案 1 :(得分:1)

Alter Mann是对的,但方法2中的主要问题是这段代码:

*((arr+i*n) + j)

由于arr现在是int *arr[]的类型,因此元素大小为sizeof(int *)而不是sizeof(int),与第一种情况相同。所以当f.e. arr = 0,然后arr + 1等于0 + sizeof(int*),而不是第一种情况中的0 + sizeof(int)。如果将arr投放到(int*),则可以正常工作:

*(((int *)arr+i*n) + j)

TL; DR你按指针大小跳过数组,而不是整数。

我的个人建议是使用指针,但是像数组一样访问它:

int *arr[];
return arr[i][j];

这种方法每次都有效,不像指针运算那样可能会让步长变大,就像你的情况一样。