繁体   English   中英

使用指针初始化const数组

[英]Initialize a const array with a pointer

为什么第一行有效但其余行无效。 我虽然第一个是第二个的速记。

const char *c = "abc"; // Why valid?

const char *b = { 'a' , 'b', 'c', '\0' }; // invalid

const int *a = { 1, 2, 3, 0 }; // invalid

这里真正的区别是"abc"char[]类型的字符串文字,而{'a', 'b', 'c', 0}则不是。 您可以轻松地使用它来初始化完全不同的类型,例如:

struct s{
  char c;
  int i, j;
  float f;
} x = {'a', 'b', 'c', 0};

所以当你写const char *b = { 'a' , 'b', 'c', '\\0' }; ,编译器选择隐式转换{'a'} -> 'a'并尝试用它初始化你的指针。 根据编译器和实际值,这可能会也可能不会失败,例如,许多编译器会解释const char *b = { '\\0' }; b初始化为NULL指针而不是像预期的那样将空字符串初始化。

如果要初始化指向使用列表初始化创建的数组(或任何其他类型)的地址的指针,则应显式转换:

const char *b = (const char[]){'a', 'b', 'c', 0};
const int *a = (const int[]){'a', 'b', 'c', 0};
struct s *x = &(struct s){'a', 'b', 'c', 0};

在第一种情况下,您有一个字符串文字,它是char数组,在此上下文中它将转换为指向char的指针。

在接下来的两种情况下,您尝试使用列表初始化来初始化一个指针,该指针将尝试将列表的第一个元素转换为生成警告的指针,因为char或int都不是指针,这与以下方式相同:

const char *b = 'a' ;

如果列表中有有效的指针,它对第一个元素可以正常工作,但由于你有更多的初始值而不是变量,因此格式不正确。

数组和指针不是一回事。

const char *c = "abc";

初始化带有字符串常量地址的指针。 Sting常量包含在其他地方(不在堆栈上,通常是特殊的全局常量区域)。

const char c[] = "abc";

初始化具有给定字符的chars数组(具有给定字符串的内容)。 这个将在堆栈上。

第一行是有效的,因为C标准允许创建常量字符串,因为它们的长度可以在编译时确定。

这同样不适用于指针:编译器无法决定是否应该为堆中的数组(例如,正常的int [] )或常规内存中分配内存,如malloc()

如果将阵列初始化为:

   int a[] = { 1, 2, 3, 0 };

然后它变得有效,因为现在编译器确定你想在堆(临时)内存中有一个数组,并且在你离开声明它的代码部分后它将从内存中释放出来。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM