matlab for (decreasing) in C - c

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--)

Related

Expressions and for loops in C

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

Variable assignment in conditional statement

I have a code:
while (i = j) {
/* not important */
}
For how long will this while loop work? Is it till the moment when the value of variable j is equal to zero?
For while loop properties, quoting C11, chapter §6.8.5/p4, (emphasis mine)
An iteration statement causes a statement called the loop body to be executed repeatedly
until the controlling expression compares equal to 0. [...]
and considering the assignment inside the loop condition, quoting §6.5.16/p3
[...] An
assignment expression has the value of the left operand after the assignment,111) but is not
an lvalue. [...]
So, every time the loop condition is executed, first the current value of j will be assigned to i and then, the value of i will be taken as the controlling expression value.
In other words, the loop will continue until j becomes 0.
That said, iff you are sure about the assignment part as the loop condition statement, put it into double parenthesis like
while ((i = j)){
Less confusion for the compiler and the next developer/maintainer.
For how long will this while loop work? Is it till the moment when the value of variable j is equal to zero?
A while loop would would work till it's the condition or expression evaluates to be false (i.e, 0).
In your code, YES while loop works till the moment when the value of variable j is equal to 0.
Note : The assignment operator in C returns the value of the variable that was assigned i.e, the value of the expression i = j os equal to j.
In while(i = j) , first i is assigned with value of jand then the expression is evaluated whether true or false.
Why not try a simple program :) :
#include <stdio.h>
int main(void)
{
int i = 0,j =10;
while (i = j)
{
printf("in loop when j = %d\n",j);
j--;
}
printf("exited loop when j = %d",j);
}
output :
in loop when j = 10
in loop when j = 9
in loop when j = 8
in loop when j = 7
in loop when j = 6
in loop when j = 5
in loop when j = 4
in loop when j = 3
in loop when j = 2
in loop when j = 1
exited loop when j = 0
An assignment operation always returns the result of the assignment, so the loop will continue until j == 0, this behavior exists so you can chain many assignment operations together like so:
a = b = c;

Condition checking in a for loop

Consider this code:
int main()
{
int i;
int ints[3];
ints[0] = 0;
ints[1] = 1;
ints[2] = 2;
for(i = 0; (ints[i])<4 && i<3; i++)
{
printf("%d\n", ints[i]);
}
}
Is there a reason I shouldn't do this sort of conditioning in the loop? I mean, when i becomes 3, will it look for a non-existing value at ints[3]? And if yes, is it ok?, since the loop is going to terminate anyway? It compiles and runs fine, but I was just wondering if there is some sort of a hidden problem with this. Thanks.
In the last iteration of this loop, the expression ints[i]<4 will access ints[3]. Since this access reads past the end of the array ints, the behavior is undefined in C. So yes, this is not good code. It may work most of the time, but the behavior is ultimately undefined.
It will be better to do i < 3 && ints[i] < 4 because the second part of the statement is evaluated only if the first one is true. The way you have it, it will look for ints[3] that does not exist.
It isn't okay to do this, because ints[3] will indeed be accessed. Now, because this is C, you're not going to get an error (unfortunately), but you'll never know for sure what the outcome would be.
Swapping the statements will solve the problem, because the && operator is optimized so that it doesn't evaluate the second condition if the first one is false.
The 'for' keyword expands out the following way:
int i;
for(i = 0; i < 2; i++)
dothing();
becomes
int i;
i = 0; /* first part of (i = 0; ...) */
beginloop:
if (i >= 2) goto endloop; /* second part of (...; i < 2; ...) */
dothing();
i++; /* final part of (...; ...; i++) */
goto beginloop;
endloop:
So, your code would expand out as follows:
i = 0;
beginloop:
if (ints[i] >= 4)
goto endloop;
if (i >= 3)
goto endloop;
printf(...);
i++;
goto beginloop;
endloop:
While this is fine, there is a problem with the ordering of your tests:
(ints[i] < 4) && (i < 3)
You should always check array indexes first to ensure they are valid before using them:
i = 0:
ints[0] < 4 && 0 < 3
i = 1:
ints[1] < 4 && 1 < 3
i = 2:
ints[2] < 4 && 2 < 3
i = 3:
ints[3] < 4 && 3 < 3 /* illegal access to ints[3] */
As a general rule of thumb, always try to order your conditionals in order of cost unless there is a better reason for the ordering, such as priority: In this case, i < 3 is the cheaper of the two tests, plus it is a constraint on the elements of ints you can access, so you checking the index should have a higher priority - you should check it before using it to tests ints[i] for anything.
The way you have written the loop, your code will try to read the non-existing array element ints [3]. That's undefined behaviour; a consequence is that anything can happen. Right now the whole internet is in uproar because of some code in OpenSSL that invoked undefined behaviour.
The loop terminates, that's okay. But you're accessing an area outside of what you're allowed to. It is undefined behaviour. You may get a segmentation anytime. But you're lucky.
Try putting i<3 before. That would work just fine.
for(i = 0; i<3 && (ints[i])<4; i++)
If i becomes 3, the second part is not evaluated. See short circuit evaluation.

Can all for-loops be converted to while-loops?

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.

Are loops with and without parenthesis handled differently in C?

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).

Resources