2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

VBのFor文でのStepの仕様を微妙に勘違いしていたっぽい

Last updated at Posted at 2016-02-09

前提知識

ForのStepは普通、

Dim i as Long
For i = 1 to 10 Step 1

  ' なんやかんやあって桶屋が儲かる

Next i

こんな感じで使う。
Stepを省略するとデフォルトで「1」になる。
大体は省略していると思う。

たまに、データを削除するときとかは逆順で処理するので、以下のように使うことがある。

Dim i as Long
For i = 10 to 1 Step -1

' なんか消す

Next i

なん...だと...

今日やろうとしたのは、
非再帰のマージソートを実装しようとした以下のコード。

' 単位を倍々にしていってマージする。1, 2, 4, 8, ...
Dim i as Long
For i = 1 to map.Count Step i

' マージソートする

Next i

こんな感じで書いたら、ループが一回まわるたびにiの値も増えるから、うまく動くはず!と思っていたわけですよ。

ただし、実際は無限ループになってしまいフリーズしたんですね。
ステップ実行して処理を追ってみると、このときiは1のままで増えることはありませんでした。

つまり、Stepは0になってました。

どういうことだってばよ

わたしがしていた勘違いをCとかの構文で書くと

for (int i = 1; i <= map.length; i += i) {
  // なんか処理
}

こうだと思っていたんです。

でも実際は

for (int step = 0, i = 1; i <= map.length; i += step) {
  // なんか処理
}

こんな感じみたいです。

まとめ

つまるところ、以下の2点が理解できていませんでした。

  • Stepの値はループごとに再評価されない
  • ループ用のカウンタの初期化より先に、Stepの設定がされる

なるほどなー。
つーか前から思っていたけどVBのForってなんでわざわざ劣化させた仕様にしているんだろう。。。
使いにくくてしょうがないな。。。

ちなみに確認したのはExcelVBAです。
他のVB系でも同じっぽいけど動作確認はしていないのであしからず。

2
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?