Using 'continue' with boolean-based statements in C - 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.

Related

Alternative syntax of combining multiple condition check

I am implementing a simple if statement in c, where I am comparing the value of integer 'tile' to four other integers: w, a, s and d.
Here is my code:
if(tile == w || tile == a || tile == s || tile == d )
{
printf("legal\n");
return true;
}
While the above is correct, the syntax is tiresome. Is there a more elegant way of writing the condition "'tile' is one of the following integers..."
I'm a novice in programming so I apologise as I suspect the answer is very obvious. I've failed to find it addressed elsewhere though.
While eyalm's answer is maybe the one you're looking for, just wanted to chime in to point you to a more important factor here (as you mentioned, "I'm a novice in programming"), which is "Write code which is easier for humans to understand".
While the bitwise approach is shorter, it generally appears to be more difficult to understand a maintain, as it grows.
A cleaner approach will be (while it takes more effort to write the code), stick to the if ( a || b || c) syntax, or a fall-though switch case. It gives better readability.
In case your options grows longer (that you may need a horizontal scroll bar), you can consider adding a function to get the required value checked and use the return value in the condition in the if statement.
The bottom line is, there is no right or wrong way, only choose the way which make the code more readable and maintainable.
Two options i can think of...
bitwise
#define TILE_W 0x0001
#define TILE_A 0x0002
#define TILE_S 0x0004
#define TILE_D 0x0008
if (tile&(TILE_w|TILE_A|TILE_S|TILE_D))
{
printf("legal\n");
return true;
}
switch-case
switch (tile)
{
case w:
case a:
case s:
case d:
printf("legal\n");
return true;
default:
return false;
}
Solution for improvement can depend on values which you compare with.
If w, a, s and d are integer numbers that have consecutive values (e.g. 10, 11, 12 and 13), if-statement can use condition for boundaries:
if( tile >= w && tile <= d) { printf("legal\n"); }
If values are disparate (e.g. 6, 32, 142, 55), you can use switch..case construction, like
switch (tile)
{
case w:
case a:
case s:
case d:
printf("legal\n");
break;
default:
printf("ILLEGAL\n");
break;
}
Also you can use setting flag in one or multiple if as
int legal = 0;
// checking can be in different places of code
if (tile == w)
legal = 1;
if (tile == a || tile == s)
legal = 1;
if (tile == d)
legal = 1;
if( legal )
{
printf("legal\n");
}
And consider storing w, a, s and d values as array of valid values, so loop can be used for checking:
int valArr[] = {101, 151, 333, 7}; // you can add any number of values here
int i;
int legal = 0;
for(i = 0; i < ( sizeof(valArr)/sizeof(valArr[0]) ); i++)
{
if(valArr[i] == tile)
{
legal = 1;
break;
}
}
if( legal )
{
printf("legal\n");
}
else
{
printf("ILLEGAL\n");
}

C - Most succinct way to check if a variable is *none* of many options?

Background:
Often, we developers must check if a single variable is at least one of many options. For example,
if ( (data == 125) || (data == 500) || (data == 750) )
{
/* ... do stuff ...*/
}
The suggestion here (albeit written in C#), provides an elegant solution to use a switch statement like so,
switch ( data )
{
case 125:
case 500:
case 750:
/* ... do stuff ...*/
break;
default:
/* ... do nothing ... */
break;
}
This works well for "or" conditionals, but is ugly for negated "or" conditionals like the following,
if ( !( (data == 125) || (data == 500) || (data == 750) ) )
{
/* ... do stuff ...*/
}
which could be written as
switch ( data )
{
case 125:
case 500:
case 750:
/* ... do nothing ... */
break;
default:
/* ... do stuff ...*/
break;
}
and seems a bit hackish.
Question:
Is there a more succinct way to check if a single variable is none of many options, like the negated "or" conditional above?
References:
C++ Most efficient way to compare a variable to multiple values?
C# Comparing a variable to multiple values
I think the latter is fine.
You can formalize it better, though:
static bool in_sprawling_set(int data)
{
switch ( data )
{
case 125:
case 500:
case 750:
return true;
}
return false;
}
and then where you want to do the work:
if(!in_sprawling_set(data))
{
/* do the work, not in set */
}
This puts the "in set" logic in a function of its own, makes it mildly self-documenting, and the actual use-place much cleaner since the ! becomes more prominent and the final if is very readable ("if not in sprawling set").
Note: if the number of values is really large, I'd probably go for using a pre-sorted array and a binary search, rather than a huge switch. I realize a sufficiently clever compiler can do that transform by itself, but the readability of a huge switch would be rather low (especially if you like to put only one case per line). There's bsearch() for the searching:
static int cmp_int(const void *ap, const void *bp)
{
const int a = *(const int *) ap, b = *(const int *) bp;
return a < b ? -1 : a > b;
}
static bool in_sprawling_set(int data)
{
static const int values[] = { 125, 500, 750 };
return bsearch(&data, values, sizeof values / sizeof *values, sizeof *values, cmp_int) != 0;
}
There's quite a lot of boilerplate going on, but you can see how the part that lists the actual values (the only thing that'll grow as more values are added) is more compact.
Instead of negating the condition, you can always use De-morgans laws to simplify the expression
if (data != 125 && data != 500 && data != 750) ...
Is there a more succinct way to check if a single variable is none of many options?
The switch() statement is certainly a fine solution.
As an alternative, if the product does not over flow, code could use a single branch test:
unsigned data = foo();
if ( (data - 125) * (data - 500) * (data - 750) ) {
/* ... do stuff as long as data is not 125, 500 or 750 ...*/
}
If it more clear - not really, Is it faster than switch()? it has potential.

A "--" operator in while loop function

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.

Calling a void function inside loop control condtion

I would like to write a loop with the following pattern, where spin_lock's return type is void:
while(workersAvailable() && spin_lock(workQueueLock) && (!list_empty(workQueue) || spin_unlock(workQueueLock)) ) {
...
spin_unlock(workQueueLock);
//long taking work, with no need for a lock
}
Reasoning:
I want to hold the lock as short as possible and don't need it for workersAvailable()
I know i can write a function int f() {spin_lock(workQueueLock); return !list_empty(workQueue) || spin_unlock(workQueueLock);}, however I feel that there should be a better way
I do understand that && void can not work since && needs two operands
I tried , and it would not compile, besides I am not sure if , gurantess ordering of the operations.
Question: Is there any way to achieve this without an extra function and without moving control logic inside the loop body (i.e. spin_lock(workQueueLock); if(list_empty(workQueue)) { || spin_unlock(workQueueLock); break;})?
If you really want to do this, you can use the , operator, it will discard all the left operands evaluating only the last one
while(workersAvailable() &&
(spin_lock(workQueueLock), 1) &&
(!list_empty(workQueue) || spin_unlock(workQueueLock)))
But in my opinion, you should write the function, it's clearer.
What is wrong with some simplicity?
while(workersAvailable() && spin_lock(workQueueLock) ) {
if (list_empty(workQueue)) {
spin_unlock(workQueueLock);
continue;
}
// critical section ...
spin_unlock(workQueueLock);
// non-critical section
// long taking work, with no need for a lock
// You *could* break out of the loop here
}
UPDATE: (I misread the question, and thought that spin_unlock() was void)
while(workersAvailable() ) {
spin_lock(workQueueLock);
if (list_empty(workQueue)) {
spin_unlock(workQueueLock);
continue;
}
// critical section here ...
spin_unlock(workQueueLock);
// non-critical section
// long taking work, with no need for a lock
// You *could* break out of the loop here
}

Is it possible to execute both if and else part of an if --- else control statement? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Simultaneous execution of both if and else blocks
Is it possible to put some condition, so that both if and else part in an if ...else control statement can be executed without any warning or error ??
Do not use! ;-)
Yes, by forking.
if ( fork() ) {
printf("if\n");
}
else {
printf("else\n");
}
There are no real use cases to prefer the above code, unless it is for parallel execution.
No, there's no way to write a Schrödinger if clause.
You might be able to execute both with a goto, but it would never pass a code review.
Yes, it's possible:
#include <stdio.h>
#define else if (1)
int main(void)
{
int test = 1;
if (test == 1)
{
printf("if\n");
}
else
{
printf("else\n");
}
return 0;
}
#undef else
A note for newbies: Never do this in real life! Instead, think about your problem again...
What you probably wanted is :
#include <stdio.h>
int main(void)
{
int one_condition = 1;
int other_condition = 2;
if ((one_condition == 1) || (other_condition == 2))
{
printf("if\n");
}
if ((one_condition != 1) || (other_condition == 2))
{
printf("quasi-else\n");
}
return 0;
}
You can replace the else-path by having another if-clause with negated conditions. This gives you the possibility to override it with a second condition.
No, that is not possible (inside the same process).
Maybe you've misunderstood your problem.
If you want a code block to execute regardless of the condition, take it out of the if...else statement.
void foofunc(int n)
{
a = 44*n;
if(a == 484)
{
//do something
}
else
{
//do something if a DOES NOT equal 484
}
//do something regardless of the outcome of the test.
}
In this example, ridiculous though it is, the last line is outside the condition statement, so will execute whether a == 484 or not, which seems to me to be the same as making c trigger your else block regardless of the if test succeeds.
Of course, else blocks are not mandatory, so if you don't care what happens if your condition fails, then simply don't have an else block.
void foofunc(int n)
{
a = 44*n;
if(a == 484)
{
//do something
}
//do something regardless of the outcome of the test.
}
I assume you're trying to have both branches of this sort of statement execute?
Dim X As Boolean
X = False
If X = True Then
...
Else
...
End If
You could get it to execute using GoTo ... but that goes against good programming practice.
Dim X As Boolean
X = False
If X = True Then
...
Goto ElseStuff
Else
ElseStuff:
...
End If
Instead of that you should write separate procedures / functions to accomplish the behavior you'd like to have execute in both statements ... or simply put the code which should execute in all cases outside of the If block.
That would be functionally equivalent to using the GoTo, plus it makes it clear to anybody else.

Resources