我的表达式是?:operator:
(adc.Voltage1[Counter.ADC_ConversionCount] = ADC_readResult(Handler.myAdc, ADC_ResultNumber_1)) > 10 ? Counter.WriteOut = 1 : Counter.WriteOut = 0;
与if-else相同的表达式:
if((adc.Voltage1[Counter.ADC_ConversionCount] = ADC_readResult(Handler.myAdc, ADC_ResultNumber_1)) > 10 ){
Counter.WriteOut = 1;
}else{
Counter.WriteOut = 0;
}
为什么我得到"表达必须是可修改的左值"第一种情况的错误?
ADC_readResult函数的返回类型是uint_least16_t。这是Counter结构定义和ADC结构定义:
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;
答案 0 :(得分:4)
您获得的错误与解析表达式的方式有关。
你的表达式(简化)如下所示:
(a = b) < 10 ? c = 1 : c = 0
三元运算符?:
的优先级高于赋值运算符=
。虽然内部=
被视为三元的一部分,但最右边的却不是。所以表达式解析如下:
((a = b) < 10 ? c = 1 : c) = 0;
结果是您尝试将值0分配给非左值的表达式,即变量名称或解除引用的指针。你需要括号来解析你想要的方式:
((a = b) < 10) ? (c = 1) : (c = 0);
由于您正在做的是根据表达式为c
分配值,因此可以简化如下:
c = ((a = b) < 10) ? 1 : 0;
甚至:
c = ((a = b) < 10);
翻译回您的代码:
Counter.WriteOut = (adc.Voltage1[Counter.ADC_ConversionCount] = ADC_readResult(Handler.myAdc, ADC_ResultNumber_1) > 10);
通过拆分操作使其更具可读性:
adc.Voltage1[Counter.ADC_ConversionCount] = ADC_readResult(Handler.myAdc, ADC_ResultNumber_1);
Counter.WriteOut = (adc.Voltage1[Counter.ADC_ConversionCount] > 10);
答案 1 :(得分:2)
我认为应该是:
Counter.WriteOut = (adc.Voltage1[Counter.ADC_ConversionCount] = ADC_readResult(Handler.myAdc, ADC_ResultNumber_1)) > 10 ? 1 : 0;
答案 2 :(得分:2)
?:
运算符的优先级高于=
运算符,因此第一个表达式被解释为
(
(adc.Voltage1[Counter.ADC_ConversionCount] = ADC_readResult(Handler.myAdc, ADC_ResultNumber_1)) > 10 ?
Counter.WriteOut = 1 : Counter.WriteOut
) = 0
因此,=
的左手表达式无法修改。
使用括号来避免这种情况:
(adc.Voltage1[Counter.ADC_ConversionCount] = ADC_readResult(Handler.myAdc, ADC_ResultNumber_1)) > 10 ? Counter.WriteOut = 1 : (Counter.WriteOut = 0);
(Counter.WriteOut = 1
不需要括号,因为它位于?:
运算符的中间,并且没有歧义)
因为分配的是常见Counter.WriteOut
,所以我更喜欢
Coumter.WriteOut = ((adc.Voltage1[Counter.ADC_ConversionCount] = ADC_readResult(Handler.myAdc, ADC_ResultNumber_1)) > 10 ? 1 : 0);
或者,使用C的比较运算符的定义(它返回1表示true,0表示false),
Coumter.WriteOut = ((adc.Voltage1[Counter.ADC_ConversionCount] = ADC_readResult(Handler.myAdc, ADC_ResultNumber_1)) > 10);