This question already has answers here:
for loop missing initialization
(6 answers)
Closed 4 years ago.
I've been doing some research for my homework in C++ and I've came across this solution to my task that is literally one line of code. (+ initializing the variables ofcourse).
for (; n != 0; n /= 10, ++count) {}
My question is, what does the semicolon at the start of the for loop do. We've never covered that with our professor. Is there a different way in how this could've been written perhaps without a semicolon but still using a for loop?
This the for loop prototype
for(initialization;testExpression; updateStatement)
you are just saying there is no initialization needed
The structure of for loop is,
for (initialization; condition; increment/decrement) {
statements;
}
So you have done your initialization outside the for loop, so you have to skip that part and just do the condition check!
Is there a different way in how this could've been written perhaps without a semicolon but still using a for loop?
The answer is No if you want to eliminate semicolon and use for loop. The semicolon is what separating a statement from being initialisation or condition or increment/decrement. Without a semicolon, it takes the first statement as initialisation.
Example:
The below code is proper for loop.
for (i = 0; i < 10; i++) {
printf("%d", i);
}
It can be rewritten as,
i = 0; // initialisation
for (; i < 10; i++) {
printf("%d", i);
}
In the above code, we initialised i = 0 outside for loop, so now we don't have to do anything in the initialization part of for loop. So in order to skip it, and move to condition statement, we added ;.
Which again can be minimized by removing increment/decrement step,
i = 0; // initialisation
for (; i < 10;) {
printf("%d", i);
i = i + 1; // increment
}
And as mentioned by Aconcagua in comments, the final minimal version of the for loop can look like this,
i = 0; // initialisation
for (; ;) {
if(i >= 10) { // condition
break;
}
printf("%d", i);
i = i + 1; // increment
}
Any part of the for loop for(init; cond; step) may be omitted if it is not needed. for(;;), for example, is a pretty idiomatic "infinite loop" construct in C and C++. What you're seeing here is the "init" step being left out.
The for keyword in C++ requires a certain number of parameters.
for (initialization_statement; condition_statement; increment_statement) {}
The initialization statement can be ommited if you do not wish to declare a new variable or affect the value of an existing variable.
However, you still have to write the first semicolon, to indicate that initialization_statement is to be ignored.
Related
Our teacher for our introductory C++ course was speaking on the nature of for loops and how everything within the parentheses can be empty as long as the semicolons are there. My question is, if I were to take two for loops, one after the other, that have the same variable involved in their update statements, is it consistent across all compilers that, once the first for loop is exited, the second will just pick up the value of the variable that came about from the first loop if you keep the initial statement of the second loop empty? Our teacher was uncertain as to whether this interaction was compiler-specific; it worked in VS2017, but she expressed doubt as to whether it would work in earlier versions.
If your variable is part of the first for loop:
for(int x = 0; 10 > x; ++x)
{
}
for(; 20 > x; ++x)
{
}
then per the standard 'x' is not even defined for the second loop and the code will not compile. Note that some older compilers don't follow the standard on this point and will behave as in the next example.
If the variable is defined outside the first for loop:
int x = 0;
for(; 10 > x; ++x)
{
}
for(; 20 > x; ++x)
{
}
then when the second loop is entered 'x' will have the value it had at the time the first loop ended. In no case will 'x' be re-initialized by the second loop, or have some otherwise random value. It will either have the value obtained at the end of the first loop or result in a compilation error.
This question already has answers here:
What does it mean when the first "for" parameter is blank?
(8 answers)
Closed 4 years ago.
I'm studying for my exam and I bumped into this example that has a line that says:
for(;i<=m;i++)
The thing I don't understand is why is there a ; with nothing in front of it?
what does it do? What does it mean?
A for statement has the following syntax:
for (declaration; condition; post-condition)
The declaration happens once and once only. The condition is checked at the start of each loop and determines whether the loop will proceed, and the post-condition happens at the end of the loop.
Any and all of these statements can be omitted.
Yours is simply a for loop that does not require a declaration, perhaps because something is already declared, like so:
int i = 0;
for (;i<=m;++i)
If you wanted a loop to run indefinitely, you could omit the second statement:
for (int i = 0; ;++i)
In this regard, infinite loops are typically written as
for (;;)
You may wish to omit the post-condition, perhaps because you're using iterators and change it during the loop
for (auto it = std::begin(v); it != std::end(v);)
what does it do, what does it mean ?
It means that the initializing part of the for-loop is empty, i.e. no loop-variable is initialized in the scope of the loop.
This construct is most common in situations where you want to access the loop variable after the loop is left, e.g. in
int i = 7;
for(; i < 100; ++i) {
if(isPrime(i)) break;
}
assert(i == 11); // can access i now
This means a part of this statement is declared somewhere before.
i=0
for(;i<=m;i++)
This loop says,for every time that i is smaller than m, I'm going to do whatever is in the code block. Whenever i reaches m value, I'll stop. After each iteration of the loop, it increments i by 1 (i++), so that the loop will eventually stop when it meets the i <=m.
The thing that i don't understand is why is there a ";" with nothing in front of it. what does it do, what does it mean.
It is a valid statement that does nothing.
You can have empty statements any where you like. It's quite common to see them in looping constructs.
The i variable must have been initialized somewhere else.. so it picks the value from there and the loop iterates from that value of i.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
Everybody is aware of the most common use of for: (0 - 9)
for (int i = 0; i < 10; i++)
however, I've also seen some less common versions, like (1 - 10)
for (int i = 0; i++ < 10;)
or (1 - 10)
int i = 0;
for (;i++ < 10;)
Which would suggest that loops might be more customizable than I thought. If I'm guessing this correctly, it would seem that
There always needs to be 2 semicolons to separate 3 optional statements
The second statement needs to be convertible to boolean 1 for the loop to continue
The first statement is the only one where I can declare variables and is called once
The third and second statement are called after every iteration and can contain whatever (aside from declarations)
As far as those conditions are met, I can do whatever
for instance (0, 3, 7)
for (int i = 0, j = 2; i < 10; i+=++j)
Are those kinds of for loops considered standard use of the language? or just things that happen to work due to the implementation design in msvc++? Any official instructions on what the rules of for loop really are?
You are correct. However...
Just because it is possible doesn't mean you should do it. The entire purpose of a "for" loop is it is supposed to be organized at a level any competent programmer can understand quickly. A key fundamental is the programmer should know how long a "for" loop will run. If you add more complexity to that which is taught, the point of the "for" loop is lost. I cannot easily look at your 3rd example and tell how long the loop will iterate.
If you need to use a "for" loop like your 3rd example, you'd be better off writing a while/do-while loop.
From the ISO C99 draft:
for ( clause-1 ; expression-2 ; expression-3 ) statement behaves as
follows:
The expression expression-2 is the controlling expression
that is evaluated before each execution of the loop body.
The expression expression-3 is evaluated as a void expression after each
execution of the loop body.
If clause-1 is a declaration, the scope of
any identifiers it declares is the remainder of the declaration and
the entire loop, including the other two expressions; it is reached in
the order of execution before the first evaluation of the controlling
expression.
If clause-1 is an expression, it is evaluated as a void
expression before the first evaluation of the controlling
expression.
Both clause-1 and expression-3 can be omitted. An
omitted expression-2 is replaced by a nonzero constant.
To answer your questions:
There always needs to be 2 semicolons to separate 3 optional statements
Yes.
The second statement needs to be convertible to boolean 1 for the loop to continue.
Yes. The second statement will evaluate as a boolean true/false (although not necessarily "1").
The first statement is the only one where I can declare variables and is called once
For C++, yes. In C (before C99), you had to declare the variable outside of the for loop.
The third and second statement are called after every iteration and can contain whatever (aside from declarations)
Yes. And they may contain nothing. For example, for ( ;; ) means "loop forever".
As far as those conditions are met, I can do whatever
Here is a good tutorial:
http://www.cplusplus.com/doc/tutorial/control/
One of my personal favourites is to iterate over a linked list:
for(Node *p = head; p; p = p->next) ...
And of course, if you do "no condition", you get an inifinite loop:
for(;;) ...
But yes, as long as you have for( following by valid statements, two semicolons and ), it's "good code".
for(printf("h"); !printf("world\n"); printf("ello, "));
is valid, if rather bizarre C-code (and C++, but cout is preferred there).
Of course, "it compiles and does what you expect" does not make it RIGHT or a good use of the language. It's often preferred if other people can read the code and understand what it's meant to do, and not want to go work somewhere else or to perform violence against the person that originally wrote the code.
It depends on how you want to do it. C++ is flexible and allows you to build statements as you wish. Of course, clearer ways as preferable.
The "for" statement has 3 parts separated by ";" character:
1) initialize code (int i = 0): where you init the counter variable(s) you're gonna use in your loop;
2) condition for loop (i < 20): condition that will be tested for the loop to continue;
3) step (increment): you can optionally specify an increment to the counter variable;
The "for" statement has preferable and indicated use when you know how much times you're going to iterate (to loop). Otherwise, it's recommended to use "while".
Example of flexibility of C++:
for(int i = 0; i < 20; i++) { }
is equivalent to
int i = 0;
for(;i < 20;) { i++; }
Most of the times, while loop is used when we are checking for an event to happen in the while loop body. And for is mostly used when a "determined" number of iterations is given. Let us assume we need to know the number of iteration we are in, generally speaking:
General While loop:
bool flag = false;
int it = 0;
while (!flag)
{
//... do something using it
++it;
flag = getFlag();
}
General For loop, the iteration number is intrinsic to the loop:
for(int it = 0; it < N; ++it)
{
//... do something using it
if (getFlag())
break;
}
However, for the case where the number of iterations is not set (that is, we are looping until the even occurs) I have never seen something like:
for(int it = 0; !getFlag(); ++it)
{
//...do something using it
}
But I always see something like the first while loop I have written. Is there any real difference? Is it considered a better style the while loop? Because for me, the for loop is more compact and easy to read and follow.
Generally you should use whichever you find the most readable, but beware that there is a difference between these two constructs that may catch you off guard: the behavior of continue.
continue would not increment it using the while construct, but it would increment it using the for construct.
while (!getFlag()) {
// ...
if (something) {
// "it" won't be incremented!
continue;
}
// ...
++it;
}
for(int it = 0; !getFlag(); ++it) {
// ...
if (something) {
// "it" will be incremented!
continue;
}
// ...
}
If you are not using continue then the behavior will be identical, but you can't make the general statement that for (a; b; c) { d; } is exactly equivalent to { a; while (b) { d; c; } } unless you add the restriction that d cannot contain a continue statement.
There is no difference in execution between the while() and for() loops you describe. There is no standard or common convention on which one is better or more elegant. Stick to the one you find more comfortable to work with.
Is there any real difference?
No. Apart from variable scoping and the meaning of continue, these are exactly equivalent:
initialize;
while (condition) {
body;
increment;
}
for (initialize; condition; increment) {
body;
}
Is it considered a better style the while loop?
There are, as you mention, typical use cases for each type of loop:
If you have some initialization, test and increment, use a for loop. Not necessarily for a known number of iterations, either; a typical C++ pattern is to iterate while i != some_container.end(). I think your last example works fine as a for loop.
If you don't need the initialization and increment, use a while loop. Writing for (; condition;) is just silly.
However, there are grey areas, where either type of loop makes sense. It is mostly a matter of personal preference.
All of the above cases are valid, and perfectly OK in my book (assuming that you meant to set flag = true; in the first case, or at least not constant false, since that will never enter the loop).
I sometimes use:
for(int i = 0; ; i++)
{
...
if (getFlag()) break;
...
}
Another favourite is the typical "linked list loop":
for(Node* p = head; p; p = p->next)
{
... Do stuff with p ...
}
To a large degree, it depends on what you are actually trying to express...
The compiler will most likely generate the same, or at least very similar, code for all three.
The fact is that
for (exp1; exp2; exp3) {
statements;
}
is equivalent to
{ // I put the brace, because exp1 may be a declaration of variable local to the loop
exp1;
while (exp2) {
statements; // as long as there is no continue (or if you replace every continue; with { exp3; continue; }
exp3;
}
}
So it's a matter of taste, of having a loop specific initialisation and an increment expression, and of the way of using continue statements .
However your analysis is exact: for is frequently used for iteration, as the c++11 range-for shows :
for (x : container) {
statements;
}
The reason (at least according to B.Stroustrup) is that all control logic for the iteration can easily be regrouped in one visible place, at top of the loop.
Whilst I'll agree with most people there is no major difference (and in fact in most situation they will actually compile down into the same code). I was always taught not to use for loops in situations where internal operations (other than the iterator) could change when the loop ends. This was for readability sake.
In a loop like so,
for (int i = 0; i < 5; i++)
{
int i_foo;
i_foo = foo();
if (i < 5)
return; //<-------- Right here
footwo();
}
How would I return that one particular turn of the loop?
I know that I could make footwo() execute under the condition that i >= 5, but I'm wondering if there is a way to make the loop exit (just the once).
For more explanation, I would like the for loop to start back at the beginning and add 1 to i, as if it had just finished that particular "loop" of the loop.
(I could not find an answer to this based on the strange wording, but if there is one just direct me and I will happily take this down.)
Use continue:
if (i < 5)
continue;
This jumps straight to the next iteration of the loop.
I'm not entirely sure what you mean but if you're checking the condition of if (i < 5) then just use the keyword continue. If the expression is true the loop will continue.
I'm not exactly what you're saying, but to clear up a bit of terminology, I think you mean to say "iteration" when you're saying a "turn of the loop" or a "loop of the loop." Common terms allow for better clarity.
As to your issue:
If you use the continue keyword, it allows you to skip to the next iteration. If you use the break keyword, it will skip past the entire iteration structure (out of the for loop entirely). This also works with while statements.
You can use continue to terminate the current iteration of a loop without terminating the loop itself. But depending on how your code is structured, an if statement might be cleaner.
Given your example, you might want:
for (int i = 0; i < 5; i++)
{
int i_foo;
i_foo = foo();
if (i_foo >= 5) {
footwo();
}
}
I'm assuming that you meant to assign the result of foo() to i_foo, not to i.
A continue can be simpler if you need to bail out from the middle of some nested structure, or if you need to bail out very early in the body of the loop and there's a lot of code that would be shoved into the if.
But in the case of nested control structures, you need to remember that continue applies only to the innermost enclosing loop; there's no construct (other than goto) for bailing out of multiple nested loops. And break applies to the innermost enclosing loop or switch statement.