dポイントプレゼントキャンペーン実施中!

C++ではfor文の初期化時にカウンタ変数等の宣言ができますよね.
0°から360°を表示するプログラムの例なのですが,次のコードを見てください.

int main(void)
{
const double drad = 2 * M_PI / 6;
double rad;

rad = 0.0;
for (int i = 0; i <= 6; i++, rad+= drad) {
//cout << "rad: " << rad << endl;
cout << "deg: " << rad * 180.0 / M_PI << endl;
}
}

このプログラムを実行すると,0°から60°ごとに360°まで表示されました.

ここで,for文の初期化処理でradの初期化を行おうとして,
for (int i = 0, rad = 0.0; i <= 6; i++, rad+= drad)
とプログラムを書き換えたところ,表示値は

deg: 57.2958
deg: 114.592
deg: 171.887
deg: 229.183
deg: 286.479
deg: 343.775

となりました.
また,コメントアウトしてある行を有効にしてradの中身を直接表示させると,

rad: 0
rad: 1
rad: 2
rad: 3
rad: 4
rad: 5
rad: 6

といったように,radが整数値に丸められています.

int iをfor文の外で宣言して
for (i = 0, rad = 0.0; i <= 6; i++, rad+= drad)
としたときには,正しい角度の表示が行われました.

これは,for文の初期化時に変数宣言を行うとき,同時にほかの初期化処理を記述してしまったらその変数も同じ型の新しい変数として宣言されてしまうということなのでしょうか?

for (int i = 0, rad = 0.0;...
→int i と int rad がスコープ内の変数として新しく宣言される?

A 回答 (4件)

>→int i と int rad がスコープ内の変数として新しく宣言される?



正解。
スコープ(forの終わりの}の外に出たらdoubleの値になります。
    • good
    • 0
この回答へのお礼

回答ありがとうございました.
おかげ様でスッキリしました.

お礼日時:2014/11/19 18:17

既に回答があるけど蛇足的に追加.



for (あれ; これ; それ) なんか
というのは, *だいたい*
{
あれ;
while (これ) {
なんか
それ;
}
}
と等価になります. つまり
for (int i = 0, rad = 0.0; i <= 6; i++, rad+= drad) なんか
は*だいたい*
{
int i = 0, rad = 0.0;
while (i <= 6) {
なんか
i++, rad+= drad;
}
}
と同じです.

ちなみに C でもだいたい同じ.
    • good
    • 0
この回答へのお礼

今まではずっとCで書いてきており、今回はそれと同じ感覚で
i=0;rad=0.0
while()
{...
となるものだと思っていました。

また、恥ずかしながら、
int A=0, B=1;
といった宣言時に初期化をする書き方ができることを知りませんでした。今までは
int A=0;
int B=1;
と書いてました^^;
だから最初に気がつかなかったんですね
新しいことも知れてよかったです。
ありがとうございました。

お礼日時:2014/11/22 00:05

ついでに言うと



doubleには誤差が含まれています。
rad += drad
のように、doube+doubleを繰り返すと、誤差が溜まることがあります。
# たとえば、0.1+0.1+..... と100回繰り返した値!=10.0 と言う事が起こり得ます。

今回の場合は
rad = drad * i
とするのがよいでしょう。

詳しくは、「double 誤差」辺りで検索してください。
    • good
    • 0
この回答へのお礼

浮動小数点の計算誤差については少しだけ知ってはいましたが,なるほどこんな対処方法もあるんですね.
これはいいことを聞きました.ありがとうございました.

お礼日時:2014/11/19 21:44

>また,コメントアウトしてある行を有効にしてradの中身を直接表示させると,



ループの外でいくつになっているのか?
というのも確認してみるとよかったかも知れませんな。

http://www.ksky.ne.jp/~seahorse/cpp/loopvar.html
とか。
VisualStudioなら… /Zc:forScopeオプションかな?
いや、違うか???

まぁ、実際の仕様書にあたった方がいいでしょう。
    • good
    • 0
この回答へのお礼

>ループの外でいくつになっているのか?というのも確認してみるとよかったかも知れませんな。

確かにそうですね.
初期化部分でintを宣言したときに,ループが終わったあとのradを表示させたら,ループ前の値のままでした.
これとは別に新しく変数がループ内に作られてこれが使用されていたということだったんですね.

回答ありがとうございました.

お礼日時:2014/11/19 18:16

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!