みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

for文内でscanf関数により配列に数値を格納することについて

プログラミング初心者です。
よろしくお願いします。

◎1------------------------------------
#include<stdio.h>
int main(void)

{
int i,dt[3];

for(i=0;i<3;++i){

printf("dt[0]=%d\n",dt[0]);
printf("dt[1]=%d\n",dt[1]);
printf("dt[3]=%d\n",dt[3]);

scanf("%d",&dt[i]);

printf("i=%d\n",i);
puts("");

if(dt[i]==0){
break;
}
}
printf("dt[0]=%d\n",dt[0]);
printf("dt[1]=%d\n",dt[1]);
printf("dt[2]=%d\n",dt[2]);
printf("dt[3]=%d\n",dt[3]);
printf("i=%d\n",i);
puts("");

i=1;

while(1){
printf("%d ",i);

if(1000<i){
break;
}
i*=2;
}
puts("");

return 0;
}
----------------------------------------
◎2------------------------------------
#include<stdio.h>
int main(void)

{
int i,dt[2];

for(i=0;i<3;++i){

printf("dt[0]=%d\n",dt[0]);
printf("dt[1]=%d\n",dt[1]);
printf("dt[2]=%d\n",dt[2]);

scanf("%d",&dt[i]);

printf("i=%d\n",i);
puts("");

if(dt[i]==0){
break;
}
}
printf("dt[0]=%d\n",dt[0]);
printf("dt[1]=%d\n",dt[1]);
printf("dt[2]=%d\n",dt[2]);
printf("i=%d\n",i);
puts("");

i=1;

while(1){
printf("%d ",i);

if(1000<i){
break;
}
i*=2;
}
puts("");

return 0;
}
----------------------------------------

以上2つのプログラムについて疑問があります。
まず◎1については、あえて添え字のdt[3]の値を見てみようと思ったら、iの値が入っているとわかりました。
しかし、何故添え字の番号の配列にiの値が入っているのかがわかりません。

次に◎2ですが、3回目のループで、添え字の番号の配列自身に入力した数値を格納すると、iと添え字番号配列に入力した数値が入っていました。
何故このようになっているのか疑問です。

以上のような疑問があります。
添え字の番号の配列とiが何か関連があるようですがいまいちわかりません。
教えていただけると嬉しいです。

投稿日時 - 2009-09-30 03:26:55

QNo.5330088

困ってます

質問者が選んだベストアンサー

そのコンパイラがiとdt[ ]を連続して確保しているためでしょう
たまたまdt[3]に当たる位置に変数iがあったというだけと思われます
環境が違えば別の結果になるでしょうし
配列の要素をオーバーして書き換えて別の変数を壊すバグもあります

変数の宣言を
int i,dummy1,dummy2,dummy3,dt[3];
に変えたら結果も変わりませんか

投稿日時 - 2009-09-30 09:28:51

お礼

ご回答ありがとうございます。

>そのコンパイラがiとdt[ ]を連続して確保しているためでしょう
>たまたまdt[3]に当たる位置に変数iがあったというだけと思われます

以上の内容しっかり理解しておきます。
int i,dummy1,dummy2,dummy3,dt[3];とするとdt[3]の値は、何も数値が設定されてない時の値が表示されていました!

投稿日時 - 2009-09-30 22:06:53

ANo.2

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(4)

ANo.4

>◎2------------------------------------
>int i,dt[2];

dt[0]とdt[1]が有効であって、dt[2]は配列の定義範囲外の領域であることはおわかりですね。

また、お使いの環境では、おそらくdt[](dt[0], dt[1])の後ろにiの領域があるのでしょう。
このとき、dt[2]という定義範囲外の領域ににアクセスするということは、
iにアクセスすることと同じです。

>添え字の番号の配列とiが何か関連があるようです

何も関係ありません。

投稿日時 - 2009-09-30 23:06:32

お礼

ご回答ありがとうございます。

dt[2]とiの領域が同じであったということですね。
理解できました!
ありがとうございます。

投稿日時 - 2009-10-01 00:10:11

ANo.3

>次に◎2ですが、3回目のループで、添え字の番号の配列自身に入力した数値を格納すると、iと添え字番号配列に入力した数値が入っていました。

どこの話をされているのか、よくわかりません。
入力例と出力例を示してください。

投稿日時 - 2009-09-30 21:24:12

お礼

説明不足ですいません。

--------------------------------------
dt[0]=-858993460
dt[1]=-858993460
dt[2]=0
10 ←入力値
i=0

dt[0]=10
dt[1]=-858993460
dt[2]=1
20 ←入力値
i=1

dt[0]=10
dt[1]=20
dt[2]=2
30 ←入力値
i=30

dt[0]=10
dt[1]=20
dt[2]=30
i=30

1 2 4 8 16 32 64 128 256 512 1024
--------------------------------------

3回目の入力で、30と入力するとiは30となり
dt[2]も30となっていました。

投稿日時 - 2009-09-30 22:22:51

ANo.1

int dt[3];
で使えるのはdt[0],dt[1],dt[2]までです
dt[3]は使えません、たまたまiの変数が近くにあっただけです

投稿日時 - 2009-09-30 08:23:06

お礼

ご回答ありがとうございます。
>たまたまiの変数が近くにあっただけです
以上の内容を頭に入れておきます!

投稿日時 - 2009-09-30 22:00:50

あなたにオススメの質問