I'm working on a function that inserts a value in a binary search tree, I wrote this code:
// this is my decalarations if its relevent
typedef struct element* tree;
typedef struct element
{
type data;
tree right;
tree left;
} noed;
tree rightSon(tree head)
{
return (head->right);
}
void insert(tree* a,int val)
{
if(!empty(*a)) {
if((*a)->data>val) {
if(!empty(leftSon(*a)))
insert(&leftSon(*a),val); // error here leftson return a tree
else {
(*a)->left=newNoed(val);
}
}
else if((*a)->data<val) {
if(!empty(rightSon(*a)))
insert(&rightSon(*a),val); //same error here
else
(*a)->right=newNoed(val);
}
else printf("value already exist!\n");
}
else {
*a=newNoed(val);
}
}
I solved the problem by declaring local variables of type tree
then assigning the values to them like this:
tree lson;
lson=leftson(*a);
insert(&lson,val);
But I still don't get what was the problem in the first place.
The "l" stands for "left", as in the left hand side of the equals sign. An rvalue is the right hand value and produces a value, and cannot be assigned to directly. If you are getting "lvalue required" you have an expression that produces an rvalue when an lvalue is required.
This error occurs when we put constants on left hand side of = operator and variables on right hand side of it. Example 2: At line number 12, it will show an error L-value because arr++ means arr=arr+1. Now that is what their is difference in normal variable and array.
The result of the unary & operator is a pointer to its operand. The operand shall be an lvalue [...] How to fix this: std::localtime expects a pointer to a std::time_t so you best provide that.
It's probably best to start with what the error means. An "lvalue" is something that appears on the left side of an equals sign. What it means is that your argument to the "address of" operator (&) must be something that you could assign to. In your case, this isn't syntactically correct:
An "lvalue" is something that appears on the left side of an equals sign. What it means is that your argument to the "address of" operator (&) must be something that you could assign to. In your case, this isn't syntactically correct:
It seems the function leftSon
(and rightSon
) has the return type tree
. That is it returns a temporary object. You may not apply the operator & to a temporary object like in this statement
insert(&leftSon(*a),val);
You could write the code without calling the functions leftSon or rightSon like
if(!empty(rightSon(*a)))
insert( &(*a)->right ,val);
In fact the if-else statements like this
if(!empty(leftSon(*a)))
insert(&leftSon(*a),val); // error here leftson return a tree
else
{
(*a)->left=newNoed(val);
}
are redundant. Instead of them you could just write
insert( &(*a)->left, val );
and
insert( &(*a)->right, val );
Your rightSon
function is returning the value of the pointer object stored at head->right
. You can't take the address of a value.
What you want to do instead is have rightSon
return the address of head->right
which can then be passed directly to insert
.
So change rightSon
to return the address:
tree *rightSon(tree head)
{
return &head->right;
}
And call it like this:
insert(rightSon(*a),val);
leftSon
presumably has the same issue, so make a similar change for that.
Also, hiding a pointer behind a typedef
is considered bad practice as it's no longer obvious by just looking at the code that a variable of that type is a pointer and can cause confusion to the reader.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With