55

この質問は素朴かもしれませんが、次のとおりです。

  • constCにキーワードはありますか?
  • どのバージョンから?
  • constCとC++ の間に意味的および/または構文上の違いはありますか?
4

10 に答える 10

60

キーワードに関しては、CとC ++の間に構文上の違いはありませんがconst、かなりあいまいなものがあります。Cでは(C99以降)、関数パラメーターを次のように宣言できます。

void foo(int a[const]);

これは

void foo(int *const a);

宣言。C++はそのような構文をサポートしていません。

セマンティックの違いも存在します。@Ben Voigtがすでに述べたように、Cconst宣言では定数式は生成されません。つまり、Cconst intでは、ラベル内のオブジェクトをcaseビットフィールド幅として、または非VLA配列宣言の配列サイズとして使用することはできません(これはすべてC ++で可能です)。また、constオブジェクトには、Cではデフォルトで外部リンケージ(C ++では内部リンケージ)があります。

ベンが言及しなかった、少なくとももう1つの意味上の違いがあります。C ++言語の定数修正ルールは、次の標準変換をサポートします

int **pp = 0;
const int *const *cpp = pp; // OK in C++

int ***ppp = 0;
int *const *const *cppp = ppp; // OK in C++

これらの初期化はCでは不正です。

int **pp = 0;
const int *const *cpp = pp; /* ERROR in C */

int ***ppp = 0;
int *const *const *cppp = ppp; /* ERROR in C */

一般に、マルチレベルポインターを処理する場合、C ++は、最上位レベルまでconst-qualificationを追加する限り、間接参照の任意の深さでconst-qualificationを追加できると言います。

Cでは、最上位ポインターが指す型にのみconst-qualificationを追加できますが、それ以上追加することはできません。

int **pp = 0;
int *const *cpp = pp; /* OK in C */

int ***ppp = 0;
int **const *cppp = ppp; /* OK in C */

同じ基本的な一般原則のもう1つの兆候は、const-correctnessルールがCおよびC++の配列で機能する方法です。C++では次のことができます

int a[10];
const int (*p)[10] = &a; // OK in C++

Cで同じことを行おうとすると、エラーが発生します

int a[10];
const int (*p)[10] = &a; /* ERROR in C */
于 2011-03-09T16:39:02.400 に答える
15

最初の2つの質問はここで答えられます:Const in C

constはい、CとC++のセマンティクスにはかなりの違いがあります。

  • C ++では、const適切な型の変数は整数定数式(初期化子がコンパイル時定数式の場合)であり、配列の境界など、それを必要とするコンテキストや列挙型定義で使用できます。Cでは、そうではなく、そうすることもできません。

  • C ++では、constグローバル変数は自動的にstaticリンクされるため、ヘッダーファイルに入れることができます。Cでは、このような変数には外部リンケージがあり、リンク時に重複した定義エラーが発生します。

于 2011-03-09T16:14:47.887 に答える
9

はい、constキーワードがあります。1989年規格の一部として追加されました。

互換性に関しては、Harbison&Steele、第5版の段落を次に示します。

型修飾子はあるが明示的なストレージクラスがないトップレベルの宣言は、C ++ではあるがCでconstあると見なされます。互換性を維持するには、トップレベルの宣言を調べて、明示的なストレージクラスを提供します。C ++では、文字列定数は暗黙的に; それらはCではありません。 staticexternconstconst
于 2011-03-09T16:16:10.893 に答える
5

はい、const少なくともANSI C(別名C89)以来存在しています。

それは確かに私の「Cプログラミング言語(第2版)」のコピー、Kernighan&Ritchie(1988年に発行)に表示されます。

関連する抽出物:

およびプロパティは、ANSI規格で新しく追加されましたconstvolatileの目的はconst、読み取り専用メモリに配置される可能性のあるオブジェクトをアナウンスすることであり、おそらく最適化の機会を増やすことです。

于 2011-03-09T16:28:07.150 に答える
5

他の2つの違い:

于 2011-03-09T17:58:08.400 に答える
2

はい。constC89からCにあります。

これは、Cでのconstキーワードの動作に関する良い読み物です。

于 2011-03-09T16:15:48.970 に答える
2

CのセマンティクスはC++のセマンティクスとは異なります。例えば、

unsigned const a = 10;
unsigned A[a];

ファイルスコープ内はC++では有効ですが、Cでは有効ではありません。

于 2011-03-09T16:18:23.163 に答える
1

Cには「const」キーワードがあり、長い間使われてきました。変数が「const」と指定されている場合、その変数への書き込みは禁止されています。

さらに、一部の環境では、「const」と宣言された変数が他の変数とは異なるデータセグメントに配置されている場合があります。このデータセグメントは、ハードウェア書き込み保護を提供する場合があり、組み込みシステムの場合、RAMではなくROMまたはフラッシュメモリに格納される場合があります(RAMよりもはるかに多くのROMまたはフラッシュを備えた一部のプロセッサでは非常に重要な違いです(128 KBフラッシュなど)。および3.5KBRAM、または2 KB ROMおよび96バイトRAM)。

コンパイラーは通常、「const」値またはそれらを含む式について推論を行わないことに注意してください。「constcharfoo[] = "Hello";」と言うと、その後、foo [1]を参照すると、コンパイラはfoo []が格納されている場所から値(ほとんどの場合'e')をロードし、ロードされた値を使用します。これにより、コンパイルされたコードイメージに値をパッチできる場合がありますが、コードが無駄になる場合もあります。

数値をコンパイル時の「置換可能な」定数として定義する場合、少なくとも整数定数の場合は、「列挙型」を使用するのが最善の方法です。たとえば、「enum {woozle = 19;}」を指定すると、コード全体で「woozle」の代わりに19が使用されます。テキストによる置換とは異なり、注意してください。列挙型宣言は、スコープの適切なルールに従います。

于 2011-03-09T16:29:07.053 に答える
1

はい、constCにはキーワードがあります。C90から使用されています。

構文的には、C++と同じ場所で発生する可能性があります。意味的には、それはもう少し緩い、IIRCです。

于 2011-03-09T16:15:05.960 に答える
1

ESRによるとconst、ANSICドラフト提案規格に追加されました。 EricGiguereによる1987年のANSICの要約は、それを裏付けています。

これはドラフト自体のように見えます-「3.5.3型修飾子」を検索してください。

于 2011-03-09T16:18:33.407 に答える