创建const元素的const数组

时间:2015-02-04 11:43:23

标签: c pointers const

我想声明一个常量char数组的常量数组。如果我这样写:

const char foo[] = "Foo";
const char bar[] = "Bar";
const char* const foobar[2] = { foo, bar };

它似乎有效,但如果我尝试使用"the spiral rule"阅读它,则foobar读作:

“foobar是一个常量(??)的数组2到指向char常量的指针”

使用此stack overflow答案,

  

const适用于它剩下的东西。如果左边没有任何内容,那么它适用于它的权利。

第一个const将应用于char,第二个const也适用于相同的char。

两种阅读方式都没有意义,但代码确实有效(至少在Arduino [抱歉])。哪个const正在制作哪个常数?是否有更合理的方式来编写它?

3 个答案:

答案 0 :(得分:8)

正如你所说:

  

const适用于它剩下的东西。如果左边没有任何内容,那么它适用于它的权利。

const char* const foobar[2] = { foo, bar };

可以重写为:

char const * const foobar[2] = { foo, bar };

现在想象一下封装const限定符和实体限定的实例:

((char const) (* const)) foobar[2] = // doesn't matter

您已经写过第二个const也适用于同一个字符。这不是真的 - 第二个const引用*,这意味着它是一个常量指针。

总而言之, foobar是一个常量字符常量指针数组

您可能还想阅读此主题:constant pointer vs pointer on a constant value

答案 1 :(得分:5)

一个挑剔但重要的观点;在C中,不可能有const数组。 (参考:C11 6.3.2.3/2)。

看起来像是一个的所有东西实际上都是一个非const数组,其元素是constLink to related discussion

在您的示例const char* const foobar[2] = { foo, bar };中,两个const关键字表示:

  • 数组中的两个指针无法指向别处
  • 这些指针指向的字符不得通过这些指针修改。

文本描述是" foobar是一个指向char常量的常量指针的数组2"。

请注意,指向的字符实际上可能是非常量char,但又有一个小而重要的区别,因为const char *可以指向const和非const。第一个const的效果是说我们可能不知道字符是否为常量,因此我们无法安全地写入它们,因此如果我们尝试将编译器生成错误使用此指针或写入它们。

答案 2 :(得分:3)

foobar是指向const的{​​{1}}指针数组。数组总是不变的,没有办法明确地使它成为const char

在函数参数的声明中,数组衰减为指针,并且const指针确实存在;在这种情况下,const可以放在const内。这些是等价的:

[]

螺旋规则并不完美(某些复杂的声明失败),我个人觉得它与限定符(void func(int foo[const]) { ... } void func(int *const foo) { ... } const等)结合起来并没有用。我不知道有什么准确地呈现规则而是语法本身(C11 6.7和6.7.6)。

然而,在这种情况下,似乎有效:

volatile

+--------------+ | +---+ | | ^ | | const char *const foobar[2] | ^ ^ | | | +----------+ | +---------------------+ 是指向foobar的{​​{1}}指针的数组(包含2个元素)。”