是否允许对左值操作进行类型转换?

时间:2015-05-08 06:10:08

标签: c pointers gcc

我有以下代码,其中我正在对void指针进行整型指针的类型转换,并尝试分配char地址。

void main()
{
   int *ptr;
   char a = 10;
   (void *)ptr = &a;
   printf("%d\n", *ptr);
}

我收到以下错误,无论如何我能解决这个问题吗?

error: lvalue required as left operand of assignment
    (void *)ptr = &a;

6 个答案:

答案 0 :(得分:4)

是,您无法在C中强制转换赋值运算符的左操作数

此外,在您的情况下,您可以通过另一种方式使代码工作:

void main()
{
   int *ptr;
   char a = 10;
   ptr = (int*) &a; // this is perfectly fine
   printf("%d\n", *ptr);
}

答案 1 :(得分:3)

左值的施法是有效的,即(void *)ptr本身是有效的,但它不再是左值。这称为左值转换

修复,正如@Joachim所评论的那样:

ptr = (int *) &a;

答案 2 :(得分:2)

ptr = (int *)&a ;

更自然,但不便携。可能会给它在小端机器上工作的印象(现在大部分时间),但依赖于&a为空后的字节。事实并非如此。

我建议

printf("%d\n", (int)a) ;

答案 3 :(得分:0)

变量或表达式的类型转换导致r值。 so(void *)ptr给出了r值,你试图将& a分配给r值。 它类似于0x12345 =& a这是错误的,所以你需要l值。

答案 4 :(得分:0)

问题与您的示例不符-但是您对问题(而不是您的示例)的回答-是-可以。方法如下:

void encode_fixed32(char *buffer,float input) {
  ((float *)buffer)[0]=input;
}

void decode_fixed32(char *buffer) {
  return ((float *)buffer)[0];
}

答案 5 :(得分:0)

编辑:此答案仅适用于C ++,不适用于C,但可能仍然适用。

您必须将左值强制转换为指向指针的引用而不是指针,然后赋值将起作用:

void main()
{
   int *ptr;
   char a = 10;
   (void *&)ptr = &a;
   printf("%d\n", *ptr);
}

void * 之后注意。这样可以保留其左值性,并可以对其进行分配。

但是,在这种特殊情况下,由于要重新将char解释为int类型,因此printf行为仍将是不确定的,即使您假定使用小端,在表示 10 < / strong>。

一个更好的用例:

int a[5];
int *ptr = a + 2; // points to the element with index=2
(char *&)ptr += sizeof(int); // advances the pointer to the next element

这很有用,例如当您在CUDA或嵌入式设备上的数组上进行跨步循环时,您想提前缓存确切的步骤,以避免每次在循环内乘以4:

const int stride = sizeof(int)*step;
int *my_ptr = first_ptr;
for (int i = 0; i < count; ++i) {
    ...
    (char *&)my_ptr += stride;
}