Consider the following:
int done = 0;
for (i = 0; !done && i < max; ++i)
{
// ... something involving 'i', that might end early ...
}
My personal preference here is to keep the "break condition" in one point. If you add a second if clause that breaks, you risk to skip over that logic when you or another programmer reads over it later. As a general rule, you should avoid using breaks in loops unless it is unavoidable. In a certain sense, it is the equivalent of a goto.
In this way the number of lines is minimized and, dare I say it, the code looks cleaner this way. Note that I used "i" in the place of "x" because if it is an index, as a rule, I tend to prefer i, though you can use whatever you prefer.
In general, if I have to cycle through a list or array of items, I will use a for loop, even if, as in your case, you may have conditional rules for exiting the loop. I will use a while loop if I am iterating through a list or array of items and index/position in list or array is not important. I will also use while if there is no predetermined end to the loop. That doesn't mean there isn't one, but rather that I don't know when the while loop will end before I begin.
I will generally avoid do ... while as more often than not, the very reason you cannot continue due to your break condition is what the logic contained within will depend on, and so you usually end up with something like:
condition = 0;
do {
if(!condition) {
// Perform some operation and possibly set condition to 1.
}
} while (!condition);
I tend to at that point break the operation into a function of its own:
while(performOperation()) ;
...
int performOperation() {
// Set result to value indicating success or failure
return result;
}
Hope that helps!