トップ回答者
VB2010 配列変数をLong指定するとエラーになる

質問
回答
-
For i As Long =1 to 9
For j As Long = 1 to 9
mSelection.Cells(i,j)= Cstr(mmSelection(i,j))
Next
Next
とすると、「Option Stricy OnでLongからintegerへの暗黙的な変換はできません」となってしまいます。
これは配列変数にintegerしか使えないということを意味しませんか?配列変数とはそういうことですか。(私は Long 型の配列を入れておく変数と解釈していました)
配列のインデックス、つまり ( ) 内に指定する要素は Integer 型でなければなりません。
これはそういう仕様に基づいて実装されているため、制限事項です。
(関数の引数が Integer 型で定義されていると捉えて頂ければ、わかりやすいかと思います)推測ですが、カウンタの変数を Long 型にしたところで実行効率に有意の差はないと思われます。
インクリメント・デクリメントレベルで差ができるようでは、x86 のアプリを動かしたときに実行効率の大きな低下を招きますし。また、Long 型の引数を用意しない理由は正確なところを言えませんが、x86 環境で逆に効率が悪くなる恐れ、事実上、64bit の整数型で表さないといけないほどの要素数を扱うことがほとんどないことが推測されます。
(Integer 型で表せない範囲、2GB を超える配列を扱うことは、それ自体が非効率と言える場面がほとんどです)# どうしてもカウンタ変数を Long 型にしたいのであれば、CInt などを使ってキャストをするべきでしょう。
質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります- 回答としてマーク Kazuo Turumi 2011年3月20日 21:10
すべての返信
-
For i As Long =1 to 9
For j As Long = 1 to 9
mSelection.Cells(i,j)= Cstr(mmSelection(i,j))
Next
Next
とすると、「Option Stricy OnでLongからintegerへの暗黙的な変換はできません」となってしまいます。
これは配列変数にintegerしか使えないということを意味しませんか?配列変数とはそういうことですか。(私は Long 型の配列を入れておく変数と解釈していました)
配列のインデックス、つまり ( ) 内に指定する要素は Integer 型でなければなりません。
これはそういう仕様に基づいて実装されているため、制限事項です。
(関数の引数が Integer 型で定義されていると捉えて頂ければ、わかりやすいかと思います)推測ですが、カウンタの変数を Long 型にしたところで実行効率に有意の差はないと思われます。
インクリメント・デクリメントレベルで差ができるようでは、x86 のアプリを動かしたときに実行効率の大きな低下を招きますし。また、Long 型の引数を用意しない理由は正確なところを言えませんが、x86 環境で逆に効率が悪くなる恐れ、事実上、64bit の整数型で表さないといけないほどの要素数を扱うことがほとんどないことが推測されます。
(Integer 型で表せない範囲、2GB を超える配列を扱うことは、それ自体が非効率と言える場面がほとんどです)# どうしてもカウンタ変数を Long 型にしたいのであれば、CInt などを使ってキャストをするべきでしょう。
質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります- 回答としてマーク Kazuo Turumi 2011年3月20日 21:10
-
「Visual Basic における配列」から、つらつら読んでみましたが、配列の添字の上限については書かれていませんでした。しかし、「UBound 関数 (Visual Basic)」の戻り値が Integer と規定されているので、Integerの範囲を超えた上限を指定すると、この関数が正しい結果を報告しなくなるでしょう。また、Array.Length プロパティも int(Int32)なので、この範囲を超える値を使うのは、止めた方が良いでしょう。ちなみに符号ありです。
普通の配列の添字にはlong(64bit)変数を使用できますが
Option Strict Off では使用できますが、Option Strict On では、コード入力時にエラーになります。プロジェクトのプロパティ ページ、「コンパイル」で、「暗黙的な変換」を「エラー」以外にすると、エラーとはなりません。Int64 -> Int32 は縮小変換なので、エラーとするか警告にとどめるか、はたまた素通りするかは、処理系依存でしょうね。ちなみに、C# は素通りです。なので、3000000000L(Int64 で 30億)を与えてみると、OverflowException が発生しました。じゃ、Int32 に代入してから…と思うと、コンパイル エラー発生。配列の添字も検出する、Option Strict On の VB が賢い?
static void Main(string[] args) { Int64 l = 3000000000L; char[] ary = new char[l]; // ← 30億を32ビットに縮小変換すると負数になるので OverflowException for (Int64 i = 0L; i < l; ++i) { ary[i] = '\0'; } Console.WriteLine(ary.Length); }
static void Main(string[] args) { Int64 l = 3000000000L; Int32 i32 = l; // ← ここで「型 'long' を 'int' に暗黙的に変換できません」コンパイル エラー Console.WriteLine(i32); char[] ary = new char[l]; for (Int64 i = 0L; i < l; ++i) { ary[i] = '\0'; } Console.WriteLine(ary.Length); }訂正:30億は、Int32 の範囲でした。縮小変換じゃなくて、最上位の符号ビットが立つので、負数です。
Jitta@わんくま同盟