I was stepping through some C/CUDA code in the debugger, something like:
for(uint i = threadIdx.x; i < 8379; i+=256)
sum += d_PartialHistograms[blockIdx.x + i * HISTOGRAM64_BIN_COUNT];
And I was utterly confused because the debugger was passing by it in one step, although the output was correct. I realised that when I put curly brackets around my loop as in the following snippet, it behaved in the debugger as expected.
for(uint i = threadIdx.x; i < 8379; i+=256) {
sum += d_PartialHistograms[blockIdx.x + i * HISTOGRAM64_BIN_COUNT];
}
So is are parenthesis-free for loops treated differently in C or in the debugger, or perhaps it is particular to CUDA.
Thanks
The debugger executes one statement at a time.
Check this out:
int sum = 0; /* one assignment statement */
for (int k = 0; k < 10; k++) sum += k; /* one for statement */
and compare with this
int sum = 0; /* one assignment statement */
for (int k = 0; k < 10; k++)
{ /* for statement with the body
in a block of statements */
sum += k; /* assignment statement */
}
In the first example above, the sum += k is an integral part of the for statement; in the 2nd example, it is a full statement on its own.
There isn't any execution difference between a single statement following the "for" or a block with one statement in it. Looking at your code though, do you realise that i isn't actually incremented? Perhaps you meant to put i+=256.
As far as the debugger is concerned the brackets constitute something else to "move into" whereas the single line is just that, a single line (just like an if statement with no block).
Related
My book says for programming using while-loop, we must first initialize with a number, provide the condition mentioning 'while', and then it's to be followed by the statement to partake in the loop until the condition is met as well as to increment value in the loop.
Example :
i = 1;
while(i<=10)
{
s = s + i;
p = p * i;
i++;
}
But, in case of summing of odd numbers program no such incrementing value has been shown.
And, strangely enough(for me), I get correct result w/o the use of i++. I absolutely cannot wrap my head around why that is the case. Is mentioning i++ or i+1 not really a rule within loops?
int s, i, n;
s = 0;
i = 1;
while (i <= n)
{
s = s + i;
i = i + 2;
}
This line is the incrementing value:
i = i + 2;
The first loop increments by 1 with i++. But since you only want the odd numbers, you need to increment by 2.
You can simplify this to:
i += 2;
There is no such rule that we must use i++ in every loop(and for that matter using i as a loop variable).
As #Barmar indicated, you are incrementing i using the line :
i = i + 2;
There are cases where we need to increment by 3, 10, √n, logn, etc.
There are even cases where we need to run a loop backwards hence, we decrement i.
The point is, the value of i must change at some point otherwise we'll end up in an infinite loop.
Is this correct way of assigning an expression to a variable?
int a == ( i<3 );
And I want to use a for loop like this
for(i=0;a; i++)
The assignment operator is =. So the correct way to assign an expression to a variable is
int a = i < 3;
More accurately, this assigns the value of the expression to a variable. It does not assign the expression itself to the variable. This means that the expression is evaluated immediately. When you do
for(i=0;a; i++)
The value of a will never change even though i does.
The idiomatic way of writing for loops is to write the boolean expression inline:
for(i=0;i<3; i++)
If you have some more complicated calculation to determine when a loop should end, then you can write a function for the calculation. For example:
int condition(int i) {
return i < 3;
}
Now you can write the for loop as
for (i = 0; condition(i); i++)
You can use macros like following
#include <stdio.h>
#define a(i) i < 3
int main(void) {
for(int i =0; a(i); i++) {
printf("%d\n",i);
}
return 0;
}
Output
0
1
2
EDIT
As others said macro is not a good idea when the condition is large. In that case you can make a separate function for the complex logic and use that in your for loop condition part. Like following:
int a(i) {
return i < 3; // Your condition. It may be even more complex as per your requirement.
}
Then you can use that function in your for loop in the following way:
for(int i =0; a(i); i++ ){...}
You cannot do that, why would you even want to? Can you give me an example, where this would be useful? Just curious, maybe we find better solution :)
Also, you can read more about loops at http://en.cppreference.com/w/cpp/language/for
How can I convert a matlab for to C language?
Matlab:
for i = 1:l,
for a = d:-1:2,
mem(a) = mem(a-1);
end;
mem(1) = s(i);
y(i) = a0*mem(1) + a1*mem(d0) + a2*mem(d);
end;
C (that's what I did, but it seems not working):
for (i = 0; i < l; i++) {
for (j=d; j==2; j--) {
mem[j]=mem[j-1];
}
mem[0]=x[i];
y[i]= a0*mem[0]+a1*mem[d0]+ a2*mem[d];
}
Is my conversion correct?
Is my conversion correct?
No, see below.
for loops always have a form like
for (FROM; WHILE; NEXT) BODY
and are executed like:
evaluate the FROM expression (usually initialization)
evaluate the WHEN expression
if it is true, goto 3
else, exit the loop
then evaluate the BODY
evaluate NEXT (usually advancing the iteration)
goto 2
Note that the conditional is always a while, and never an until. They're logically opposites.
Now, look at your two loops:
for (i = 0; i < l; i++) {
runs while i < 1. As soon as that condition is false, the loop exits.
for (j=d; j==2; j--)
You want this to loop until j==2, but that's not how for loops work. It actually loops while j==2, which is to say, never. It should be
for (j=d; j >= 2; j--)
I know that I shouldn't put semicolon after a loop. But I am learning and accidentally I inserted one. And I wanted to know exactly what is happening with my error. So next time something similar happens, I know the source of the mistake.
In the following code below, in this portion of the code:
triangularNumber = 0;
for ( n = 1; n <= number; ++n )
;
I accidentally inserted a semi colon after the for loop. When I execute the entire code, it prompts the user to insert a number for calculating a TriangularNumber. But with the semicolon the result is wrong. For example, when I insert 10, the answer should be 55, but with the semicolon error it delivers to me 56. I wanted to understand why 56.
The complete code is below:
#include <stdio.h>
int main(void)
{
int n, number, triangularNumber, counter;
for(counter = 1; counter <=5; counter++)
{
printf("What Triangular Number do you want?");
scanf("%i", &number);
triangularNumber = 0;
for ( n = 1; n <= number; ++n )
**;**
triangularNumber += n;
printf("Triangular number %i is %i\n\n", number, triangularNumber);
}
return 0;
}
The other answers are all good, but to answer your question about why you get the specific number that you do (which would be 11 when you enter 10, not 56), it's because this:
for ( n = 1; n <= number; ++n )
;
does essentially nothing except loop until n is exactly 1 more than number, so when number is equal to 10, n will equal 11.
Then, this:
triangularNumber += n;
just sets triangularNumber to 11, since before the loop you set it to 0, so when it's sitting outside the loop as it does with the semi-colon there, triangularNumber += n; is basically equivalent to triangularNumber = n;.
Incidentally, if you'd defined n within the for loop, instead of at the beginning of main(), like so (you may need to put your compiler in C99 mode with -std=c99 or similar to do this):
for ( int n = 1; n <= number; ++n )
;
triangularNumber += n;
then you'd have spotted the error immediately because the program wouldn't compile, as by the time you got to triangularNumber += n; outside the loop, n would no longer be in scope. This is one good reason why limiting the scope of your variables to the minimum amount of code you need it can often be a good idea.
The second for statement has no braces, so the code runs ; number times!
You want:
for ( n = 1; n <= number; ++n )
{
**;**
triangularNumber += n;
}
Think of it like this:
loop {
do this;
and also this;
}
and more code outside the loop;
now, if you have a ";" with no code it will look like this:
loop {
;
}
and more code outside the loop;
the ; is a blank statement that gets run each time through the loop.
now if you remove the brackets take a look at this:
loop
;
and some code outside of the loop;
since there are no brackets the loop will only contain the very next line of code, in this example the empty line ";". then the line after that "and some code outside of the loop;" gets executed no matter what since it is outside of the loop.
basically, the code is interpeted as having brackets around one line of code if you don't have brackets. anything after the one line is outside of the brackets and is not in the loop.
i hope this clears things up!
The keyword for is a preface for a single statement that is run each time the loop completes. Since a semicolon ends a statement, the following loop does precisely nothing upon each iteration.
for ( n = 1; n <= number; ++n ) ;
Then execution continues to the subsequent statement (triangularNumber += n;), which is executed one time.
The same principle applies to if, while, and do keywoards as well. What gives you flexibility in all of these cases is this rule: Everything enclosed within a pair of braces is considered as one statement.
Thus, your code needs to look like one of these examples to work how you probably want it to.
for ( n = 1; n <= number; ++n ) triangularNumber += n;
-or-
for ( n = 1; n <= number; ++n )
{
triangularNumber += n;
} //everything between the braces is considered to be the one statement executed by the loop
Using the conversion from the for-loop to the while-loop in the example below, can // fixed block be any valid block of code given that you can add any other blocks of code before or after it in the while-loop?
for (int i = 0; i < 10; i++) {
// fixed block
}
int i = 0;
while (i < 10) {
// any block
// fixed block
// any block
}
To show that the answer may not trivially be "yes", I thought of a block of code that may be a counter example:
for (int i = 0; i < 10; i++) {
i = i * 2;
if (1 < 2) {
print(i);
continue;
}
}
The if-statement is there so that in the while-loop you can add a block of code after the continue; statement without getting a possible compiler error/warning. The output of the for-loop is 0, 2, 6 and 14. Adding i++; either before or after the fixed block of code in the while-loop doesn't work, showing that the answer may not be trivial.
Sure they can, just set up a similar exit condition. I don't think the inverse (while loops converted to for loops) is true though.
Also, yes, you're blocks of code will function the same in both cases, if the code is valid (logically and syntactically), then yes it will work.