Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C-表达式必须是可修改的左值_C_Pointers_Void Pointers - Fatal编程技术网

C-表达式必须是可修改的左值

C-表达式必须是可修改的左值,c,pointers,void-pointers,C,Pointers,Void Pointers,我不明白为什么我的编译器在以下情况下抛出错误: void funcExample (void * p_Buf, uint16_t len) { uint16_t i; for (i = 0; i < len; i++) { otherFunc (((uint8_t *)p_Buf)++); //error = expression must be a modifiable lvalue } } void函数示例(void*p_Buf,uint1

我不明白为什么我的编译器在以下情况下抛出错误:

void funcExample (void * p_Buf, uint16_t len) 
{
    uint16_t i;

    for (i = 0; i < len; i++) {
        otherFunc (((uint8_t *)p_Buf)++); //error = expression must be a modifiable lvalue
    }
}
void函数示例(void*p_Buf,uint16_t len)
{
uint16_t i;
对于(i=0;i
但如果我在传递给otherFunc之前进行强制转换,则可以,因为递增非空指针没有问题:

void funcExample (void * p_Buf, uint16_t len) 
{
    uint16_t i;
    uint8_t * p_Buf_8bit;

    p_Buf_8bit = (uint8_t *) p_Buf;   

    for (i = 0; i < len; i++) {
        otherFunc (p_Buf_8bit++); 
    }
}
void函数示例(void*p_Buf,uint16_t len)
{
uint16_t i;
uint8_t*p_Buf_8bit;
p_Buf_8bit=(uint8_t*)p_Buf;
对于(i=0;i

无效指针不能在强制转换后递增吗?我是不是错过了一些基本的东西

强制转换操作的结果是右值,而不是左值<代码>((uint8_t*)p_Buf)+
根本不是合法的C代码。

C
中增加
void
指针是个坏主意。大多数编译器甚至不允许对其进行编译。改用这个:

p_Buf = (uint8_t*)p_Buf + 1;
c中的Cast运算符:

6.5.4。在表达式前面加括号的类型名的p5转换 将表达式转换为命名类型此结构称为“类型转换”。104)指定 任何转换都不会对表达式的类型或值产生影响

104)强制转换不会产生左值。因此,对限定类型的强制转换与对限定类型的强制转换具有相同的效果 类型的非限定版本

但是一元运算符
++
需要一个左值,如下所述:

6.5.3.1。p1前缀递增或递减运算符的操作数应具有原子、限定、, 或非限定实数或指针类型,且应为可修改的左值。

因此,您可以:

p_Buf = ( uint8_t* )p_Buf + 1 ;
其中,
p_Buf
为左值,
(uint8_t*)p_Buf
为右值



让我注意一下,在第二个示例中,您没有强制转换(如您所说),而是声明了一个uint8\u t指针。然后,当您在其上使用
++
时,您不会执行任何强制转换(因为它具有正确的类型),并且该操作是有效的。

发布的@2501答案是绝对正确的,但没有解释为什么标准要求后期增量使用左值。基本原因是,您需要一个左值(变量或内存位置),以便post增量执行其增量

当您将
p\u Buf
转换为
uint8\u t*
类型时,您已经在C中创建了一个右值。简单来说,右值表示可以传递给函数、分配给变量等的瞬时值。增量后返回原始值,然后更新存储该值的变量或内存位置,增加它。因为它们只在表达式的持续时间内存在,所以不能更新右值,并且不能对它们进行增量后操作。因此,问题在于

    otherFunc (((uint8_t *)p_Buf)++); //error = expression must be a modifiable lvalue
((uint8_t*)pBuf)
只是一个右值表达式,没有实际的存储位置。实际上,强制转换意味着您只使用
p_Buf
的值,而不再直接使用变量
p_Buf

另一方面,将强制转换指定给变量时:

p_Buf_8bit = (uint8_t *) p_Buf;
那么变量
p_Buf_8bit
是一个左值,表示变量或内存位置。这可以后加,使其成为C语言中格式完美的语句:

    otherFunc (p_Buf_8bit++); 

您正在将您的
void
指针转换为
uint8\u t
,而不是指向它的指针。@Seprum No我不是。您可能已经看到了一个旧的编辑。刷新页面。感谢您的回复和标准参考。是的,第二个任务不是强制转换。不完全相同,但非常重要。感谢您的额外解释->这真的很有帮助。问题在于强制转换的临时性/暂时性(右值对左值)。非常感谢。