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 ;

static_assert 宣言

宣言指定子:

記憶域クラス指定子 宣言指定子 opt

型指定子 宣言指定子 opt

型修飾子 宣言指定子 opt

関数指定子 宣言指定子 opt

アライメント指定子 宣言指定子 opt

初期化宣言子リスト:

初期化宣言子

init-declarator-list 、init-declarator

初期化宣言子:

宣言子

宣言子 = 初期化子

boldtype-specifierを使用している行はint、 、charorvoidなどのキーワードです。 type-qualifierconst volatileはetcのようなキーワードです。

標準によれば、宣言指定子は再帰的に定義されるため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

うわー、多くの「const」が進行中です。


int * const foo1

foo1「intへのconstポインタ」です。の値foo1は定数です。foo1指すものは変更される場合があります。


int const foo2
const int foo3

foo2foo3は同じ型です - どちらも正しいです - C は両方を許可しますintとの順序はconstスタイルの選択です。どちらの場合も、識別子は定数です。 私の経験では、最初に持っconstている方が一般的です。したがって、私は先行技術に従う傾向があります。さらに-モジュールと一貫性がある限り、どちらでも問題ありません。どちらの場合も、次のような初期化子が見つかると予想されますconst int foo3 = 7;


しかし、混乱の解明も必要です。
[編集された回答が続きます]

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

OPは、「constはその左側に型がないのと同じように、その左側に型を修飾し、右側の部分を修飾する」と推測しました。これはこれら 2 について説明可能であり、追加のサンプルに適用されるようです。

foo4「intへのポインタへのconstへのポインタ」です。
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一定です。それが指すデータは定数として扱われます。

@ugorenconst、 a を横切って移動することについての投稿で正しい*です。を動かすとタイプconstが変わります。これはスタイルの違いではなく、コードの違いです。


参照:

C11 6.2.5.29 "例 1 ''float *'' として指定された型の型は ''pointer to float'' です。その型カテゴリは浮動小数点型ではなくポインターです。この型の const 修飾バージョンは '' として指定されます。 ''float * const'' 一方、''const float *'' として指定された型は修飾された型ではありません — その型は ''const 修飾された float へのポインター'' であり、修飾された型へのポインターです。

C11 6.7

http://cdecl.org/

于 2013-08-29T12:32:56.350 に答える