创建 const 元素的 const 数组
Creating a const array of const elements
我想声明一个常量字符数组的常量数组。如果我这样写:
const char foo[] = "Foo";
const char bar[] = "Bar";
const char* const foobar[2] = { foo, bar };
它似乎有效,但如果我尝试使用 "the spiral rule" 读取它,foobar 被读取为:
"foobar is an array 2 of constant (??) to a pointer to a char constant"
使用这个 stack overflow 答案,
const applies to the thing left of it. If there is nothing on the left then it applies to the thing right of it.
第一个 const
将应用于字符,第二个 const
也将应用于相同的字符。
两种阅读方式都没有意义,但代码确实起作用(至少在 Arduino [抱歉] 中)。哪个 const
使哪个成为常量?有没有更合乎逻辑的写法?
正如您所说:
const applies to the thing left of it. If there is nothing on the left then it applies to the thing right of it.
const char* const foobar[2] = { foo, bar };
可以重写为:
char const * const foobar[2] = { foo, bar };
现在想象一下封装 const
限定符和限定实体的括号:
((char const) (* const)) foobar[2] = // doesn't matter
您已经写到第二个常量也适用于同一个字符。这不是真的 - 第二个 const
指的是 *
,这意味着它是一个常量指针。
总而言之,foobar
是指向常量字符的常量指针数组。
您可能还想阅读此主题:constant pointer vs pointer on a constant value .
foobar
是指向 const char
的 const
指针数组。数组始终是常量,无法显式地使其成为 const
.
在函数参数声明中,数组衰减为指针,const
指针确实存在;在这种情况下,const
可以放在 []
内。这些是等价的:
void func(int foo[const]) { ... }
void func(int *const foo) { ... }
螺旋规则并不完美(对于一些复杂的声明它会失败),我个人认为它与限定符(const
、volatile
等)结合使用没有帮助。除了语法本身(C11 6.7 和 6.7.6)之外,我不知道有什么能准确地呈现规则。
然而,在这种情况下,它似乎有效:
+--------------+
| +---+ |
| ^ | |
const char *const foobar[2] |
^ ^ | |
| +----------+ |
+---------------------+
"foobar
是 const
指向 const char
的数组(有 2 个元素)。"
一个挑剔但重要的观点;在 C 中,不可能有 const
数组。 (参考:C11 6.3.2.3/2)。
所有看起来可能是一个的东西实际上是一个非常量数组,其元素是 const
。 。
在您的示例 const char* const foobar[2] = { foo, bar };
中,两个 const
关键字的意思是:
- 数组中的两个指针不能指向别处
- 这些指针指向的字符不能通过这些指针修改。
文字说明为"foobar is an array 2 of constant pointer to a char constant"。
再次注意一个小但重要的区别,指向的字符实际上可能是非常量 char
,因为 const char *
可以指向常量和非常量。第一个 const
的作用是说我们可能不知道字符是否为 const,因此我们不能安全地写入它们,所以如果我们尝试使用它,编译器会产生错误指针未写入它们。
我想声明一个常量字符数组的常量数组。如果我这样写:
const char foo[] = "Foo";
const char bar[] = "Bar";
const char* const foobar[2] = { foo, bar };
它似乎有效,但如果我尝试使用 "the spiral rule" 读取它,foobar 被读取为:
"foobar is an array 2 of constant (??) to a pointer to a char constant"
使用这个 stack overflow 答案,
const applies to the thing left of it. If there is nothing on the left then it applies to the thing right of it.
第一个 const
将应用于字符,第二个 const
也将应用于相同的字符。
两种阅读方式都没有意义,但代码确实起作用(至少在 Arduino [抱歉] 中)。哪个 const
使哪个成为常量?有没有更合乎逻辑的写法?
正如您所说:
const applies to the thing left of it. If there is nothing on the left then it applies to the thing right of it.
const char* const foobar[2] = { foo, bar };
可以重写为:
char const * const foobar[2] = { foo, bar };
现在想象一下封装 const
限定符和限定实体的括号:
((char const) (* const)) foobar[2] = // doesn't matter
您已经写到第二个常量也适用于同一个字符。这不是真的 - 第二个 const
指的是 *
,这意味着它是一个常量指针。
总而言之,foobar
是指向常量字符的常量指针数组。
您可能还想阅读此主题:constant pointer vs pointer on a constant value .
foobar
是指向 const char
的 const
指针数组。数组始终是常量,无法显式地使其成为 const
.
在函数参数声明中,数组衰减为指针,const
指针确实存在;在这种情况下,const
可以放在 []
内。这些是等价的:
void func(int foo[const]) { ... }
void func(int *const foo) { ... }
螺旋规则并不完美(对于一些复杂的声明它会失败),我个人认为它与限定符(const
、volatile
等)结合使用没有帮助。除了语法本身(C11 6.7 和 6.7.6)之外,我不知道有什么能准确地呈现规则。
然而,在这种情况下,它似乎有效:
+--------------+
| +---+ |
| ^ | |
const char *const foobar[2] |
^ ^ | |
| +----------+ |
+---------------------+
"foobar
是 const
指向 const char
的数组(有 2 个元素)。"
一个挑剔但重要的观点;在 C 中,不可能有 const
数组。 (参考:C11 6.3.2.3/2)。
所有看起来可能是一个的东西实际上是一个非常量数组,其元素是 const
。
在您的示例 const char* const foobar[2] = { foo, bar };
中,两个 const
关键字的意思是:
- 数组中的两个指针不能指向别处
- 这些指针指向的字符不能通过这些指针修改。
文字说明为"foobar is an array 2 of constant pointer to a char constant"。
再次注意一个小但重要的区别,指向的字符实际上可能是非常量 char
,因为 const char *
可以指向常量和非常量。第一个 const
的作用是说我们可能不知道字符是否为 const,因此我们不能安全地写入它们,所以如果我们尝试使用它,编译器会产生错误指针未写入它们。