2

正如我在 c 标准中所读到的,地址常量应以这种方式进行限定:

int * const ptr,

我在问自己,也会工作int const i,而不是const int i.

它确实做到了。

在我注意到他们是平等的之后,我只是尝试了一下,以了解const'行为'的意义。我做了类似的事情

int * const * pPtr我通知说,int const * ptr在不同的编译器中,它们都将const, 定义为:

“const 限定了它左边的类型,就像它的左边没有类型一样,它应该限定右边的部分”

但我在标准中找不到任何关于此的内容。并且标准中的每个示例都写const在声明的开头或部分后面static

(至少不会拒绝我的建议……)

那么为什么几乎每个人都在声明开始时使用 const ,因为我提到的方式更容易理解?

const以及如何根据编译器支持这两种方式的假设正确地将标识符限定为?

4

3 回答 3

2

那么为什么几乎每个人都在声明开始时使用 const ,因为我提到的方式会更容易理解?

这只是一种编码风格,都是有效的语法。

C11 §6.7 声明

句法

宣言:

声明说明符 init-declarator-listopt ;

静态断言声明

声明说明符:

存储类说明符声明说明符选择

类型说明符声明说明符选择

类型限定符声明说明符 opt

函数说明符声明说明符选择

对齐说明符声明说明符选择

初始化声明器列表:

初始化声明器

初始化声明器列表,初始化声明器

初始化声明器:

声明者

声明器 = 初始化器

注意我使用粗体的行,类型说明符是关键字intcharvoid等。类型限定符是关键字等const volatile

根据标准,声明说明符是递归定义的,这就是为什么const int i并且int const i都是有效的:

       int            const       i;
//      |               |
//type-specifier  type-qualifier 
//      \______________/  
//             |
//     declaration-specifier

      const               int       i;
//      |                  |
//      |            type-specifier 
//      |                  |
//type-qualifier  declaration-specifier
//      \__________________/  
//                |
//        declaration-specifier
于 2013-08-29T08:58:07.903 回答
0

Rule of thumb: Moving const over a * makes a difference. Otherwise it doesn't.

于 2013-08-29T08:43:27.733 回答
0

哇,有很多'const'正在发生。


int * const foo1

foo1是“指向 int 的 const 指针”。的值foo1是恒定的。foo1指向什么可能会改变。


int const foo2
const int foo3

foo2并且foo3是相同的类型——两者都是正确的——C 允许两者int和的 顺序const是 一种风格 选择. 在这两种情况下,标识符都是恒定的。 根据我的经验,拥有const第一更常见。因此,我倾向于遵循现有技术。此外 - 只要它与模块一致,我发现任何一个都可以。在这两种情况下,人们都希望找到一个像const int foo3 = 7;


但也需要解开一些混乱。
[编辑答案如下]

// OP's experimented with these
int * const * foo4;
int const * foo5;

OP 推测“const 限定其左侧的类型,就像其左侧没有类型一样,它应限定右侧部分”。这对于这两个是可以解释的,并且似乎适用于其他示例:

foo4是一个“指向 const 指向 int 的指针”。
foo5是“指向 const int 的指针”。

附加样本:

int * const foo6;
const int* foo7;
int const * const foo8;

foo6是“指向 int 的 const 指针”。
foo7是“指向 const int 的指针” - 与foo5.
foo8是“指向 const int 的 const 指针”。

foo6是恒定的,它指向的数据不是恒定的。
foo7不是常数,它指向的数据视为常数。是恒定的。它指向的数据被视为常量。
foo8

@ugoren在关于跨 a移动的帖子中正确的。移动改变类型。这不是风格差异,而是不同的代码。const*const


参考:

C11 6.2.5.29 “示例 1 指定为 ''float *'' 的类型具有类型 ''pointer to float''。它的类型类别是指针,而不是浮点类型。这种类型的 const 限定版本被指定为 ' 'float * const'' 而指定为 ''const float *'' 的类型不是限定类型 - 它的类型是 ''pointer to const-qualified float'' 并且是指向限定类型​​的指针。

C11 6.7

http://cdecl.org/

于 2013-08-29T12:32:56.350 回答