General C program - c

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.

Related

if/else logic using NULL

I'm not sure if I understand the conditionals using = NULL and != NULL.
Is this
if (somethin->example == NULL)
{
do task A
return;
}
else
{
do task B
}
the same as this?
if (somethin->example != NULL)
{
do task B
}
else
{
do task A
return;
}
Yes, they are equivalent.
== is the inverse of !=. If you both invert the condition and swap the if and else blocks the two changes cancel out. These are equivalent:
if (a)
{
foo();
}
else
{
bar();
}
and
if (!a)
{
bar();
}
else
{
foo();
}
Yes. They are the same, the only difference is the order of comparison (is NULL vs. is not NULL)
and the order of operation blocks that go below the if statement based on the conditions written and conditions met.
if (x == y) {
do(x);
} else {
do(y);
}
is the same as
if (x != y) {
do(y);
} else {
do(x);
}
So the difference is that in the first sample we are evaluating that x is equal to y, so precedence of "equal" takes place, while the second sample we are evaluating that x is not equal to y, therefore precedence of "not equal" takes place.

pass bool variable by reference in function argument

I am trying to include a boolean flag in the below function argument to see whether a value already exists in the current tree structure of values.
VLTreeNode *addNewNode(AVLTreeNode *currentNode, int k, int v, bool *ifExist)
{
if (currentNode == NULL)
{
return newAVLTreeNode(k, v);
}
if (k == currentNode->key && v == currentNode->value)
{
*ifExist = true;
return currentNode;
}
else if ((k == currentNode->key && v < currentNode->value) || k < currentNode->key)
{
currentNode->left = addNewNode(currentNode->left, k, v, &ifExist);
currentNode->left->parent = currentNode;
}
else if ((k == currentNode->key && v > currentNode->value) || k > currentNode->key)
{
currentNode->right = addNewNode(currentNode->right, k, v, &ifExist);
currentNode->right->parent = currentNode;
}
}
The call of this function would be like the following:
bool ifExist = false;
Tree->root = addNewNode(Tree->root, k, v, &ifExist);
if (ifExist)
{
T->size++;
}
and it does not work... could someone give me some hints what goes wrong in the code. Much appreciated.
In addNewNode, in your last two else if blocks, you're passing in &ifExist. But ifExist is a bool* already, should just pass in ifExist.
I'm not sure, but It's possible that the return statements only in the first if blocks is ok so long as those cover all possible base cases of your recursive function. [I was not thinking straight, the return statements are definitely necessary in all branches - I meant that setting ifExist to true is only required in the base cases...]
But yeah, the passing ifExist by reference (effectively now bool **) inside addNewNode is definitely not right.
EDIT: To clarify, in your outermost call to addNewNode where you have...
bool ifExist = false;
Tree->root = addNewNode(Tree->root, k, v, &ifExist);
...you do need to pass in by reference.
But inside addNewNode, your last two if else blocks should be
else if ((k == currentNode->key && v < currentNode->value) || k < currentNode->key)
{
currentNode->left = addNewNode(currentNode->left, k, v, ifExist);
currentNode->left->parent = currentNode;
}
else if ((k == currentNode->key && v > currentNode->value) || k > currentNode->key)
{
currentNode->right = addNewNode(currentNode->right, k, v, ifExist);
currentNode->right->parent = currentNode;
}
I would advise doing instead:
bool exists = false;
bool * ifExist = &exists;
Tree->root = addNewNode(Tree->root, k, v, ifExist);
That way, the way addNewNode arguments look is consistent everywhere... which will prevent future arcidents due to copy paste.

How can i point to another pointer then increment the first one's value without changing the second's value

How can i iterate over the list using X without actually changing list->tete value
celluleS* rechercherC(listeS *list,int val){
celluleS *X = list->tete;
celluleS *Y = NULL;
while(X != NULL && X->s != NULL && val != X->s->value ){
Y = X;
X = X->succ;
}
return Y;
}
At no point in your code are you changing the list->tete value.
*X = list->tete means X is a pointer to the head of the list
your assignments Y = X; and X = X->succ; do not change the values that X and Y are pointed to nor does it change any property of the list.
If the list->tete value is changing, you are changing the value elsewhere in your code.

Count elements in vector or check whether element is in array in D

How can I check whether an element is in an array or count occurences of a specific element?
I know that I can hack that myself:
int main()
{
int [] a = [1,2,3,4,3,4,5,6,6,3,3,3];
assert(count(a,6) == 2);
assert(contains(a,7) == false);
return 0;
}
uint count(T)(T[] a, T t){
uint cnt = 0;
foreach(elem; a){
if(elem == t) ++cnt;
}
return cnt;
}
bool contains(T)(T[] a, T t){
foreach(elem; a){
if(elem == t) return true;
}
return false;
}
but there must be a "library-way" to do it!
edit: I just compared std.algorithm's canFind() and my contains() and it turns out, that contains is faster. Strange but true.
For count see: std.algorithm.count.
For contains: std.algorithm.canFind. For sorted arrays you can use SortedRange (contains method uses binary search).

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

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

Resources