A "--" operator in while loop function - c

I am coding in C on a IAR compiler and have two while loops:
i= 5;
do {
Task_sleep(1000);
}while(i-- && !Ready);
if (!Ready)
{
dprint("No ready response!");
return false;
}
And
i= 5;
do {
Task_sleep(1000);
i--;
}while(i > 0 && !Ready);
if (!Ready)
{
dprint("No ready response!");
return false;
}
The first will skip over the while loop and the second works properly. The "Ready" bool is set in another thread. The first loop will return false and the second will pass so Ready is not getting set to true.
I am thinking the compiler does not know how to handle the i-- in the while and is setting it to false. Is there something else that could be going on? With my setup I cannot step through the code in debug.
Edit Added to functions:
if(!Ready)
{
dprint("No Ready responce!");
return false;
}
Tested Ready as volatile, --i instead of i--, and removing Ready. All failed. Testing:
}while(((i--) > 0) && !Ready);
Still fails, it has to be the IAR compiler not reading the i-- properly and needs to have the -- operation removed from the while function. Let me know if you guys have anything else I can try but I feel confident in closing this issue.

You're confusing post-decrement with pre-decrement operators. The two operators are different. Both i-- and --i will decrement i. But their values are different. The value of i--, the post-decrement operator, is the old value of i. The value of --i, the pre-decrement operator, is the new value of i.

Your first code:
do {
Task_sleep(1000);
}while(i-- && !Ready);
Is equivalent to this:
int condition;
TOP:
Task_sleep(1000);
condition = (i != 0 && !Ready);
i = i - 1;
if (condition)
goto TOP
Your second code:
do {
Task_sleep(1000);
i--;
}while(i > 0 && !Ready);
is equivalent to this:
int condition;
TOP:
Task_sleep(1000);
i = i - 1;
condition = (i > 0 && !Ready);
if (condition) goto TOP;
The loops are different. i is decremented at a different time relative to the time the condition is evaluated, and the comparison on i within the condition is different.

Maybe you can try using volatile keyword to qualify variable i in the first version. I met a similar problem last week.

Related

Trying to understand the logic of an IF statement

I'm trying to construct some Ada code, but to do so, I have to understand some C.
In net-snmp-5.8.1.pre2/apps/snmpbulkwalk.c and probably others, there is an if statement which I am trying to understand what is happening and to separate it out, thus:
if ((vars->name_length < rootlen) || (memcmp(root, vars->name, rootlen * sizeof(oid))) != 0) {
/*
* not part of this subtree
*/
running = 0;
continue;
}
I get name_length < rootlen, I also get that memcpy always returns a pointer and never fails. From my poor eyesight it seems to say that if the < fails, it will then try the memcpy which always succeeds and then execute the contents of the IF block. But no... If that were the case, you could just put the memcpy inside the block.
No matter how I separate out the if statement, I can never get it to work the way it is already coded.
Your if does "short circuit" evaluation. It is basically of the form:
if (expression_A || expression_B)
do_something;
It evaluates expression_A, if it is true, expression_B is not evaluated. And, the if is taken (i.e. do_something is executed)
If expression_A is false, then expression_B is evaluated. If it is true, the if is taken
Restating the actual if code:
if (vars->name_length < rootlen) {
/*
* not part of this subtree
*/
running = 0;
continue;
}
if (memcmp(root, vars->name, rootlen * sizeof(oid)) != 0) {
/*
* not part of this subtree
*/
running = 0;
continue;
}
Restating the general case:
if (expression_A)
do_something;
else {
if (expression_B)
do_something;
}

Using 'continue' with boolean-based statements in C

For those of you who didn't understand - I KNOW this is NOT how a good code should look like... The purpose of this tricky question is to write a code without if-statements in order to practice boolean logic...
I'm trying to solve a question in C which restricts the programmer from using if/else/switch statements. cant use ternary operators either.
The idea is to use boolean based logical statements to get the "wanted path".
i.e - instead of:
if (1 > 0)
printf("TRUE")
else
printf("FALSE")
I would use:
bool res = true;
res = (1 > 0 && printf("TRUE")) || printf("FALSE")
(this is the general idea, using the boolean statement processing logic to manipulate different actions.
The only problem I ran into was to replace a part that looks somewhat like this (where i want the program to skip a certain part of the loop if A is equal to B):
while (...)
{
if (A == B)
continue;
//code
}
Do you know if this is possible to execute without using if/else/switch statements?
Thanks!!
The equivalent of your
while (condition)
{
foo();
if (A == B)
continue;
bar();
baz();
}
is
while (condition)
{
foo();
(A != B) && bar();
(A != B) && baz();
}
This assumes bar() doesn't change A or B. If it does, use a temporary variable:
while (condition)
{
foo();
bool cond = A != B;
cond && bar();
cond && baz();
}
Do you know if this is possible to execute without using if/else/switch statements?
With gcc extension statement expressions you can do this:
int main() {
int A, B;
while (1) {
A == B && ({continue;0;});
}
}
Please don't do this and please don't do res = (1 > 0 && printf("TRUE")) || printf("FALSE"). Just write ifs.
Assuming OK to use state variable then
while (...)
{
if (A == B)
continue;
//code
}
Can be implemented as
state = true ;
while ( ... ) {
...
while ( a == b ) {
state = false ;
break ;
} ;
while ( !state ) {
// code here
break ;
} ;
}
Or with fewer clutter, if allowed:
while (...)
{
state = A == B ;
while ( state ) {
//code here
break ;
} ;
}
With relatively minor performance penalty from having to double-test.
Side note: In my undergrad studies (many years ago), I recall hearing a lecture that explain that ALL control flow commands (if, while, do {} while, switch, with the exception of goto), can be implemented using the while. I wish I can find the reference/proof for that. This was part of a lecture about code verification.
if (1 > 0)
printf("TRUE")
else
printf("FALSE")
I would use:
bool res = true;
res = (1 > 0 && printf("TRUE")) || printf("FALSE")
If I see such a code written by any programmer in my team I would fire him/her.
Why? Your version is not human readable, it is error prone and almost not debugable.

Loop through array, find zero, perform action, stop

I am relatively new at programming, and I'm having trouble figuring out how to loop through an array until the counter finds zero, and when it finds zero once, performs an action and exits the loop. Here is the loop I have so far:
for (int i = 0; i<13; i++)
{
if(pHand[i] == 0)
{
pHand[i] = deal(numArray);
printf("%d\n", i);
printHand(pHand, "Your");
}
}
Currently, this loops through the array until it finds zero, calls deal(), prints the value of pHand, and then loops back through the same sequence until i=0. Please help. I am completely stumped on how to fix this.
The break statement can be used to exit an enclosing loop (e.g., a while, do-while, or for) or switch.
for (int i = 0; i<13; i++)
{
if(pHand[i] == 0)
{
pHand[i] = deal(numArray);
printf("%d\n", i);
printHand(pHand, "Your");
break;
}
}
// code will continue executing here if the for loop condition becomes
// false (i is 13) or if the break statement is reached.
In your code, if you encountered ZERO value cell, you just call "deal" function and printf, but you don't exit the loop, your are continuing to the next iteration.
In order to exit the loop, add "break" statement in the "if" scope and you will go out the loop once you fulfill the condition.
Some consider break to be harmful. I've used it plenty, but some people have issues with it. If you wanted to avoid using break, you could do the following:
int i = 0;
char finished = 0;
while (i < 13 && !finished)
{
if(pHand[i] == 0)
{
pHand[i] = deal(numArray);
printf("%d\n", i);
printHand(pHand, "Your");
finished = 1;
}
i++;
}
You could also rework it to use do-while. Some would say that this kind of solution is a little nicer, semantically.

Switching the status of a state machine from inside a loop

I have an array (nchar[12]) and I wrote this code to print it as vertical columns composed of "X"'s.
I first wrote a version with an accumulator and a while-loop and it worked fine, but it only could print colums as long as a given limit.
Then I tried to write it as a state machine, but the output is just an endless series of blank spaces.
I declared status as an int and assigned a value of 1 to it, then:
while (status = 1) {
for (i = 1; i <= 12; ++i) {
status = 0;
if (nchar[i] > 0) {
printf(" X");
--nchar[i];
status = 1;
}
else
printf(" ");
}
It should stop when it doesn't find any value to print for the last processed line, but it just goes on forever and I don't understand why.
The loop never ends because = is the assignment operator not == which is the comparision operator. You probably want
while (status == 1)
Or simply
while (status)
instead of
while (status = 1)
Also if you have an array declared as
type nchar[12];
then the valid indices for it start from 0 and end at 11. So, your loop should start with i=0 and should loop until i<12 becomes false.

how can i get rid of: warning: value computed is not used [-Wunused-value]

I'm a beginner in programming so I would like a simple answer :)
I have a for loop with multiple conditions, which prints out two arrays. It works, but i get a warning and a red line under for(). Why is it so and how can I avoid it? I'm writing it in C and I use a Geany compiler in Ubuntu. :)
for((i=LEN-1) && (j=1); (i>=LEN-3) && (j<=PODIUM); i-- && j++)
{
printf("%d. koht: %s tulemusega %f\n", j, voist[i], tul[i]);
}
for(i=LEN-1,j=1 ; (i>=LEN-3) && (j<=PODIUM); i--, j++)
EDIT:
It works because this is the correct syntax. you don't need to use and operator to combine two initializations or two increments. you can just use the ,
This warning is because of the return value of (i=LEN-1) && (j=1) which is bot used further.To avoid the warning, try this
int temp;
...
temp = (i=LEN-1) && (j=1);
for(; (i>=LEN-3) && (j<=PODIUM); i-- && j++)
{
....
temp = (i=LEN-1) && (j=1);
}

Resources