为什么我不能使用与 'const char*' 相同的 'const int*' 创建一个 int 数组?

Why can't I make an int array using 'const int*' same as 'const char*'?

为什么我可以用这种方式创建字符串或字符数组:

#include <iostream>
int main() {
  const char *string = "Hello, World!";
  std::cout << string[1] << std::endl;
}

?并且它正确地输出了第二个元素,而没有数组的下标符号 [ ] 我不能创建整数类型的数组? char的那个和这个有什么区别:const int* intArray={3,54,12,53};.

字符串乱码来自C语言。在代码中用双引号声明的任何字符串都会自动转换为 const char[].

所以这个:

const char str[6] = "hello";

完全相同:

const char str[6] = { 'h', 'e', 'l', 'l', 'o', '[=11=]' };

C 语言中存在这样的特性,被命名为复合文字

例如

#include <stdio.h>

int main(void) 
{
    const int *intArray = ( int[] ){ 3, 54, 12, 53 };

    printf( "%d\n", intArray[1] );

    return 0;
}

但是 C++ 不支持 C 的这个特性。

与字符串文字相比有区别。字符串文字的静态存储持续时间与其出现的位置无关,而复合文字的静态存储持续时间或自动存储持续时间取决于它们出现的位置。

在 C++ 中,接近此功能的是 std::initializer_list。例如

#include <iostream>
#include <initializer_list>

int main() 
{
    const auto &myArray = { 3, 54, 12, 53 };

    std::cout << myArray.begin()[1] << std::endl;

    return 0;
}

"why" 是:"Because string literals are special"。字符串文字存储在二进制文件中,作为程序本身的常量部分,而 const char *string = "Hello, World!"; 只是将文字视为存储在别处的匿名数组,然后将指针存储在 string.

其他类型没有等效的特殊行为,但您可以通过创建一个命名的静态常量并使用它来初始化指针来获得相同的基本解决方案,例如

int main() {
  static const int intstatic[] = {3,54,12,53};
  const int *intptr = intstatic;
  std::cout << intptr[1] << std::endl;
}

static const 数组的作用是分配字符串文字将使用的相同常量 space(尽管与字符串文字不同,编译器不太可能识别重复数组并合并存储),但作为命名变量而不是匿名变量。字符串大小写可以用同样的方式显式表示:

int main() {
  static const char hellostatic[] = "Hello, World!";
  const char *string = hellostatic;
  std::cout << string[1] << std::endl;
}

但直接使用字面量会使事情变得更简洁。

几乎可以。有几件事在起作用。

{1,2,3}"abc" 不是一回事。事实上,如果要进行比较,"abc" 更应该与 {'a', 'b', 'c', '[=15=]'} 进行比较。它们都是有效的数组初始值设定项:

char foo[] = "abc";
char bar[] = {'a', 'b', 'c', '[=10=]'};

然而,只有"abc"也是C++中初始化指针的有效表达式。

在 C 中(以及作为某些 C++ 编译器(包括 Clang 和 GCC)的扩展),您可以将复合文字转换为数组类型,如下所示:

static const int* array = (const int[]){1, 2, 3};

然而,这几乎是不正确的。它在全局范围内工作并作为函数参数,但是如果您尝试用它初始化自动存储的变量(即函数内的变量),您将获得指向即将过期的位置的指针,所以你将无法将它用于任何有用的事情。