片段1:
char** x;
char arr[][4] = {"abc","def"};
x = arr; // why is this wrong ? but;
片段2:
char* x;
char arr[4] = {"def"};
x = arr; // this is correct
那么我们如何将2d数组分配给双指针(对于任何多维数组)?
此外,我有一个结构,我想按以下方式分配作业:
struct document
{
char **text;
int numOfLines;
};
char arr[3][50] = {
"IF WE COULD TAKE THE TIME",
"TO LAY IT ON THE LINE",
"I COULD REST MY HEAD" };
t->text = arr; // I think it is the same problem
但是我们可以直接将双指针分配为:
t->text = { "IF WE COULD TAKE THE TIME", "TO LAY IT ON THE LINE", "I COULD REST MY HEAD" };
这也为什么起作用:
char *arr[3] = {
"IF WE COULD TAKE THE TIME",
"TO LAY IT ON THE LINE",
"I COULD REST MY HEAD" };
t->text = arr;
答案 0 :(得分:3)
声明char **x;
表示指向指针的指针,而char arr[][4];
是指向数组的指针。
下面的代码有效。
#include <stdio.h>
int main(void)
{
char (*x)[10];
char arr1[][10] = {{"First"}, {"Second"}};
x = arr1;
printf("%s\n%s\n", arr1[0], arr1[1]);
printf("%s\n%s\n", x[0], x[1]);
return 0;
}
答案 1 :(得分:1)
char arr[][4] = {"abc","def"};
将arr
定义为数组数组。对于其他对象(例如结构),可以使用C
将一个结构(例如B
)分配给相同类型的另一个结构(例如B = C;
)。但是,C对于数组有特殊的规则。
在表达式中使用数组时,它将自动转换为指向其第一个元素的指针,除非它是sizeof
或一元&
的操作数,或者是用于初始化数组。所以,当我们写的时候:
x = arr;
自动转换使它就像我们编写的一样:
x = &arr[0];
然后,由于&arr[0]
是指向4 char
的数组的指针,因此x
也必须是指向4 char
的数组的指针(或兼容的指针,也许是指向未知数char
的数组的指针。)
请注意,char **x;
声明了一个指向指针的指针。也就是说,它是一个指针,并且在它指向的内存上必须有另一个指针。相反,&arr[0]
是指向数组的指针。它是一个指针,并且在它指向的内存中有一个数组4 char
。如果尝试使用**x
,则编译器将查看x
指向的内存,并期望在那里找到一个指针。相反,如果没有指针而是四个任意char
值,则程序将被破坏。因此char **x
与指向4个char
数组的指针不兼容。
x
的正确声明为char (*x)[4];
。在这样的声明之后,赋值x = arr;
将是正确的。
您的代码t->text = { "IF WE COULD TAKE THE TIME", "TO LAY IT ON THE LINE", "I COULD REST MY HEAD" };
不严格符合C,并且不能在典型的编译器中编译。
考虑代码(已调整为允许编译):
struct document
{
char **text;
int numOfLines;
} t;
char *arr[3] = {
"IF WE COULD TAKE THE TIME",
"TO LAY IT ON THE LINE",
"I COULD REST MY HEAD" };
t.text = arr;
char *arr[3]
声明arr
是指向char
的3个指针的数组。然后将其初始化为包含三个指向字符串(第一个字符)的指针。
因此arr
,arr[i]
的每个元素都是指向char
的指针。根据C的关于数组自动转换的规则,在t.text = arr;
中,arr
被转换为指向其第一个元素的指针。因此,我们有了t.text = &arr[0];
。那么&arr[0]
是指向char
的指针,而t.text
是指向char
的指针,因此类型兼容。