質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
for

for文は、様々なプログラミング言語で使われている制御構造です。for文に定義している条件から外れるまで、for文内の命令文を繰り返し実行します。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

2回答

2063閲覧

for文のカウンタ変数はどこで宣言されているのですか?

退会済みユーザー

退会済みユーザー

総合スコア0

for

for文は、様々なプログラミング言語で使われている制御構造です。for文に定義している条件から外れるまで、for文内の命令文を繰り返し実行します。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

1グッド

0クリップ

投稿2017/11/03 11:34

編集2017/11/03 11:46

for文の内部的な仕組みについて疑問に思ったので質問させてもらいます。
追記:言語はC#でおねがいします。

for文を使った簡単なコードについて考えてみます。

using System; public class Hello{ public static void Main(){ for(int i = 0; i < 2; i++) { int a = 3; Console.WriteLine(a); } } }

上記のコードは実行することができます。
しかし、同じ処理である「「int型のaという変数を宣言し、3で初期化する。そのあと、aという変数の中身を出力する。」これを2回行う。」ということを以下のように書くと、A local variable named `a' is already defined in this scope のようにエラーが出て、実行できません。

using System; public class Hello{ public static void Main(){ int a = 3; Console.WriteLine(a); int a = 3; Console.WriteLine(a); } }

上のコードは実行できて、下のコードが実行できないのは、上のコードで1回目のループが終わったあとに、一度for文の{}を抜けることで、変数aの寿命が切れて死ぬことで、再びaという変数が宣言できるようになるからではないかと思います。

しかし、この予想が正しいとすると、カウンタ変数についてはどうでしょう。
ループを抜けているのなら、変数aと同様に、カウンタ変数iも同様に寿命を迎えて死んでいるはずです。しかし、2回目のループのとき、iは数値データを保持しており、ループもしっかり2回で終わります。この説明は理屈が通ってないと思います。
逆に、ループを抜けていないとするなら、iが数値データを保持できていることの説明はつきます。しかし、変数aは寿命を迎えて死んでいるのに、iは死んでいないので、この説明も理屈が通っていません。

このことをどうしたら説明できるか考えた結果、スコープが二重になっているのではないかと考えました。
つまり、外側のスコープで変数iを宣言し、内側のスコープでaを宣言しループの中身の処理が全て終わったらループを抜けて、外側のスコープに戻る。変数iをインクリメントしたのち、i < 2がtrueかをチェックし、trueなら内側のスコープに移り、もう1度ループを回す。i < 2がfalseになったら、ループを抜けて、外側のスコープからも抜ける。といった具合です。

これなら、for文を抜けたあと、再び変数iを宣言しようとしても、A local variable named `i' is already defined in this scope のエラーが出ないことの説明もつくのですが、どうやって確かめたらいいのかがわかりません。
今まで読んだ書籍のどこにも「for文ではスコープが二重になっている」、との記述は見当たらなかったので、そもそも間違っているかもしれませんが、私の予想は正しいのでしょうか?そして、それはどうすれば確かめることができるのでしょうか?

回答よろしくお願いします。

追記:私の中のイメージでは、どんな言語でも、ifやforのようなほとんど全ての言語に存在する機能の内部的なロジックは同じだと思っているのですが、言語によってfor文の仕組みが違うといったことはあるのでしょうか?

Bongo👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kei344

2017/11/03 11:35

質問タグに言語を追加してはいかがでしょうか。
LouiS0616

2017/11/03 11:36

いろいろな言語についての意見を求めているのでしょうか?
guest

回答2

0

ベストアンサー

C#前提です。

{}を抜けることで、変数aの寿命が切れて死ぬことで、再びaという変数が宣言できるようになるからではないかと思います。

YESです。

カウンタ変数についてはどうでしょう。 ループを抜けているのなら、変数aと同様に、カウンタ変数iも同様に寿命を迎えて死んでいるはずです。

NOです。カウンターはループを繰り返す間ずっと生きたままでないと困るのはおわかりですよね?

C#

1// (A) 2for (i = 0; i < 2; i++) { 3 int a = 3; 4 Console.WriteLine(a); 5} 6==> 7// (B) 8{ 9 i = 0; 10 while (i < 2) { 11 int a = 3; 12 Console.WriteLine(a); 13 i++; 14 } 15}

言語仕様が規定しているのは概ね上記のような意味付けと考えてよいと思います。(B)を見ればわかりますが、こんなコーディングはしたくないですよね?だから簡便な記法でかけるfor文があるのだと考えればよいのではないでしょうか。

投稿2017/11/03 11:53

KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/11/03 12:44

回答ありがとうございます! for文は{}を1セットだけ書くことで、本来は{}を2セット分書かなくてはならないのを省略して書くことができるということでしょうか? 言い換えると、for文はあくまで省略記法であり、(A)のように書いても(B)のように書いても、コンパイル結果は同じになるということでしょうか?
KSwordOfHaste

2017/11/03 12:55

意味から考えてそうなると思います。iはfor文の外では参照できないですね?しかしfor文が繰り返しをしている間は生きてます。さらにaはループ1回ごとに消えます。つまりは2つブロックがあるのと同じ振る舞いになるということですね。
退会済みユーザー

退会済みユーザー

2017/11/03 13:30

わかりやすい説明ありがとうございます!ベストアンサーに選ばせてもらいました。
guest

0

C

1int i = 0;//カウンタ変数 2{ 3 int a = 0;//ループ内変数 4 //略 5} 6{ 7 int a = 0; 8 //略 9} 10

こういうことでしょうか?
まあ、もっとも「宣言」とか「定義」はコンパイルの都合のもので「実行時に二回目が出てきたらおかしい」という考え方自体少し不自然です。

投稿2017/11/03 11:49

HogeAnimalLover

総合スコア4830

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/11/03 12:51

回答ありがとうございます。 > まあ、もっとも「宣言」とか「定義」はコンパイルの都合の > もので「実行時に二回目が出てきたらおかしい」という > 考え方自体少し不自然です。 とのことですが、おっしゃっている意味がよくわかりません。全く同じ名前の変数を複数宣言出来たら、例えば、その変数に対して演算するときに、同じ名前の変数の中からどの変数に対して演算をすればいいのかわからなくなってしまうと思うのですが、いかがでしょうか。
HogeAnimalLover

2017/11/04 16:21 編集

はい。コンパイル上で同名の変数で区別できない組があれば、これはコンパイルエラーとなります。 プログラミングにおいてはコンパイル(ソースコードから機械語を作り出す)と実行(機械語で記述された実行ファイルを起動する)は別物です。 ループ処理が行われるのはコンパイル時ではなく実行時です。たとえば、実行時に1億回ループする処理をプログラムしたとしても、コンパイル時には1億回ループするわけではありません。また、変数名についての情報はコンパイル時に使用されるものであって、コンパイルの過程で切り捨てられます(言語によって例外はありますが、多くの場合、実行時に変数名を使用することはできず代わりにアドレスを使用します)。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問