1

こんにちは、私はプログラミングの世界の初心者です。const変数の値を変更しないようにする方法を知りたいです。

#include <stdio.h>
int main()
{
 const int i = 10;
 int * p = &i;
 *p = 20;
 printf("*p = %d\ni = %d\n", *p,i);
 printf("%u\n%u\n",&i, p);
 return 0;
}

上記のプログラムでは、ポインタを介してconstフィールドに値を割り当てている間、警告のみが表示されますが、エラーは発生しませんが、出力する場合は違いはありません。

*p = 20
i = 10
3210723532
3210723532

それでは、変更できない場合にconstへのポインタを取得する方法は何ですか。

4

4 に答える 4

7

まず第一に、コンパイラはコードのために警告を出しますint * p = &i;

コンパイルによってコードが最適化されるため、i の値は変更されません。gcc を使用してコードをテストします。

を使用するとgcc -O0 const.c -o constO0コンパイラの最適化がないことを表し、結果は次のようになります。

*p = 20
i = 20
1114013412
1114013412

しかし、を使用すると、コンパイラの最適化を表し、結果gcc -O2 const.c -o constO2

*p = 20
i = 10
1262279764
1262279764

したがって、コンパイラは の型がiisであることを認識しており、コンパイル時にconstに置き換えiられるため、コードは次のようになります。10

 printf("*p = %d\ni = %d\n", *p,10);

gcc -S const.cまた、アセンブリ コードを調べるために使用することもできます。

于 2012-04-10T09:31:23.077 に答える
2

C 言語標準では、コンパイラが不正なコードを拒否することを (ほとんど) 要求していません。違法なことを書き、コンパイラーがそれについて警告するだけの場合、C 言語標準に関する限り、コンパイラーはその仕事を完了しています。

コンパイラの警告を真剣に受け止める必要があります。コードが警告やエラーなしでコンパイルされた場合、それはおそらく合法です (これは、実際に動作するという意味ではありません!)。

于 2012-04-10T09:17:50.577 に答える
1

C 標準では、「診断」という用語のみが使用されます。警告とエラーの区別はありません。

const int *キャストなしのへの変換はint *、診断が必要な制約違反です。

これは、構文エラーと同じカテゴリに分類されます。コードは有効な ISO C プログラムではなく、とにかく変換​​して実行した場合の動作は未定義です。

残念ながら、多くのコンパイラは、必要な診断と、追加する追加の診断を区別していません。さらに悪いことに、警告として診断を要求することもありました。これは許可されています。C 標準では、診断を必要とするプログラムは変換および実行を禁止する必要があるとは規定されていません。警告を発行することにより、コンパイラは診断の要件を満たします。

もう 1 つの問題は、多くの C コンパイラが要求されない限り標準の ISO C 方言を受け入れず、代わりに独自の方言を受け入れることです。

GNU C コンパイラは、方言オプションを指定しない場合、GNU C 89 と呼ばれる C 方言を理解します。

const int *したがって、皮肉なことに、この方言では、キャストなしに変換することは単なる警告にすぎint *ませんが、特定の合法的な C90 プログラムは完全に拒否されます。

したがって、基本的には、コンパイラの入力方言を制御する方法を常に理解し、すべての警告をフォローアップする必要があります。これらの警告は、言語の実際の違反であるか、コンパイラの気まぐれであるかにかかわらず、自分で理解する必要があります。作家 (「この表現を括弧で囲むことを提案する」)。

gcc -Wall -W -ansi(C90 でプログラミングしている場合、またはC99-std=c99の代わりにansi) を使用してコンパイルし、警告がないことを確認することは悪い考えではありません。余分な括弧などを示唆する文体的なものでさえありません。警告をフォローアップするのに十分な訓練を受けていない場合は、警告を-Werrorビルドに失敗するエラーに変えるために追加してください。をお勧めする人も-pedanticいます。

この規則に従えば、a の転覆がconst intコードベースに忍び込むことはありません。

于 2012-04-10T10:40:15.230 に答える
0

代わりににし#defineます。

宣言されたオブジェクトはconst、用語の英語の意味では一定ではなく、「読み取り専用」です。

#include <stdio.h>
int main()
{
 #define I 10
 int * p = &I; // illegal &I
 *p = 20;
 printf("*p = %d\nI = %d\n", *p,I);
 printf("%u\n%u\n",&I, p); // illegal &I
 return 0;
}
于 2012-04-10T09:32:29.403 に答える