为什么我不能使用'const int *'和'const char *'一样创建一个int数组?

时间:2017-07-07 00:17:50

标签: c++ arrays pointers literals

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

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

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

4 个答案:

答案 0 :(得分:4)

“为什么”是:“因为字符串文字是特殊的”。字符串文字存储在二进制文件中,作为程序本身的常量部分,而const char *string = "Hello, World!";只是将文字视为存储在别处的匿名数组,然后它将指针存储在string中。 / p>

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

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

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

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

但直接使用文字使事情变得更清洁。

答案 1 :(得分:1)

此功能存在于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;
}

答案 2 :(得分:1)

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

{1,2,3}"abc"不是一回事。实际上,如果您想绘制比较,则应将"abc"{'a', 'b', 'c', '\0'}进行比较。它们都是有效的数组初始值设定项:

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

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

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

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

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

答案 3 :(得分:0)

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

所以这个:

const char str[6] = "hello";

完全相同:

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