C表达式必须是可修改的左值(为什么我要使用此表达式)

问题描述 投票:0回答:3

我有这个表达式?: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;
c if-statement launchpad
3个回答
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);

2
投票

我认为它应该是:

Counter.WriteOut = (adc.Voltage1[Counter.ADC_ConversionCount] = ADC_readResult(Handler.myAdc, ADC_ResultNumber_1)) > 10 ? 1 : 0;

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);
© www.soinside.com 2019 - 2024. All rights reserved.