为什么我们不能使用整数指针声明数字数组

kum*_*vam 9 c c++ arrays string pointers

char *ch = "delhi";               // valid

int *arr = {1, 2, 3};             // invalid

int *arr = (int[3]){1, 2, 3};     // valid
Run Code Online (Sandbox Code Playgroud)

为什么上述某些陈述有效而其他陈述无效?

son*_*yao 6

免责声明:我正在回答C++的问题,我认为答案在很多方面都不适用于C.

简而言之,指针和数组是不同的东西.

在c ++中,

int *arr = {1, 2, 3};无效,因为无法通过列表初始化初始化指针.

int *arr = (int[3]){1, 2, 3};是有效的,因为数组可以通过列表初始化初始化,实际上将为数组应用聚合初始化.对于这种情况,将构造一个临时数组,然后将其衰减int*并分配给arr.请注意,临时变量将在语句之后被销毁,因此arr在此之后将被悬空.

char *ch = "delhi";从c ++ 11开始const char* ch = "delhi"无效,是有效的."delhi"是一个带有类型的字符串文字const char[6],然后衰减const char*并分配给ch.因为字符串文字具有静态存储持续时间并且ch不会悬空.

请注意,它不是int指针的特殊规则,它也适用于char指针.const char* ch1 = { 'd', 'e', 'l', 'h', 'i', '\0'};也会失败.


Mik*_*eMB 1

免责声明:我正在回答 C++ 的问题 - 一些推理可能也适用于 C,但我还没有检查后者。

字符串文字(第一个示例的右侧)是(在 C++ 中)const char具有静态存储持续时间的数组。这意味着编译器将它们放置在内存中的固定位置,该位置在程序的整个执行过程中保持有效。因此,您可以像任何其他数组一样将它们分配给指针(存储第一个元素的地址)。

您的特定示例在 c++11 及更高版本中不起作用,因为ch实际上必须是类型const char*. 然而,在 C 中,据我所知,字符串文字是类型数组char(非 const),因此您也可以将它们分配给普通的charptr,并且出于兼容性原因,c++11 之前的 c++ 版本允许进行此分配。

由于多种原因,第二行是无效的 C++ 代码:与第一行相反,右侧不是数组,因此数组到指针的衰减在这里不起作用。现在您可以使用初始化列表初始化指针,但前提是

  1. 它只有一个元素
  2. 元素具有适当的类型(例如指向 int 或 的指针nullptr

但是,与第一个示例相比,含义完全不同:您不会使用初始值设定项列表中元素的地址来初始化指针,而只是使用副本

现在在第三个示例中(顺便说一下,它会被 C++ 编译器拒绝,但对于const int*和来说是可以的const int[])我相信您正在创建一个临时数组,该数组通过复制初始值设定项列表的内容(整数文字)进行初始化,然后将其分配给一个指针。恕我直言,一旦到达语句末尾,这应该会产生一个悬空指针,但我不能 100% 确定这一点。