- PR -

変数の範囲

投稿者投稿内容
まどか
ぬし
会議室デビュー日: 2005/09/06
投稿数: 372
お住まい・勤務地: ますのすし管区
投稿日時: 2006-10-04 11:11
引用:

Dim宣言の前にその変数に対し値を設定しようとすると、同じプロシージャ内でも
ローカル変数'hoge'は宣言されているため、参照できません。
というコンパイルエラーが出ます。
引用:

なちゃさんの書き込み (2006-10-04 10:54) より:
いやそもそもこれをエラーにするようになった理由は、
コンパイラにはあいまいでなくても、人間に分かりにくいものは
エラーにするという方針によるものでしょう。




ということですね。
なので宣言の適用範囲は内部ではそれを含むブロック全体のはずです。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-10-04 11:59
C# と VB では禁じられていますが、J# や C++/CLI では OK ですね。

コード:


/** J# */
private void oneMethod() {
for (int i = 0; i < 10; i++) {

}

for (int i = 0; i < 10; i++) {

}

int i = 0;
i++;
}

コード:


// C++/CLI
private:
System::Void OneMethod() {
for (int i = 0; i < 10; i++) {

}

for (int i = 0; i < 10; i++) {

}

int i = 0;
i++;
}


わかりにくくなるので、私は書きませんけども。

[ メッセージ編集済み 編集者: じゃんぬねっと 編集日時 2006-10-04 12:04 ]
だーやん
会議室デビュー日: 2004/03/07
投稿数: 16
投稿日時: 2006-10-04 12:11
それっぽいリンクを見つけたので
http://msdn2.microsoft.com/ja-jp/library/35styb3a.aspx
の「有効期間の開始」の項目を読んでみました。

私なりの解釈
○VB.NETでは(C#も?)プロシージャの中で宣言されている変数は、プロシージャの開始時点ですべてメモリが確保され有効期間が開始される。これは、コードによりその宣言文が実行されようがされまいが同じである。
○宣言文より上であっても変数の有効期間内であるため、プロシージャに属するブロックでは同じ変数名を使用することは出来ない。
○宣言文より上でも変数の有効期間内だが、その変数が使えない(値の格納、参照が出来ない)のは、人様の目から見てわかりにくいコードになるのを避けるためである。

ということなんですね?(違ってたらすみません。)

以上を受けて反省。
よくプロシージャの最初で引数の検証を行い、駄目だったらReturnというコード(1)を書いていたのですが、(2)のように書いたほうがメモリ確保の時間などがかからず効率的なコードということなのですね。(ブロックがどんどん深くなっていって個人的には嫌いなんですが・・・)

(1)
Private Sub Hoge()
  If Not 前提条件 Then
   Return
  Endif
  '処理
End Sub
(2)
Private Sub Hoge()
  If 前提条件 Then
    '処理
  Endif
End Sub
囚人
ぬし
会議室デビュー日: 2005/08/13
投稿数: 1019
投稿日時: 2006-10-04 12:32
引用:

以上を受けて反省。
よくプロシージャの最初で引数の検証を行い、駄目だったらReturnというコード(1)を書いていたのですが、(2)のように書いたほうがメモリ確保の時間などがかからず効率的なコードということなのですね。(ブロックがどんどん深くなっていって個人的には嫌いなんですが・・・)


この結論に至った過程が不明ですが、普通は(1)にすると思いますよ。
_________________
囚人のジレンマな日々
だーやん
会議室デビュー日: 2004/03/07
投稿数: 16
投稿日時: 2006-10-04 12:36
引用:

囚人さんの書き込み (2006-10-04 12:32) より:
引用:

以上を受けて反省。
よくプロシージャの最初で引数の検証を行い、駄目だったらReturnというコード(1)を書いていたのですが、(2)のように書いたほうがメモリ確保の時間などがかからず効率的なコードということなのですね。(ブロックがどんどん深くなっていって個人的には嫌いなんですが・・・)


この結論に至った過程が不明ですが、普通は(1)にすると思いますよ。



(1)だと前提条件に合致しようがしまいが、処理のために宣言されている変数のメモリ確保・初期化が行われる。
(2)だと前提条件に合致したときだけ、処理のために宣言されている変数のメモリ確保・初期化が行われる。

ので、(2)のほうが効率の良いコードなのかな?と思った次第です。気にするほどの差ではないのかな?
ダッチ
大ベテラン
会議室デビュー日: 2005/10/31
投稿数: 113
投稿日時: 2006-10-04 12:41
引用:

だーやんさんの書き込み (2006-10-04 12:11) より:

よくプロシージャの最初で引数の検証を行い、駄目だったらReturnというコード(1)を書いていたのですが、(2)のように書いたほうがメモリ確保の時間などがかからず効率的なコードということなのですね。(ブロックがどんどん深くなっていって個人的には嫌いなんですが・・・)

(1)
Private Sub Hoge()
  If Not 前提条件 Then
   Return
  Endif
  '処理
End Sub
(2)
Private Sub Hoge()
  If 前提条件 Then
    '処理
  Endif
End Sub




(1)が(2)にくらべてどれだけメモリ確保に関して効率的なのでしょうか。
私は微々たる物だと思います。

(1)は効率が悪いといって(2)のようなインデントが深くなっていくと
コードが読みにくくなり保守性も下がると思います。
それに(2)だと
IF に対する END IF まで目が行ってしまいますので
コードを読む時間も長くなってしまいます。

そのため、(1)のような書き方は結構みなさんもされていると思いますよ。
なちゃ
ぬし
会議室デビュー日: 2003/06/11
投稿数: 872
投稿日時: 2006-10-04 12:51
引用:

だーやんさんの書き込み (2006-10-04 12:36) より:
ので、(2)のほうが効率の良いコードなのかな?と思った次第です。気にするほどの差ではないのかな?


こんなレベルの効率を意識する必要など全くありません。
気にするとするなら効率ではなくて純粋にスタイルの問題でしょう。

そもそも参照なさったところには、
引用:

有効期間の開始

プロシージャ内部のブロック内で宣言された変数 (For ループなど) は、そのプロシージャへのエントリ時点で初期化されます。これらの初期化は、コードによってそのブロックが実行されるかどうかにかかわらず、有効になります。


と書かれてますよ。
だーやん
会議室デビュー日: 2004/03/07
投稿数: 16
投稿日時: 2006-10-04 12:59
引用:

そもそも参照なさったところには、
引用:

有効期間の開始

プロシージャ内部のブロック内で宣言された変数 (For ループなど) は、そのプロシージャへのエントリ時点で初期化されます。これらの初期化は、コードによってそのブロックが実行されるかどうかにかかわらず、有効になります。


と書かれてますよ。



を、すみませんでした。大いなる勘違いでした。
プロシージャ内に入ったときに、宣言がFor文の中にあろうが、If文の中にあろうが、実行されようがされまいが、すべてプロシージャの開始時に確保されるんですね。

スキルアップ/キャリアアップ(JOB@IT)