[英]passing 2D array pointer to function in C
我正在尝试将二维数组的地址传递给 C 中的函数。我将二维数组初始化为:
const int N = 3;
char t[N][N];
我尝试将其转换为字符***:
char*** t_ptr = &t;
但它失败了:
warning: initialization from incompatible pointer type
我想接收数组的函数有一个原型,例如:
void f(char*** t, int N) { ... };
我究竟做错了什么? 谢谢你。
这个
char*** t_ptr = &t;
编译器指出是错误的,因为t
是一个二维数组,而不是像char***
这样的三重指针,而是使用指向数组的指针来指向它。 例如
char t[3][3] = { "ab","de","gh"}; /* total 3 1D array & each 1D array has 3 elements */
char (*t_ptr)[3] = t; /* t_ptr is a pointer to an array, pointing to 3 elements at a time */
你可以像打印t_ptr
一样
for(int index = 0; index < 3 ; index++) {
printf("%s\n",t_ptr[index]);
}
阅读c声明,可以访问: https : //cdecl.org/
现在使用@Achal 的示例数组:
#include <stdio.h>
#include <stdlib.h>
int main()
{
// t is a 2D array (not a VLA)
char t[3][3] =
{
{'a', 'b', '\0'},
{'d', 'e', '\0'},
{'g', 'h', '\0'}
};
printf("t is composed of 3 arrays of 3 characters each,\n");
printf("with the following addresses (on my machine):\n");
printf("--------------------------------------------------\n");
printf("%p, %p, %p\n", t[0], t[1], t[2]);
// ------------------------------------------------
// p is an array of 3 char pointers or char*
// Notice initialization
char* p[3] = {t[0], t[1], t[2]};
// following line of code will break, if no '\0' is encountered
// since %s requires a char* and a null terminator
printf("\nPrint strings using p:\n");
printf("------------------------\n");
printf("%s, %s, %s\n", *p, *(p + 1), *(p + 2));
// ------------------------------------------------
// q is a pointer to a char* or q has type char**
// Notice initialization of q (q points to p)
char** q = p;
printf("\nUsing q:\n");
printf("-----------\n");
printf("%s, %s, %s\n", *q, *(q + 1), *(q + 2));
// ---------------- printing characters individually
printf("\nIndividually:\n");
printf("---------------\n");
for(int i = 0; i < 2; i++)
{
for(int j = 0; j < 2; j++)
{
printf("%c ",
*(*(q + i) + j)
);
}
printf("\n");
}
// -----------------------------------------------
// r is a pointer to an array of size 3 containing char
// r advances three char at a time (r doesn't know the size of t)
char (*r)[3] = t; // this is the type of t
printf("\nUsing r:\n");
printf("---------------\n");
printf("%p, %p, %p\n", *r, *(r + 1), *(r + 2));
// to extract chars
printf("%c, %c", *(*(r + 0) + 0), *(*(r + 2) + 1));
// -----------------------------------------------
return EXIT_SUCCESS;
}
输出:
t is composed of 3 arrays of 3 characters each, with the following addresses (on my machine): -------------------------------------------------- 000000000022FE2F, 000000000022FE32, 000000000022FE35 Print strings using p: ------------------------ ab, de, gh Using q: ----------- ab, de, gh Individually: --------------- a b d e Using r: --------------- 000000000022FE2F, 000000000022FE32, 000000000022FE35 a, h Process returned 0 (0x0) execution time : -0.000 s Press any key to continue.
char t[N][N];
实际上是一样的
char t[N * N];
在记忆中。 在这两种情况下,指向此类数组的指针都是char *
类型。
char ***
是指向指针的指针,即指向 char 的指针,而char *
是指向char *
的指针,这就是您在 C 中传递数组引用的方式:您将它们作为指向第一个元素的指针传递数组,第一个元素是一个字符。
一旦将数组传递给函数,C 就无法保留数组的确切类型或结构。 在内存中,字符数组只是一堆充满字符的内存,您可以传递的只是指向该内存的指针。 如果该内存是char []
或char [][]
甚至char [][][]
不起作用,则在内存中所有这三个都是一个充满字符的块,该函数必须明确知道内存中的结构,否则对于函数,所有 char 数组将始终为char []
。
我强烈不鼓励 C 初学者使用多维数组。 代替
char t[N][N];
char c = t[y1][x1];
t[y2][x2] = 'X';
用
char t[N];
char c = t[y1 * N + x1];
t[y2 * N + x2] = 'X';
因为这基本上是编译器在内部会做的事情。
注意C中的多维数组不是xy,而是yx,第一个值是行,第二个是列, 请看这个教程。
谁不相信我刚才说的话,试试这个代码:
int main ( ) {
char a[5][5];
for (int y = 0; y < 5; y++) {
for (int x = 0; x < 5; x++) {
a[y][x] = x + 10 * y;
}
}
for (int y = 0; y < 5; y++) {
for (int x = 0; x < 5; x++) {
printf("%02d ", a[y][x]);
}
printf("\n");
}
printf("------\n");
char * a2 = (char *)a;
for (int y = 0; y < 5; y++) {
for (int x = 0; x < 5; x++) {
printf("%02d ", a2[y * 5 + x]);
}
printf("\n");
}
}
您可以在线运行它,如果您愿意,输出是相同的。 还可以查看编译器为任一循环(例如gcc -S
)生成的汇编代码,您会发现它几乎相同,因为即使在第一种情况下,编译器也使用add
和mul
指令访问正确的内存位置大批。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.