同じように変数を定義しているように見えるが実は意味が違った件

1.下記はコンパイル不可

 int x = 10;
 printf("%d", x);
 int x = 10;
 printf("%d", x);
 int x = 10;
 printf("%d", x);

2.下記はコンパイル可能

 int i;
 for ( i = 0; i != 3; i++){
   int x = 10;
   printf("%d", x);
 }

どちらも同じ意味に見えるが実は違うらしい・・・
1.の場合は二重(三重)に同じ名前の変数が定義されているためコンパイルが出来ない。
2.の場合forのなかの{}で囲まれたブロック内では、一回ループするたびに同名だが別のアドレスを持つ?別の変数xが定義されるらしい。
変数のスコープはforのブロック内のみに限定されるようだ。
つまり、{の直後のint x = 10; で新たなブロック内のみで有効な変数xが定義され、}の直後に変数xが開放され、ループするようだ。


したがって、3.のような変態的なきもちわるい書き方もできるらしい・・・
gccでは-Wshadow オプションをつければ警告してくれるらしい・・・

3.コンパイル可能

 int i;
 int x = 30;
 printf("%d", x);
 for ( i = 0; i != 2; i++){
   int x = 10;
   printf("%d", x);
 }
 printf("%d", x);

ちなみに一番最後のprintfの結果は30になる。