2020年09月13日
川俣晶の縁側ソフトウェアC# コーディング How To total 937 count

【入門級】簡単なfor文がハングアップするとき

Written By: 川俣 晶連絡先

無限に繰り返す §

 for (int i = 0; i <= 255; i++)というコードを見て、0から255までしか繰り返さないならbyte型で十分と判断してintをbyteに書き換えたらハングしてしまいました。なぜでしょう?

for文の動作 §

 for文は第2引数の条件が満たされている間だけ繰り返します。

 for (int i = 0; i <= 255; i++)の場合、iが256になった時点で繰り返しは終了します。

 ところが、byte型は256を表現できません。最大値が255だからです。ですから、255に1を足すとオーバーフローして0に戻ってしまいます。これではループは終わることができません。

解決方法 §

 少なくとも最終値+1を表現できる型を使うことが条件です。

 (カウントダウンする場合は+1ではなく-1かもしれない。他の条件が必要とされることもある)

 この場合、shortやushortを使えば少なくとも条件を満たします。もちろんintでも条件を満たします。

 どうしてもbyte型でカウントしたいときは、サンプルソースの【byte型で無限ループしない別解】のパターンのように判定式をfor文の第2引数から外に出してしまう方法もあります。カウントアップする前に最終値(255)かどうか判定すれば安全です。

罠の数々 §

  • またしても出た境界値の問題。境界値は罠がいっぱい!
  • バグのかなりの割合は境界値で起こる。厳重注意!
  • 実際に、単体テストは境界値をテストするものが多い! そこでバグが起きやすいからだ!
  • 単体テストは代表値と境界値の確認コードを書くのが基本だ。境界値はそれほどまでに重要だ!

参考リンク §

for (C# リファレンス)

整数数値型 (C# リファレンス)

 for文は高機能だが、必ず3つの式を書かねばならないわけではない。それぞれの式の意味と書かない場合の効果を調べてみよう。全部書かなかったら何が起こるだろうか?

リポジトリ §

https://github.com/autumn009/cshowto

for §

using System;

class Program

{

    static void Main()

    {

        // 無限ループしない

        for (int i = 0; i <= 255; i++) Console.Write($"{i} ");

        // byte型で無限ループしない別解

        for(byte i = 0; ;i++ )

        {

            Console.Write($"{i} ");

            if ( i == 255) break;

        }

        // 無限ループする

        for (byte i = 0; i <= 255; i++) Console.Write($"{i} ");

    }

}

実行結果

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38(以下無限に0~255を順番に繰り返す)

COOL C# CREW

C#ハウツー連載の解説増量、カラーのソース、新規書き下ろし追加の読みやすい単行本はこちら。

C#ハウツー: 逆引き入門・こんな機能はどう書くの?