>1) --i would decrement then check. i-- will check then decrement.
Not as the third step of a for loop. First there's the initialization, then the condition is treated as a top-of-loop test, the body is performed if the condition is true, then the increment is performed, and the condition is tested again.
>Using break statements is generally considered undesirable from a design standpoint.
And from an implementation standpoint, using break statements usually results in cleaner code. It would be nice if practice were like theory, but in practice, theory tends to fall flat. If you can fiddle with the condition to avoid a break, more power to you. However, if you need to use flags and conditionals or use an uncommon idiom to avoid a break, it's probably not worth the added complexity.
>This just goes on and on despite reporting the terminating condition in the body of the loop.
Maybe if you weren't modifying i in the body of your loop, the problem would be easier for you to see. It's generally a bad idea to write to the counter in a for loop because it changes how many times the loop iterates. It's harder to verify correctness that way.