I have been looking through some code and I have seen several examples where the first element of a for cycle is omitted.
An example:
for ( ; hole*2 <= currentSize; hole = child)
What does this mean?
Thanks.
It just means that the user chose not to set a variable to their own starting value.
for(int i = 0; i < x; i++)
is equivalent to...
int i = 0;
for( ; i < x; i++)
EDIT (in response to comments): These aren't exactly equivalent. the scope of the variable i is different.
Sometimes the latter is used to break up the code. You can also drop out the third statement if your indexing variable is modified within the for loop itself...
int i = 0;
for(; i < x;)
{
...
i++
...
}
And if you drop out the second statement then you have an infinite loop.
for(;;)
{
runs indefinitely
}
The for construct is basically ( pre-loop initialisation; loop termination test; end of loop iteration), so this just means there is no initialisation of anything in this for loop.
You could refactor any for loop thusly:
pre-loop initialisation
while (loop termination test) {
...
end of loop iteration
}
Some people have been getting it wrong so I just wanted to clear it up.
int i = 0;
for (; i < 10; i++)
is not the same as
for (int i = 0; i < 10; i++)
Variables declared inside the for keyword are only valid in that scope.
To put it simply.
Valid ("i" was declared outside of the loops scope)
int i = 0;
for (; i < 10; i++)
{
//Code
}
std::cout << i;
InValid ("i" does not exist outside the loop scope)
for (int i = 0; i < 10; i++)
{
//Code
}
std::cout << i;
It means that the initial value of hole was set before we got to the loop
That means loop control variable is initialized before the for loop .
For C code,
int i=0;
for( ; i <10 ; i++) { } //since it does not allow variable declaration in loop
For C++ code,
for(int i=0 ; i <10 ; i++) { }
You could omit any of the parameters of a for loop.
ie: for(;;) {} is about the same as while(true) {}
It means that the initial value of hole was set before we got to the loop.
Looks like a list traversal of some kind.
Suppose you wanted to
for (hole=1 ; hole*2 <= currentSize; hole = child)
But the value of hole just before the for loop was already 1, then you can slip this initilization part of the loop:
/* value of hole now is 1.*/
for ( ; hole*2 <= currentSize; hole = child)
Related
Note: This is coming from a beginner.
Why does the first one outputs 333 and the second one 345 ?
In the second code does it skips over the declaration? I mean it should initialise the "j" variable again like in the first one.
int main() {
static int j =12;
for(int i=0; i<=2; i++) {
j = 2;
j += 1;
std::cout<<j;
}
return 0;
}
int main() {
for(int i=0; i<=2; i++) {
static int j = 2;
j += 1;
std::cout<<j;
}
return 0;
}
static variables are only initialized once (when first used). After that, it behaves as if it is declared somewhere else (I mean, the initialization is ignored). In the second main, the initialization static int j = 2; is executed only the first time, after that, you are incrementing it sequentially (i.e. 2,3,4...)
In the first loop, you set it's value on each iteration, which is not the same as initialization, so it can be run multiple times.
is this loop statement is correct?
if not correct then what alternative way?
I am trying to o(n) loop statement like this-
for(int i=0 ; i<n ; i++ , j=n ; j<n*2 ; j++){
continue;
}
The construct is wrong, you cannot you two loops in one construct, but you can have more than one variable controlling the iteration.
For example, you can have
Two (or more) variables, i and j, initialized with certain values.
A loop controlling statement, involving operation and condition check on i and j (and others, if defined).
Finally, you can control the increment or decrement of i and j (and others, if defined).
A sample construct can be:
for (int i = 0, j = n; i < n && j < n * 2; ++i, ++j)
|^^^^^^^| -------- variable modification
| | |^^^^^^^^^^^^^^^^^| ---------------- loop condition
|^^^^^^^^^^^^^^^|--------------------------------------- initialization
What you seem to want is something like:
for (int i = 0, j = n; i < n && j < n * 2; ++i, ++j)
{
continue;
}
To help you better understand what I did and why, and how you can do such transformations in the future, you need to understand how a for loop is really handled by the compiler: As a special while loop.
For example, if you have
for (a; b; c)
{
d;
}
then that's equivalent to this:
{
a;
while (b)
{
d;
c;
}
}
If we take what you (probably) want, in the form of a while loop then it would be
{
int i = 0, j = n; // a in my example above
while (i < n && j < n * 2) // b in my example above
{
continue; // d in my example above
++i, ++j; // c in my example above
}
}
Now it's easy to translate it to the for loop I showed initially.
As noted in a comment, the while loop shown here is a little misleading, as it won't actually do the increment. But then I assume your real loop doesn't have an unconditional continue statement as the only statement in the body. That would make the loop rather meaningless. However the principle is still valid, even if the example isn't.
for(int i=0 ; i<n ; i++ , j=n ; j<n*2 ; j++){
continue;
}
The above code is wrong
but it can be written as
for(int i = 0 ,j = n; i < n ,j < n * 2; i++ ,j++)
The above code is correct
i=0 and j=n is initialization
i<n and j<n*2 is loop condition
i++ and j++ is incrementation
I have 3 nested loops in which the code doesn't in anyway modify the counters, I need the value of the topmost-level loop counter to use later in the code. It looks like this
int i;
for( i = 0; !found && i <f_i.size();i++){
for(unsigned int j = 0; !found && j < f_g.size();j++){
for(unsigned int k = 0; !found && k < f_g.size();k++){
///Do Stuff
found = (/*Condition that's fulfilled after 2 iterations on k*/);
}
}
}
//Stuff that uses i
The condition is fulfilled after 2 iteration of the innermost loop, so i has the value 0 at that point.
Using GDB I saw that the value of i jumps to 1 after the condition is checked in the topmost loop, which gives me a wrong later in my program, or worse an out of bounds access.
Thanks in advance
This is how for loops work. The increment is done before the condition is checked.
The proper way (easier to read, easier to maintain) to do what you want is to add a variable, outside the loop.
int index;
And set it when you find the element:
found = ...
if (found) index = i;
The variable i is incremented due to the third expression of the for loop
int i;
for( i = 0; !found && i <f_i.size();i++){
^^^^
for(unsigned int j = 0; !found && j < f_g.size();j++){
for(unsigned int k = 0; !found && k < f_g.size();k++){
///Do Stuff
found = (/*Condition that's fulfilled after 2 iterations on k*/);
}
}
}
To avoid this you can write for example
int i;
for( i = 0; !found && i <f_i.size();){
for(unsigned int j = 0; !found && j < f_g.size();j++){
for(unsigned int k = 0; !found && k < f_g.size();k++){
///Do Stuff
found = (/*Condition that's fulfilled after 2 iterations on k*/);
}
}
i += !found;
}
Or instead of the expression statement
i += !found;
you can use the if statement like
if ( !found ) ++i;
Also the code will look more readable if the variable i will be initialized before the loops for example like
int i = 0;
while ( !found && i < f_i.size() ){
for(unsigned int j = 0; !found && j < f_g.size();j++){
for(unsigned int k = 0; !found && k < f_g.size();k++){
///Do Stuff
found = (/*Condition that's fulfilled after 2 iterations on k*/);
}
}
i += !found;
}
As others have said (or, at least, implied): once the (outermost) for loop is entered†, the variable, i, will be incremented at the end of that loop, before the condition is tested, to see if another loop should be run ...
... that is, unless you 'jump out' of the loop using a break statement!
So, the following, slightly modified, code will not increment i (at all) if found becomes true during the first iteration of the outermost loop:
int i;
for (i = 0; !found && i < f_i.size(); i++) {
for (unsigned int j = 0; !found && j < f_g.size(); j++) {
for (unsigned int k = 0; !found && k < f_g.size(); k++) {
///Do Stuff
found = (/*Condition that's fulfilled after 2 iterations on k*/);
}
}
// If "found" becomes true, exit the loop immediately, AVOIDING THE INCREMENT:
if (found) break;
}
So, while the other answers are very good, and the code solutions they offer are perfectly valid, the proposal here is a far more 'minimal' adjustment to your code. I hope it helps.
Note: You could, of course, add similar break statements to the inner loops; however, as your j and k variables are declared locally to those loops, it would appear that undesired increments to their values is not relevant. Furthermore, break cannot be used to jump out of multiple, nested loops.
† Also, be aware that if the found variable is true before the outermost for loop is encountered, that loop will not be executed (obviously) and, thus, the i variable will not be incremented in that case.
I have found a piece of code in a C++ program, it seems that it loops two times every for() loop in this program, but why does it need this third for in such preprocessor definition?
#define for for(int z=0;z<2;++z)for
It replaces for with for(int z=0;z<2;++z)for. Obviously, that would turn
for (int i = 0; i < N; ++i) {
// ...
}
into
for (int z=0;z<2;++z) for (int i = 0; i < N; ++i) {
// ...
}
Thus creating two nested loops. Without that extra for it would be
for (int z=0;z<2;++z) (int i = 0; i < N; ++i) {
// ...
}
Which is obviously incorrect.
Note that even though it's “correct” in the form you gave in your question, it doesn't mean it's a “good practice”. This is an example of excessive macro abuse and must be avoided. Here is one of the numerous examples how it could go wrong:
for (int z = 0; z < 5; ++z) {
for (int i = 0; i < 3; ++i) {
std::cout << z << std::endl; // this will never print 2, 3, 4
}
}
This will expand into
for (int z=0;z<2;++z) for (int z = 0; z < 5; ++z) {
for (int z=0;z<2;++z) for (int i = 0; i < 3; ++i) {
std::cout << z << std::endl; // this will never print 2, 3, 4
}
}
Meaning that you now have four nested loops, and that the inner loop will print the “invisible” z instead of the z you have declared in the outer loop (which becomes the second-level loop in the expanded code).
Another reason: as pointed by #stefan, it's a very bad idea to use keywords or other well-known identifiers as macro names. Makes one think of the infamous #define true false. And, as #HolyBlackCat mentions, it's also undefined behavior, meaning that as far as the standard is concerned, anything could happen. Ranging from the code “seemingly working” to a full-blown World War III with Martians (who invaded Earth to cleanse it from ugly code).
Firstly, that macro is the ugliest thing I've ever seen. I don't recommend ever doing something like this.
The top answer from Sergey Tachenov is really great, but it should also be mentioned that this macro really makes every for loop run twice. This means the doubly nested loops shown below will execute 400 times (not 200 times)! This might be unexpected.
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
// I'll be executed 100 times without the macro
}
}
becomes
for (int z=0;z<2;++z) for (int i = 0; i < 10; i++) {
for (int z=0;z<2;++z) for (int j = 0; j < 10; j++) {
// I'll be executed 400 times with the macro
}
}
It only gets worse from here. Consider an infinte loop like
int some_condition = 0;
for(;;) {
// insert logic here for calculating whether to break out
if (some_condition) {
some_condition = 0; // set back to false for use down the line
break;
}
}
turns into
int some_condition = 0;
for (int z=0;z<2;++z) for (;;) {
// insert logic here for calculating whether to break out
if (some_condition) {
some_condition = 0; // set back to false for use down the line
break; // gets me out of for(;;)...but the outer loop repeats
}
}
which bumps you out of the inner infinite loop if the condition is met....only to go right back in it. Now you might be stuck in an infinite loop.
Unexpected behavior is a good reason to avoid something, and macro shenanigans like this is very dangerous, and could be a real b**ch to debug. Imagine if some include directive had this ported in several header files deep...
Preprocessor substitution occurs in a single pass and does not support recursion. So the second "for" is probably for some zany idea of chaining existing "for" loops, prepending them with the macro "for" loop portion.
#define for for(int z=0;z<2;++z)for
Thus it replaces
for (int i = 0; i < N; ++i)
{
// ...
}
with
for(int z=0;z<2;++z)
for (int i = 0; i < N; ++i)
{
// ...
}
Which is a pretty crazy use of the preprocessor.
I just want to confirm a suspicion I have about loop indexes. I am using c++.
I have two for loops in my code. For one I declared my index outside of the loop, i.e
int i;
for(i = 0; i < n; i++){
. . .
}
cout << i <<endl;
And then I have later:
for(int j = 0; j<n; j++){
. . .
}
cout << j <<endl;
In the first case I see that some random number is outputted. In the second case, I get an error message about -fpermissive or something like that. I just want to confirm that the index goes out of scope whenever the loop ends, because that seems to be what is happening.
I was trying to use the index for something later on, I guess I just have to put a second index in the loop to increment as i or j do, and then I can use this value later. i.e.:
int index = 0;
for(int j = 0; j<n; j++){
. . .
index ++;
}
cout << index <<endl;
Would someone confirm this for me?
The first example::
http://codepad.org/L5VErMAh
int main( void )
{
int i, n = 10 ;
for(i = 0; i < n; i++){
// do something useful. . .
}
cout << i <<endl;
return 0 ;
}
Output:: 10
Explanation:: The scope of i and n is global for the for loop. So, they don't go invalid or undefined after the execution of for loop.
The second example:: http://codepad.org/iqNtQ1Ok
int main( void )
{
int n = 10 ;
for(int j = 0; j < n; j++){
// do something useful. . .
}
cout << j <<endl;
return 0 ;
}
Output:: name lookup of 'j' changed for new ISO 'for' scoping
Explanation:: The scope of n is global for for loop but as the j is declared inside the for loop, its scope and lifetime is local for the for loop. That means, the j will be and is destroyed after the execution of for loop. That's why, the error.
The third example:: I think, you must have got the idea that it is pretty same as the first example.
Now for your doubt, "In the first case I see that some random number is outputted." No, that can't happen unless you are doing something wrong inside the for loop. You can post the first case for loop code and we can point you out the error.
In the first case, since j is declared outside the loop, the scope of i is even the outside of the loop. So,
cout<<i<<endl;
prints the value of n. The second case, j is declared in the loop. So the scope of j is only inside the loop; So you get the error.
So the first case itself you can use the value of i at later phases
#include<stdio.h>
main()
{
int i;
for(i=0;i<5;i++)
printf("%d\n",i);
return 0;
}
gave me an output of 5.
well this one will just print n
int i;
for(i = 0; i < n; i++){
//...
}
cout << i <<endl;//prints the value of n
and this one J is declared out of scope
for(int j = 0; j<n; j++){
. . .
}
cout << j <<endl; //the compiler asks: whats a j?
and the last one does the same as the first
int index = 0;
for(int j = 0; j<n; j++){
. . .
index ++;
}
cout << index <<endl;//still prints n