为什么int * ptr_arr_int = {1,2}; 在C / C ++中不起作用?

Amr*_*h A 6 c c++ pointers

为什么int* ptr_arr_int = {1,2};会出现编译器错误,但char* ptr_arr_char = "amruth";编译正常?

int* ptr_arr_int = {1,2};         // ->ERROR
char* ptr_arr_char = "amruth";    // ->OK
Run Code Online (Sandbox Code Playgroud)

Bat*_*eba 12

"amruth"const char[7]C ++中的char[7]类型,也是C中的类型(尽管尝试修改字符串的行为未定义)。

在某些情况下(例如您的情况),它可能分别衰减为a const char*char*type。

尽管在某些情况下int[2]意志与衰败类似int*{1, 2}但既不是一种int[2]也不是一种const int[2]类型。而是一个大括号初始化器


Sta*_*nny 7

如前所述,字符串是一个const char[7]数组,尽管它可以衰减为a char*{1, 2}但是不能衰减为int*(这是一个大括号初始化器列表,类似:)std::initializer_list。但是请注意,还有一个数组[]声明,它允许您自动声明数组。从C ++ 11开始,将其与列表初始化结合使用,您就可以通过[]以下两者进行初始化:

int ptr_arr_int[] = { 1,2 }; //OK
char ptr_arr_char[] = "amruth"; //OK
Run Code Online (Sandbox Code Playgroud)

  • {{1,2}`本身不是std :: initializer_list`,而是支撑的初始化列表。尽管它们具有相似的名称,但它们是不同的东西。请参阅:http://eel.is/c++draft/temp.deduct.type#5.6 (2认同)

PSk*_*cik 6

字符串本身已经暗示了一个存储类-它是使用特殊语法声明的static(有效地constchar数组。

与此相反,尚不清楚应如何存储{1, 2}in int *ptr_arr_int = {1, 2}。应该是static还是auto

如果要auto在本地作用域中或static文件作用域中使用它,则可以在C> = 99中显式地执行操作int *ptr_arr_int = &(int[]){1,2}[0];(此操作&[0]是可选的)。

可以想象,您可以将其隐式化,但是您能走多远?int ****x = {1,2};通过创建数组,指向该数组的指针,指向该数组的指针等进行初始化可能会导致int大量的代码/数据,并且在简单的结构下隐藏大量的代码/数据并不是C方式。大括号语法何时应初始化最终目标基本类型或某些中间指针也不清楚。


Lun*_*din 5

仅仅是因为语言语法如此。关于数组:

  • 我们必须使用大括号括起来的列表初始化数组{...},其中不再包含任何适合数组内部的项目。
  • 作为特殊规则,char可以使用字符串文字初始化数组"..."

但是,您的代码中没有数组,只有指针。

char*始终可以将A 设置为指向字符串文字(在C中),因此char* ptr_arr_char = "amruth";有效。但是,它是可疑的风格,因为无法修改字符串文字。正确的风格是用const char*

C ++更严格,C ++中的字符串文字具有type const char[]。如果您不使用,则C ++编译器可能会在“不建议使用的转换”方面发出警告const char*

至于int* ptr_arr_int = {1,2};,它有两个问题。

  • {1,2}是一个初始值设定项列表,但它ptr_arr_int是一个项目,因此没有任何意义。有一个特殊的奇怪规则,实际上允许我们{}在初始化单个变量时使用,但是您内部必须只有一个初始化器。
  • 您不能使用整数初始化指针。请参阅“来自整数的指针/没有转换的指针的整数”问题

如果您打算将指针指向仅存在于本地范围内的临时数组,则可以使用称为复合文字的C功能:

int* ptr_arr_int = (int[]){1,2};

但是,除非您依靠非标准扩展名,否则这不是AFAIK在C ++中可以实现的。但是,无论使用哪种语言,您当然都可以这样做:

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