[解決済み] C言語で新しい変数を宣言できる場所とできない場所とは?
質問
プログラム/関数の先頭ですべての変数を宣言すべきであり、文の中で新しい変数を宣言すると問題が発生すると聞きました(おそらく先生から)。
しかし、K&R を読んでいて、次の文章に出会いました: "Declarations of variables (including initializations) may follow the left brace that introduces any compound statement, not just the one that starts a function". 彼はその後に例を挙げています。
if (n > 0){
int i;
for (i=0;i<n;i++)
...
}
このコンセプトで少し遊んでみたところ、配列でも動作することがわかりました。例えば
int main(){
int x = 0 ;
while (x<10){
if (x>5){
int y[x];
y[0] = 10;
printf("%d %d\n",y[0],y[4]);
}
x++;
}
}
では、具体的にどのような場合に変数の宣言が許されないのでしょうか?例えば、変数宣言が開始波括弧の直後でない場合はどうでしょうか?ここのように。
int main(){
int x = 10;
x++;
printf("%d\n",x);
int z = 6;
printf("%d\n",z);
}
プログラム/マシンによってはトラブルの原因になるのでは?
どのように解決するのですか?
また、変数を関数の先頭に置くのが一番良い方法だとよく聞きますが、私は強く反対です。私は、変数をできるだけ小さなスコープに閉じ込めることを好みます。そうすれば、誤用される可能性が少なくなり、プログラム上の各行で私の精神的空間を埋めるものが少なくなるからです。
C のすべてのバージョンでレキシカル ブロック スコープを許可していますが、変数を宣言できる場所は、ターゲットにしている C 標準のバージョンに依存します。
C99 以降または C++
gcc や clang のような最近の C コンパイラは C99 と C11 という規格があり、文が通る場所であればどこでも変数を宣言することができます。変数のスコープは宣言の時点からブロックの終わり(次の閉じ中括弧)までとなります。
if( x < 10 ){
printf("%d", 17); // z is not in scope in this line
int z = 42;
printf("%d", z); // z is in scope in this line
}
ループの初期化子の内部で変数を宣言することもできます。変数はループの中だけに存在することになります。
for(int i=0; i<10; i++){
printf("%d", i);
}
ANSI C (C90)
もしあなたが、古い ANSI C 規格を対象としている場合、変数の宣言は開始波括弧 1 .
しかし、これはすべての変数を関数の先頭で宣言しなければならないということではありません。C言語では、文が入る可能性のある場所ならどこでも中括弧で区切られたブロックを置くことができます(以下のようなものの後だけではありません)。
if
や
for
) を使って、新しい変数スコープを導入することができます。以下は、これまでのC99の例のANSI C版です。
if( x < 10 ){
printf("%d", 17); // z is not in scope in this line
{
int z = 42;
printf("%d", z); // z is in scope in this line
}
}
{int i; for(i=0; i<10; i++){
printf("%d", i);
}}
1
gcc を使用している場合は
--pedantic
フラグを渡す必要があることに注意してください。もし、単に
-std=c90
を使用すると、gcc は C90 のスーパーセットを受け入れるようになり、より柔軟な C99 変数宣言も可能になります。
関連
-
error: '.' トークンの前にunqualified-idを指定する必要があります。
-
libc++abi.dylib: NSException タイプの捕捉されない例外で終了するエラー
-
#137: 式は変更可能なlvalueでなければならない問題 // 文字列配列の代入問題
-
[解決済み] Valgrind が初期化されていないバイトについて警告する
-
[解決済み] 1ビットのセット、クリア、トグルはどのように行うのですか?
-
[解決済み] 難読化Cコードコンテスト2006。sykes2.cの解説をお願いします。
-
[解決済み] C言語で関数をパラメータとして渡すにはどうすればよいですか?
-
[解決済み] C言語でファイルが存在するかどうかを確認する最も良い方法は何ですか?
-
[解決済み] ストラクチャーとユニオンの違い
-
[解決済み】forループで型の異なる2つの変数を宣言することは可能ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[C] レポートエラー 代入の左オペランドとしてlvalueが必要
-
libc++abi.dylib: NSException タイプの捕捉されない例外で終了するエラー
-
[解決済み] 初期化でポインタ対象の型から修飾語を捨てる
-
[解決済み] PTHREAD_MUTEX_INITIALIZER vs pthread_mutex_init ( &mutex, param )
-
[解決済み] C 言語で const char* を char* に変換するには?
-
[解決済み] C言語でのブーリアン値の使用
-
[解決済み] プログラム終了前にmallocの後にfreeをしないと本当に何が起こるのか?
-
[解決済み] .aファイル、.soファイルとは何ですか?
-
[解決済み] アセンブリがCより速いのはどんなとき?[クローズド]
-
[解決済み] C言語で "unsigned long "をprintfする方法は?