Can anyone explain me why this line of code is wrong?
int n = 0, y = 1;
y == 1 ? n = 0 : n = 1;
The error is "Lvalue required as left operand of assignment " for "n=1"
The statement
(y == 1 ? n = 0 : n) = 1;
is interpreted as because n binds with ?: operator due to its higher precedence.
= needs l-value as its left operand while ?: returns an r-value.
Try this instead
y == 1 ? n = 0 : (n = 1);
or
n = y == 1 ? 0 : 1;
You should use :
n = y==1 ? 0 :1
According to the C standard, the behaviour is undefined if an attempt is made to use the result of the conditional operator as an Lvalue.
You can use ternary operator for assigning for example:
int n = 0, y = 1;
n = y == 1 ? 0 : 1;
Related
I have this expression with ?: operator:
(adc.Voltage1[Counter.ADC_ConversionCount] = ADC_readResult(Handler.myAdc, ADC_ResultNumber_1)) > 10 ? Counter.WriteOut = 1 : Counter.WriteOut = 0;
And the same expression with if-else:
if((adc.Voltage1[Counter.ADC_ConversionCount] = ADC_readResult(Handler.myAdc, ADC_ResultNumber_1)) > 10 ){
Counter.WriteOut = 1;
}else{
Counter.WriteOut = 0;
}
Why am I getting "expression must be a modifiable lvalue" error in the first case?
The ADC_readResult function return type is uint_least16_t. Here is the Counter struct definition and the ADC struct definition:
typedef struct __COUNTERS__ {
uint16_t WriteOut;
uint16_t ADC_ConversionCount;
uint16_t ADC_CycleCount;
uint8_t LimitADCReached1;
uint8_t LimitADCReached2;
uint8_t LimitADCReached3;
uint8_t LimitADCReached4;
uint8_t LimitADCReached5;
} COUNTERS;
typedef struct __ADC_VOLTAGES__ {
uint16_t Voltage1[ADC_VAL];
uint16_t Voltage2[ADC_VAL];
uint16_t Voltage3[ADC_VAL];
uint16_t Voltage4[ADC_VAL];
uint16_t Voltage5[ADC_VAL];
} ADC;
The error you're getting has to do with the way the expression is parsed.
Your expression (simplified) looks like this:
(a = b) < 10 ? c = 1 : c = 0
The ternary operator ?: has higher precedence than the assignment operator =. While the inner = is seen as part of the ternary, the rightmost one is not. So the expression parses like this:
((a = b) < 10 ? c = 1 : c) = 0;
The result is that you're trying to assign the value 0 to an expression that is not an lvalue, i.e. a variable name or a dereferenced pointer. You would need parenthesis for it to parse the way you want:
((a = b) < 10) ? (c = 1) : (c = 0);
Since what you're doing is assigning a value to c based on an expression, it can be simplified as follows:
c = ((a = b) < 10) ? 1 : 0;
Or even:
c = ((a = b) < 10);
Translating back to your code:
Counter.WriteOut = (adc.Voltage1[Counter.ADC_ConversionCount] = ADC_readResult(Handler.myAdc, ADC_ResultNumber_1) > 10);
And made more readable by splitting the operations:
adc.Voltage1[Counter.ADC_ConversionCount] = ADC_readResult(Handler.myAdc, ADC_ResultNumber_1);
Counter.WriteOut = (adc.Voltage1[Counter.ADC_ConversionCount] > 10);
I think it should be:
Counter.WriteOut = (adc.Voltage1[Counter.ADC_ConversionCount] = ADC_readResult(Handler.myAdc, ADC_ResultNumber_1)) > 10 ? 1 : 0;
The ?: operator has higher precedence than = operator, so the first expression is interpreted as
(
(adc.Voltage1[Counter.ADC_ConversionCount] = ADC_readResult(Handler.myAdc, ADC_ResultNumber_1)) > 10 ?
Counter.WriteOut = 1 : Counter.WriteOut
) = 0
Therefore, the lefthand expression of = is not modifiable.
Use parenthesis to avoid this:
(adc.Voltage1[Counter.ADC_ConversionCount] = ADC_readResult(Handler.myAdc, ADC_ResultNumber_1)) > 10 ? Counter.WriteOut = 1 : (Counter.WriteOut = 0);
(no parenthesis are needed for Counter.WriteOut = 1 because it is middle of ?: operator and no ambiguity is there)
Because what is assigned are common Counter.WriteOut, I prefer
Coumter.WriteOut = ((adc.Voltage1[Counter.ADC_ConversionCount] = ADC_readResult(Handler.myAdc, ADC_ResultNumber_1)) > 10 ? 1 : 0);
or, using definition of comparision operators of C (it returns 1 for true and 0 for false),
Coumter.WriteOut = ((adc.Voltage1[Counter.ADC_ConversionCount] = ADC_readResult(Handler.myAdc, ADC_ResultNumber_1)) > 10);
for (minus == false ? i = 0 : i = 1; string[i] >= '0' && string[i] <= '9'; ++i)
{
intValue = string[i] - '0';
minus == false ? result = result * 10 + intValue :
result = result * 10 - intValue;
}
error: expression is not assignable
screenshot - http://share.pho.to/AarcJ
https://codeshare.io/5Pdd7X
minus == false ? i = 0 : i = 1 will be parsed as (minus == false ? i = 0 : i) = 1 because of operator precedence rule. After evaluation of minus == false ? i = 0 : i, left side of operator = will become an rvalue, but assignment operator must have an lvalue as its left operand.
Change it to minus == false ? (i = 0) : (i = 1)
Use (for example)
for (i = minus? 1:0; string[i].... etc
And...
result = result * 10 + minus? (-lastvalue) : lastvalue;
I was solving some problems related to "or" operators in C.
The body of the program was like what mentioned below:
#include<stdio.h>
main() {
int i = 4, j = -1, k = 0, w, x, y, z;
w = i || j || k ;
x = i && j && k ;
z = i && j || k ;
printf("\n w=%d , x = %d", w, x);
printf("\n y=%d , z = %d", y, z);
}
Can someone please tell me the mechanism of these statements?
These are binary operators, they take two arguments. When confronted with a more complicated expression you can break it down into sets of binary operations.
For example, z = i && j || k; could be written as z = ( (i && j) || k ). Or in pictorial form:
z
=
||
/ \
&& k
/ \
i j
To know that the tree has this layout we look up operator precedence (or language grammar rules), the rule is that to choose between && and ||, the || is the 'outer' operation (i.e. lower precedence).
These operators also do short-circuiting, although that is not relevant in this particular example.
So, looking at the above table, i && j gives 1 because both i and j are non-zero. The 1 || k gives 1 because at least one of the operands is non-zero. Finaly 1 is assigned to z.
You can find the right values for w and x in a similar way, using the precedence rule that the left-most && is the inner one, when the situation is a && b && c, and similarly for ||.
the || and && operators are logical operators, which means they evaluate the numbers as either 'true' or 'false'
In that sense, i and j are 'true' and k is 'false'. So, calculating the outcome:
w = 'true' or 'true' or 'false' = true = 1
x = 'true' and 'true' and 'false' = false = 0
z = 'true' and 'true' or 'false' = true = 1
y isn't defined and will contain 0 or garbage
--edit--
note that && and || are left to right operators, therefore the first operator is always evaluated first.
I am a novice in C and having the following problem while compiling a simple code:
#include <stdio.h>
int main()
{
int i, a, b;
i = 3;
a = b = 0;
printf("Before: ");
printf("%d %d\n", a, b);
i == 3 ? a = 4 : a = 10; /* Line 9 */
printf("After: ");
printf("%d %d\n", a, b);
return 0;
}
Gives me error:
#gcc some.c
In function ‘main’:
some.c:9: error: lvalue required as left operand of assignment
I cannot understand it. What am i doing wrong?
This operator
i==3 ? a=4 : a = 10;
is equivalent to
( i==3 ? a=4 : a ) = 10;
Use instead
i==3 ? a=4 : ( a = 10 );
You need to assign outside the ternary operator, not inside of it, because the ternary operator binds tighter than assignment. So you should write
a = ((i == 3) ? 4 : 10);
What you wrote is equal to
(i == 3 ? a = 4 : a ) = 10;
In this code, an rvalue is being assigned to. This is the same error as writing
myfunc() = 16;
Cosmetic note: In this case it is better to use an if else statement instead of a conditional operator, because it is more clear here.
if (i == 3)
a = 4;
else
a = 10;
?: is a ternary operator.
ternary operator have higher precedence than '=' operator.
so 9th line of your code work like this..
(i == 3 ? a = 4 : a) = 10;
you have to use parenthesis or modify your sentence.
you can replace your 9th line with either of following line..
i == 3 ? a = 4 : (a = 10);
a = i == 3 ? 4 : 10;
a = (i == 3 ? 4 : 10);
Try this! :-)
Try this
if (i==3) a = 4; else a = 10;
The ternary operator does not work like this. You should use parenthesis to give higher priority to the equality operator. Check the priority precedence. By default, equality operators have least priority.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
double negation in C : is it guaranteed to return 0/1?
int main(void)
{
int i = 2, j = 1;
printf("%d", !!i +!j);
return 0;
}
From what I understand, the !! turns the expression into a bool, so is it saying since i not equal to 2 the value is 0 + j which is not equal to 1 the value is 0, and since 0 is equal to false it reads: false + false = true which represents the value of 1. Please help I am new to C programming.
C doesn't have a boolean type (well, C99 and newer do, but there's nothing in your program that uses it).
! is just a unary operator that turns 0 into 1 and anything else into 0. So in your case, since i is 2, !i is 0, and !!i is 1. j is 1, so !j is 0. That leaves !!i + !j to be be 1 + 0, and you're printing 1. Try out this example program to see it in action:
#include <stdio.h>
int main(void)
{
int i = 2, j = 1;
printf("i = %d, j = %d\n", i, j);
printf("!i = %d, !!i = %d\n", !i, !!i);
printf("!j = %d\n", !j);
printf("!!i + !j = %d + %d = %d\n", !!i, !j, !!i + !j);
return 0;
}
!x is 0 if x is true (i.e. not equal to 0) or 1 if x is false (i.e. equal to 0). Since your example i is 2, !i will be 0 and thus !!i will be 1. Likewise !j will be 0. So the result of the expression will be 1 + 0 = 1.
Note that there are no circumstances under which 0 + 0 (i.e. false + false) would equal 1.
Here's what the specification states about the ! operator (C99 §6.5.3.3/5). The terse last sentence is all that is really required to understand its behavior:
The result of the logical negation operator !is 0 if the value of its operand compares
unequal to 0, 1 if the value of its operand compares equal to 0.
The result has type int.
The expression !E is equivalent to (0==E).
We can use the transformation from the third sentence to evaluate your expression, !!i + !j. The transformation becomes:
(0 == (0 == i)) + (0 == j)
and we can evaluate it as follows:
(0 == (0 == 2)) + (0 == 1) // substitute the variable values
(0 == (0 )) + (0 == 1) // 0 == 2 is false, so it becomes 0
(0 == (0 )) + (0 ) // 0 == 1 is false, so it becomes 0
(1 ) + (0) // 0 == 0 is true, so it becomes 1
1 // 1 + 0 is 1