为什么我们不能将2D整数数组初始化为指针?

时间:2018-12-18 03:29:35

标签: c

为什么2D字符数组不能初始化为指针,而不能初始化为2D整数数组?为什么在尝试这样做时会出现错误?另外,将数组初始化为指针意味着什么?

#include<stdio.h>
int main()
{
    char* m[] = { "Excellent","Good", "bad" };
    int* x[] = { {1,2,3},{4,5,6} }; 
    return 0;                      
}

1 个答案:

答案 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的两件事。这些事物中的每一个本身都是一组(由三个事物组成)。但是,xint *的数组。 x的每个成员都应使用一个指针进行初始化。但是{1,2,3}这三件事并不是一个指针。

初始化数组和结构时,用于解释事物组的C规则有点复杂,因为它们旨在为省略括号提供一定的灵活性,因此我必须进一步研究该标准以解释它们在此处的应用。可以说编译器将声明解释为使用1初始化x[0]。由于1int,而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程序员在了解存储期限规则之前应避免使用复合文字。