将二维数组传递给函数时,单指针和双指针有什么区别?
When passing 2d array to function what is the difference between single pointer and double pointer?
我们可以将二维数组作为单指针和双指针传递。但在第二种情况下,输出不符合预期。那么第二个代码有什么问题?
方法一:
#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
方法二:
#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
第一个是未定义的行为:Accesing a 2D array using a single pointer。
第二个完全错误,你不能将二维数组(arr[][3]
)传递给int
指针数组(*arr[]
),看看Correct way of passing 2 dimensional array into a function:
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 */
But this way the column in arr[][3] must be globally defined. Isn't
any other workaround?
在 C99 下,您可以使用 VLA(可变长度数组):
void print(int rows, int cols, int arr[rows][cols])
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];
这每次都有效,不像指针算法那样可能会影响您的步长,就像您的情况一样。
我们可以将二维数组作为单指针和双指针传递。但在第二种情况下,输出不符合预期。那么第二个代码有什么问题?
方法一:
#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
方法二:
#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
第一个是未定义的行为:Accesing a 2D array using a single pointer。
第二个完全错误,你不能将二维数组(arr[][3]
)传递给int
指针数组(*arr[]
),看看Correct way of passing 2 dimensional array into a function:
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 */
But this way the column in arr[][3] must be globally defined. Isn't any other workaround?
在 C99 下,您可以使用 VLA(可变长度数组):
void print(int rows, int cols, int arr[rows][cols])
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];
这每次都有效,不像指针算法那样可能会影响您的步长,就像您的情况一样。