C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

ループと変数について

[トピック内 5 記事 (1 - 5 表示)]  << 0 >>

■85755 / inTopicNo.1)  ループと変数について
  
□投稿者/ 吉岡 (1回)-(2017/11/21(Tue) 10:36:17)

分類:[.NET 全般] 

凄く初歩的なことなんですが、変数の宣言はどこですることが良いのか?正しいのか?
ネットのサンプルソースなどを見ていると、ループの外と中で宣言しているものがあります。
違いがよくわからないのですが、ループの中で宣言すると、ループを抜けるまでずっと変数が溜まっていったりしますか?

for (int i = 0; i <= 10000; i++)
{
i++;
string str = "yoshi";
Console.WriteLine(str);
}

string str = "";
for (int i = 0; i <= 10000; i++)
{
i++;
str = "yoshi";
Console.WriteLine(str);
}

この2つの違いって何でしょうか?
気にせずどっちでも良いのでしょうか?

引用返信 編集キー/
■85756 / inTopicNo.2)  Re[1]: ループと変数について
□投稿者/ shu (1067回)-(2017/11/21(Tue) 10:41:03)
No85755 (吉岡 さん) に返信
> 凄く初歩的なことなんですが、変数の宣言はどこですることが良いのか?正しいのか?
> ネットのサンプルソースなどを見ていると、ループの外と中で宣言しているものがあります。
> 違いがよくわからないのですが、ループの中で宣言すると、ループを抜けるまでずっと変数が溜まっていったりしますか?
> 
> for (int i = 0; i <= 10000; i++)
> {
>     i++;
>     string str = "yoshi";
>     Console.WriteLine(str);
> }
こっちはここでstrが無効


> string str = "";
> for (int i = 0; i <= 10000; i++)
> {
>     i++;
>     str = "yoshi";
>     Console.WriteLine(str);
> }
こっちはここでstrが有効

です。

引用返信 編集キー/
■85759 / inTopicNo.3)  Re[2]: ループと変数について
□投稿者/ 774RR (574回)-(2017/11/21(Tue) 13:05:46)
C/C++/C# では、ループ内で定義した変数はそこで初期化され(ループを回るたびに初期化される)
ループを閉じるカギ括弧に到達した時点で処分される(ループの回数処分される)規則っす。
# GC の話はおいとく

サンプル前者は str という参照は5001回初期化され処分されます。
サンプル後者は1回初期化されるっきりです(この全体をくくるカギ括弧に到達したら処分)

(まあ提示コードサンプルでは、最適化の結果どちらも同じことになりそうな気がする)

なのでループの中で不変な変数はループ外で定義するほうが性能面では上昇します。
ループ1回の内で条件判定などで値を変える変数があるならループごとに初期化するほうが良いので中で定義。
ループ後に結果を得るなどする必要があるならループ外で定義せざるを得ないっす。

ループ制御変数を for 式の第三項以外にループ内部で i++; してるのは混乱の基なのでやめたほうがいい。
ループ終了条件は C の世界では "<=" でなくて "<" で書くほうが良いでしゅ。

このサンプル、ぱっと見て 10000 回のループに見えるんだけど、その実 5001 回のループであるわけで、
オイラの後輩君がこんなことかいてたら教育的指導の対象っす。
引用返信 編集キー/
■85761 / inTopicNo.4)  Re[1]: ループと変数について
□投稿者/ WebSurfer (1357回)-(2017/11/21(Tue) 13:45:11)
No85755 (吉岡 さん) に返信

c# 変数 スコープ などをキーワードにググると質問者さんの疑問に答えてくれる記事が見つかる
と思います例えば下記:

[雑記] 識別子のスコープとオブジェクトの寿命
http://ufcpp.net/study/csharp/start/st_scope/



以下、変数のスコープとは関係ない余談ですが、

文字列にはインターンプールというのがあるそうで、質問者さんの例では "yoshi" というインス
タンスは、前者・後者とも一つしか存在しないようになるはずです。

https://msdn.microsoft.com/ja-jp/library/system.string.intern(v=vs.100).aspx

また、最適化ということも行われて結局 Console.WriteLine(<インターンプールの参照>); という
ことになるかもしれません。(未確認です)

引用返信 編集キー/
■85762 / inTopicNo.5)  Re[2]: ループと変数について
□投稿者/ ぶなっぷ (145回)-(2017/11/21(Tue) 14:01:08)
基本的には、みなさんが答えてくれている通りです。

なので、以下の件だけ答えてみます。
> 違いがよくわからないのですが、ループの中で宣言すると、
> ループを抜けるまでずっと変数が溜まっていったりしますか?

値型はスコープが切れたら自動開放されますが、
参照型はnewしたら、ガベージコレクトされるまで溜まり続けます。
それと同じかどうかという話ですよね?

string型は参照型ですが、値型っぽい動作をします。
なので、どっちでしょう?
でも、実際の文字列の領域は参照先に存在することからして、
ガベージコレクタ任せな気がします。

よって私の意見は、どっちも、
ガベージコレクタが走るまで溜まっているに一票。
もちろん、自信なし(笑)

引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ