【问题标题】:How are these two definitions different to the compiler?这两个定义与编译器有何不同?
【发布时间】:2016-09-17 13:06:54
【问题描述】:

这个说法是正确的:

char *c[3] = {"abcd", "efgh", "jklm",};

这个虽然结构相似,但编译器不喜欢它。

int *a[3] = {{48,49,50,51}, {5,6,7,8}, {9,10,11,12},};

它们有何不同?编译器不能从 a 的初始化中推断出大小吗?

在我看来,编译器对char * 的处理方式不同。

【问题讨论】:

  • 你可以使用复合文字int *a[3] = {(int[4]){48,49,50,51}, ...}
  • 数组不是指针(反之亦然)!

标签: c


【解决方案1】:

与 C 字符串文字不同,它产生一个以空值结尾的数组,该数组“衰减”为指针。为了获得与整数相同的功能,您需要使用复合文字。

C 编译器将为"abcd" 及其空终止符分配内存,并为您提供指针。但是,编译器不会为整数数组 {48,49,50,51} 分配内存,除非您告诉它字面量表示整数数组:

int *a[3] = {
    (int[]){48,49,50,51}
,   (int[]){5,6,7,8}
,   (int[]){9,10,11,12}
};

此功能在 C99 和更新版本中可用。如果您使用的是较旧的编译器,并且希望 a[] 成为指针数组,则需要单独分配其元素:

static int a0[] = {48,49,50,51};
static int a1[] = {5,6,7,8};
static int a2[] = {9,10,11,12};
int *a[] = {a0, a1, a2};

这可以让您创建一个“锯齿状”数组。如果您不想要锯齿状数组,因为a[] 中的所有行的大小都与4 相同,您可以创建一个常规的 3x4 数组。

【讨论】:

  • 尚不清楚为什么字符串文字数组会衰减为指针(它们不会“产生指针”),但整数数组不会。实际原因更加微妙,因为编译器无法推断大括号中的整数是int-array。这是模棱两可的。
  • "decuce" -> "推断"
  • 复合文字不是扩展。它们是 C99 的一部分,如 C99 草案标准 n1256 6.5.2.5 复合文字所示
  • @EOF 啊,酷! GNU 页面说“作为 GNU 扩展,GCC 允许通过复合文字初始化具有静态存储持续时间的对象(这在 ISO C99 中是不可能的,因为初始化器不是常量)”,所以我认为这将适用于“嵌套" 也是初始化器中的复合文字。显然,它没有!我将编辑答案以包含此内容。谢谢!
  • @Olaf 整数数组确实衰减为指针。这就是int *a[3] = { (int[]){48,49,50,51} 发生的事情
猜你喜欢
  • 2012-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-23
  • 2015-10-21
  • 1970-01-01
  • 1970-01-01
  • 2016-02-10
相关资源
最近更新 更多