简体   繁体   English

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

[英]When passing 2d array to function what is the difference between single pointer and double pointer?

We can pass a 2d array as a single pointer and as well as a double pointer. 我们可以将2d数组作为单个指针传递,也可以传递双指针。 But in the 2nd case the output is not as expected. 但在第二种情况下,输出不如预期。 So what is wrong in the 2nd code? 那么第二个代码有什么问题?

Method 1: 方法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;
}

Output: 输出:

1 2 3 4 5 6 7 8 9

Method 2: 方法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;
}

Output: 输出:

1 3 5 7 9 3 0 -1990071075 0

The first one is undefined behavior: Accesing a 2D array using a single pointer . 第一个是未定义的行为: 使用单个指针访问2D数组

The second one is simply wrong, you can't pass a 2D array ( arr[][3] ) to an array of int pointers ( *arr[] ), take a look to Correct way of passing 2 dimensional array into a function : 第二个是完全错误的,你不能将2D数组( arr[][3] )传递给int指针数组( *arr[] ),看一下将2维数组传递给函数的正确方法

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

Must be 一定是

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

or 要么

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

But this way the column in arr[][3] must be globally defined. 但是这样,arr [] [3]中的列必须是全局定义的。 Isn't any other workaround? 没有任何其他解决方法吗?

Under C99 you can use VLA's (Variable-length array): 在C99下你可以使用VLA(可变长度数组):

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

Alter Mann is right, but the main problem in Method 2 is this code: Alter Mann是对的,但方法2中的主要问题是这段代码:

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

Since arr is now type of int *arr[] , the element size is sizeof(int *) and not sizeof(int) as in the first case. 由于arr现在是int *arr[] ,因此元素大小为sizeof(int *)而不是sizeof(int)如第一种情况。 So when fe arr = 0 , then arr + 1 equals to 0 + sizeof(int*) instead of 0 + sizeof(int) as in the first case. 因此,当fe arr = 0arr + 1等于0 + sizeof(int*)而不是0 + sizeof(int)如第一种情况。 It would work okay if the arr was casted to (int*) like: 如果arr被转换为(int*)它会工作正常:

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

TL;DR you're jumping through the array by the pointer size, not an integer size. TL; DR你用指针大小跳过数组,而不是整数大小。

My personal suggestion is to use pointers, but access it like an array: 我个人的建议是使用指针,但访问它就像一个数组:

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

This works every time unlike the pointer arithmetic that might bite you with the step size, like it did with your case. 这种方法每次都有效,不像指针算术那样可能会咬你的步长,就像你的情况一样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM