为什么2D字符数组不能初始化为指针,而不能初始化为2D整数数组?为什么在尝试这样做时会出现错误?另外,将数组初始化为指针意味着什么?
#include<stdio.h>
int main()
{
char* m[] = { "Excellent","Good", "bad" };
int* x[] = { {1,2,3},{4,5,6} };
return 0;
}
答案 0 :(得分:4)
在声明的上下文中,{
和}
仅表示“这里是一组事物”。它们不表示对象,地址或数组。 (注意:在初始化中,有一些表达式,并且这些表达式可以在确实代表对象的某些上下文中包含花括号。但是,在问题所示的代码中,花括号只是对事物进行了分组。)
在char* m[] = { "Excellent","Good", "bad" };
中,列出了三个项目来初始化m
:"Excellent"
,"Good"
和"bad"
。因此,每个项目都会初始化m
的一个元素。
"Excellent"
是字符串文字。在编译过程中,它成为字符数组,以空字符终止。在某些情况下,数组会保留为数组:
sizeof
的操作数时。&
的操作数(用于接收地址)。这些都不适用于这种情况。 "Excellent"
不是sizeof
的操作数,也不是&
的操作数,它只是初始化m
的一个元素,而不是整个数组。因此,该数组不会保留为数组:根据C中的规则,它会自动转换为指向其第一个元素的指针。然后,该指针将初始化m[0]
:m[0]
是指向"Excellent"
第一个元素的指针。
类似地,m[1]
初始化为指向"Good"
的第一个元素的指针,而m[2]
初始化为指向"bad"
的第一个元素的指针。 >
在int* x[] = { {1,2,3},{4,5,6} };
中,列出了用于初始化x
的两件事。这些事物中的每一个本身都是一组(由三个事物组成)。但是,x
是int *
的数组。 x
的每个成员都应使用一个指针进行初始化。但是{1,2,3}
这三件事并不是一个指针。
初始化数组和结构时,用于解释事物组的C规则有点复杂,因为它们旨在为省略括号提供一定的灵活性,因此我必须进一步研究该标准以解释它们在此处的应用。可以说编译器将声明解释为使用1
初始化x[0]
。由于1
是int
,而x[0]
是int *
,因此编译器会抱怨类型不匹配。
char *m[]
没有声明二维数组。它是指向char
的指针的数组。由于C的规则,通常可以在语法上以与二维数组相同的方式使用它,因此m[i][j]
挑选出字符串j
的字符i
。但是,char *m[]
和char a[3][4]
之间存在差异,例如:
m[i][j]
中,m[i]
是一个指针。该指针是从内存中加载的,并用作[j]
的基地址。然后将j
添加到该地址,并从内存中加载该字符。 此评估中有两个内存负载。 a[i][j]
中,a[i]
是一个数组。此数组的位置是从a
开始通过算术计算得出的。那么a[i][j]
是char
,其地址是通过加上j
来计算的,并且那里的字符是从内存中加载的。 此评估中有一个内存负载。 有一种语法可以初始化int
指针数组,以指向int
数组。它称为复合文字。这是很少使用的:
int *x[] = { (int []) {1, 2, 3}, (int []) {4, 5, 6} };
这些字符串文字和复合文字之间的关键区别在于,字符串文字定义了在程序执行的整个生命周期内存在的对象,但是函数内部使用的复合文字具有自动存储持续时间-当函数返回时,它将消失。较早,具体取决于使用位置。新手C程序员在了解存储期限规则之前应避免使用复合文字。