Put a condition check and variable assignment in one 'if' statement - c

I am looking at some legacy C code and got confused. It is something like:
UINT A, B = 1;
if((A = B) == 1) {
return(TRUE);
} else {
return(FALSE);
}
We all know there will be a compiler warning if we do if(A = B), but here it looks like the 'if' is checking A against 1. Am I correct?

First, it assigns the value of B to A (A = B), then it checks if the result of this assignment, which is A and evaluates to 1, is equal to 1.
So technically you are correct: On the way it checks A against 1.
To make things easier to read, the code is equivalent to:
UINT A, B = 1;
A = B;
if(A == 1){
return(TRUE);
} else {
return(FALSE);
}

Rather, your code is always assigning B to A, and it is moreover checking whether the value of B (and thus also A) is equal to 1.
There's nothing "legacy" about this, this is generally a pretty handy idiom if you need the result of an operation but also want to check for errors:
int result;
if ((result = foo()) != -1)
{
printf("The result is: %i\n", result);
}
else
{
// panic
}

If you want to keep it on 1 line:
if ((A = B), A == 1)
does the same thing.

We are trying to avoid if statements to make code more readable.
UINT A, B = 1;
bool fResult = false;
fResult = (A == B);
return(fResult);
And if there must be an condition to act on (not) equality, see this example.
UINT A, B = 1;
bool fResult = false;
fResult = (A == B);
if(fResult)
{
doThis();
}
else
{
doThat();
}
return(fResult);

Correct. The value A has after the assignment will be compared to 1.
This code sample is equivalent to just:
return (TRUE);

Related

Is there a better way to exit all recursive functions at once, rather than one by one?

Is there a better way to exit all of the recursive iterations immediately after the if(a == b) condition is met, instead of having to include lines 7 and 8 in their current form? Without lines 7 and 8 as they currently are, it seems to exit merely the last iteration.
bool recursive(int a, int b) {
if(a == b)
return true;
for(int i = 0; i < count; i++)
if(locked[b][i] == true)
if(recursive(a, i) == true)
return true;
return false;
}
It's not really critical, but I'd like to spare lines whenever possible. Any ideas?
I would probably write this like so:
bool recursive(int a, int b) {
bool result = (a == b);
for (int i = 0; i < count && !result; i++) {
result = (locked[b][i] && recursive(a, i));
}
return result;
}
Introduction of a variable to hold the working result of the function allows for testing that result as part of the condition for performing a loop iteration. That way you can terminate the loop as soon as the result flips from false to true, yet you don't need any code to distinguish after the fact between the two possible reasons for loop termination.
Yes. You could use a bit obscure functionality of C named longjmp.
It allows to jump back a stack over multiple function calls. A bit similar to throw in C++.
Firstly, return environment is created with setjmp().
It returns 0 if to was a first call to setjmp().
Otherwise it returns a value set by longjmp() called deeper in the recursive call.
#include <stdio.h>
#include <setjmp.h>
void slowrec(int n) {
if (n == 0) {
puts("done");
} else {
puts("go down");
slowrec(n - 1);
puts("go up");
}
}
jmp_buf env;
void fastrec(int n) {
if (n == 0) {
puts("done");
longjmp(env, 1);
} else {
puts("go down");
fastrec(n - 1);
puts("go up");
}
}
int main() {
puts("-- slow recursion --");
slowrec(5);
puts("-- longjmp recursion --");
if (setjmp(env) == 0) {
fastrec(5);
}
return 0;
}
produces:
-- slow recursion --
go down
go down
go down
go down
go down
done
go up
go up
go up
go up
go up
-- longjmp recursion --
go down
go down
go down
go down
go down
done
For original problem the code may look like this:
jmp_buf env;
void recursive_internal(int a, int b) {
if (a == b) longjmp(env, 1); // true
for(int i = 0; i < count; i++)
if(locked[b][i])
recursive_internal(a, i);
}
bool recursive(int a, int b) {
if (setjmp(env) == 0) {
recursive_internal(a, b);
// left without triggering long jump
return false;
}
// returned with longjmp
return true;
}
Note that there is no return value in recursive_internal because either a==b condition is met and longjmp was taken as it was the only way true could be returned. Otherwise, condition was never met and the algorithm exited via return false.

Is there a difference between multiple if statements and else if?

If I write
int a = 1;
int b = 2;
if (a == b) {
//Do something
} else if (a > b) {
//Do something else
} else if (a < b) {
//Do something else
}
as opposed to:
if (a == b) {
//Do something
}
if (a > b) {
//Do something else
}
if (a < b) {
//Do something else
}
Is there a difference be it the way the compiler interprets the code or speed? I see no logical difference, but there surely must be a reason why an if else statement exists. It's just a single line break difference.
In the scenario above, they are the same, other than speed. If/else will be faster than a series of ifs, because else statements are skipped if the if condition is satisfied. In a series of ifs, on the other hand, each condition is evaluated separately.
In other scenarios, of course, the logic is not the same, and so replacing if/else with a series of ifs breaks the program. Example:
// this:
if(x <= 0) {
x = 1;
}
else { // only true if x started out > 0
x = 37;
}
// is different from this:
if(x <= 0) {
x = 1;
}
if(x > 0) { // always true in this version
x = 37;
}
In else-if statements, when a condition is met, all other else-ifs are skipped.
Whereas in multiple if statements, it has to go through all of them.
To be more precise, Lets suppose a=b.
Consider your first code block:
int a = 1;
int b = 1;
if (a == b)
{
//Do something
}
else if (a > b)
{
//Do something else
}
else if (a < b)
{
//Do something else
}
While executing, since a=b, it will skip all other conditions (a>b & a<b).
Checks if a=b.
Executes the code block.
All others are skipped.
Consider your second code block:
int a = 1;
int b = 1;
if (a == b)
{
//Do something
}
if (a > b)
{
//Do something else
}
if (a < b)
{
//Do something else
}
Even the first condition is met, all of them will be evaluated.
Checks if a=b.
Executes the code block.
Checks if a>b.
Checks if a<b.
In second type of code you wrote. Compiler will show out put for each true statement and will not skip any condition. Else command is use to make sure that one of two conditions are matched.
the time complexity of if-else statements is less as compared to multiple if statements. Therefore if-else steements are much advantageous

General C program

The following code;
typedef struct chainCell{
int data;
struct chainCell* next;
} chainCell;
bool sameValues (chainCell *x, chainCell *y)
{
if ((x == NULL) & (y == NULL)) return true;
if ((x == NULL) | (y == NULL)) return false;
bool same = true;
chainCell *xp = x, *yp = y; // scan pointers
while ((xp != NULL) & (same == true)) // point A
{
if (xp->data != yp->data) same = false;
xp = xp->next;
yp = yp->next;
if (((xp == NULL) & (yp != NULL)) // point B
| ((xp != NULL) & (yp == NULL)))
same = false;
};
return same;
};
I am very confused as to why the loop control contains (same == true) ?
Also what is the purpose of the if statement at Point B? I'm unsure of what the Boolean expression is checking for?
Any help for further understanding would be appreciated!
It checks that two linked lists contain the same values.
Obviously, if one list is shorter, they are not identical (point B).
Note: I think using here break/return would be a better choice, it makes the code more readable.
Note2: as noted on the comments, those should be logical operators. It works as it is, but it's a bit confusing.
Note3: You could move the test before the loop inside the loop (while(1)), this would eliminate the need for the test at the end of the loop.
This is just an ugly code, it should be about 5 lines of code, not a dozen...
bool sameValues (chainCell *x, chainCell *y)
{
while(1) {
if (!x && !y) return true;
if (!x || !y) return false;
if (x->data != y->data) return false;
x = x->next;
y = y->next;
}
return false; //this is just to suppress compiler warning.
};
The function bool sameValues (chainCell *x, chainCell *y) checks if the two struct chainCell has the same value, that is to say, every field of chainCell type between x and y are equal.
"why the loop control contains (same == true) ?"
The boolean value same is an indicator whether the previously checked field are equal. If same == false, it is concluded that x and y are not the same in value, and the while loop could be break.
what is the purpose of the if statement at Point B?
The if statement set a condition that two fields can be equal, only if the two fields are both null or both not null.
Compact form of #Karoly Horvath's answer:
bool sameValues (chainCell *x, chainCell *y)
{
for( ; x || y; x = x->next, y = y->next) {
if (!x || !y) return false;
if (x->data != y->data) return false;
}
return true;
}
As I understand it that code is a loop to check whether two chainCell objects are the same.
(same == true) is included to cause the while loop to exit if a position in the cellChains is found where they don't match.
Point B is checking that if either of the chainCells being compared is null and the other is not null that the comparison returns false.
The exit from the loop would be caused by xp reaching a point where it is null.
I would also agree with Shafiks comment, the operators are bitwise and they should be logical.

Recursive function divide a number

I need to create a recursive function that receives a number by two without using /.
This is what I wrote, but it works only if after dividing it will still be a decimal number and not a float, that's why I asked.
int recursive(int a, int b){
if ( a == (0.5 * b) )
return a;
return recursive(a-1, b);
}
Btw, the function can receive only 1 parameter not 2 or more :/
I think you need something like this
int divide(int a, int b){
if(a - b <= 0){
return 1;
}
else {
return divide(a - b, b) + 1;
}
}
This divides by two using repeated subtraction and recursion.
int divide_by_two(int a) {
if (a < 0) return -divide_by_two(-a);
if (a < 2) return 0;
return 1 + divide_by_two(a - 2);
}
Generalising, this divides a by b using repeated subtraction and recursion.
int divide(int a, int b) {
if (a < 0) return -divide(-a, b);
if (b < 0) return -divide(a, -b);
if (a < b) return 0;
return 1 + divide(a - b, b);
}
Note, these functions don't round exactly the same way that division is defined to do in C.
You can try this, it should work:
int dividebytwo (int a){
static int answer = 0;
if (a < 0){
if ((answer * 2) > a){
answer --;
return dividebytwo (a);
}
return answer;
} else if (a > 0){
if ((answer * 2) < a){
answer ++;
return dividebytwo (a);
}
return answer;
}
return 0;
}
The trick here is using the static attribute. The static attribute means that the variable is only initialized once and retains its value after every function call. Really, you're using two parameters but it looks like you're only using one.
The only downside to this function is that you can only count on it to work more than once. Since this is probably for a simple homework assignment, it probably doesn't matter. But in reality, this is considered hugely inefficient and unreliable.
To compensate for the only-works-once factor, may add one of these fixes:
declare answer as a global variable and set it to 0 before every function call.
append return answer = 0; to the end of the function, instead of return 0;. This is so that whenever you want to call it again, you would call it beforehand as dividebytwo (0);.
I also cannot stress enough how weird of a concept this is, it sets of all sorts of red flags for anyone who practices careful programming - could be why you're getting so many downvotes. So use with caution!
#include<stdio.h>
int divide(int a, int b){
if( a-b < 0)
return 0;
else if ( a-b == 0)
return 1;
else {
return divide(a-b, b) + 1;
}
}
http://codepad.org/o4CoiaON

boolean expression in C

I found this expression in a C program and I didn't get it :
struct stack_rec *ss;
ss=(struct stack_rec *)EMalloc(sizeof(struct stack_rec));
if (ss) {
int res;
res = (ss->elem = * i , 1); // what does this mean ????
if (res <= 0)
return res;
if (*s == 0) {
ss->next = 0;
} else {
ss->next = *s;
}
*s = ss;
return 2;
}
return 0;
What does res = (ss->elem = * i , 1); mean? Is it a boolean expression? I've tried it with a 0 instead of 1 and it always returns the value of the second parameter! Can anyone explain this expression, please?
Looks broken. It's a use of the comma operator, which simply evaluates to the value of the final expression, i.e. 1.
Therefore, since that code is equivalent to:
ss->elem = *i;
res = 1;
The subsequent testing of res seem pointless, and thus broken.
The comma u see is a not very much used C operator.
Basically, what it does is execute the 2 statements (ss->elem = *i; and 1;). The statement 1; doesn't realy do much.
After that it returns the result from the last statement (in this case 1)

Resources