创建一个由常量元素组成的常量数组

8

我希望声明一个常量字符数组的常量数组。如果我这样写:

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

看起来它可以工作,但如果我尝试使用"螺旋规则"来阅读它,foobar会被读作:

"foobar是一个指向char常量的指针数组2"

使用这个堆栈溢出的答案,

const适用于其左侧的内容。如果左侧没有任何内容,则适用于其右侧的内容。

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

两种阅读方式都没有意义,但代码确实可以运行(至少在Arduino中)。哪个const使哪个成为常量?有没有更合理的编写方式?

3个回答

11

正如您所说:

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也适用于相同的char,这是不正确的 - 第二个const 是指*,这意味着它是一个常量指针。
总的来说,foobar是一个指向常量字符的常量指针数组
你可能还想阅读这个帖子:constant pointer vs pointer on a constant value

8

一个挑剔但重要的问题:在C语言中不可能有一个const数组(参考:C11 6.3.2.3/2)。

所有看起来像是const数组的东西实际上都是非const数组,其元素为const相关讨论链接

在你的例子const char* const foobar[2] = { foo, bar };中,两个const关键字的含义如下:

  • 数组中的两个指针不能指向其他地方
  • 通过这些指针引用的字符不得被修改。

文本描述为“foobar是一个常量指向常量字符的二维数组”。

请注意再次强调的一个小但重要的区别,即被指向的字符实际上可能是非const char,因为const char *可以指向const和非const。第一个const的效果是说我们可能不知道这些字符是否为const,因此如果我们尝试使用此指针写入它们,则编译器将生成错误。


5

foobar是一个指向const charconst指针数组。 数组始终是常量,无法明确将其设置为const

在函数参数声明中,数组会衰减为指针,并且存在const指针; 在这种情况下,可以将const放在[]内。以下两个表达式是等效的:

void func(int foo[const]) { ... }
void func(int *const foo) { ... }

螺旋规则并不完美(对于某些复杂的声明会失败),我个人认为与限定符(如constvolatile等)结合使用时没有什么帮助。我不知道有什么东西能精确地呈现这些规则,除了语法本身(C11 6.7和6.7.6)。然而,在这种情况下,它似乎起作用了。
                    +--------------+
                    |      +---+   |
                    |      ^   |   |
       const char *const foobar[2] |
             ^      ^          |   |
             |      +----------+   |
             +---------------------+

"foobar 是一个包含 2 个指向 const charconst 指针的数组。"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接