C 空指针:怎么了?

C 空指针:怎么了?,c,void-pointers,C,Void Pointers,我有一个3字节的变量,但因为C中没有3字节的变量,所以我使用了长32位。然后我只想在总线上发送3个字节。我以ext Ram 8位宽度访问总线。 为了只发送3个字节,我需要将长值分解为2字节(短)和1字节(字符) 我所做的是: typedef union { unsigned char b[3]; unsigned long lng; } lng_array; void SendLong(unsigned long d) { volatile void* c =(void*)D

我有一个3字节的变量,但因为C中没有3字节的变量,所以我使用了长32位。然后我只想在总线上发送3个字节。我以ext Ram 8位宽度访问总线。 为了只发送3个字节,我需要将长值分解为2字节(短)和1字节(字符)

我所做的是:

typedef union
{
  unsigned char b[3];
  unsigned long lng;
} lng_array;

void SendLong(unsigned long d)
{   
  volatile void* c =(void*)Dat; // Dat is a #defined long number equal to the address on the bus that data must be sent
  lng_array tmp;
  tmp.lng=d;
  *c=*(unsigned short*)(&tmp.b[0]);  // Error
  *c=*(unsigned char*)(&tmp.b[2]);   // Error
}
对于2“*c=”行,我得到一个错误:“错误36无效使用void表达式”


这里我做错了什么?

因为变量
c
是指向void的指针类型,所以不能取消引用它(例如,读取/写入
*c
)。如果要访问它指向的内存,必须添加类型转换

C标准规定:

6.3.2.2无效

void表达式的(不存在)值(具有 类型无效)不得以任何方式使用


由于
c
是指向void解引用的指针类型,因此它会生成一个void表达式,该表达式不能用于任何事情。等号另一侧的任何内容都与此无关。

因为变量
c
是指向void的指针类型,所以不能取消引用它(例如,读取/写入
*c
)。如果要访问它指向的内存,必须添加类型转换

C标准规定:

6.3.2.2无效

void表达式的(不存在)值(具有 类型无效)不得以任何方式使用


由于
c
是指向void解引用的指针类型,因此它会生成一个void表达式,该表达式不能用于任何事情。在等号的另一边有什么与此无关。

*c
如果
c
是一个
void*
,则没有意义(无法解除限制),因为编译器需要知道它的大小。再次将其转换为
无符号字符*
,例如:
*((无符号字符*)(c))=(无符号字符*)(&tmp.b[2])c
void*
,则code>
没有意义(无法解除保护),因为编译器需要知道它的大小。再次将其转换为
无符号字符*
,例如:
*((无符号字符*)(c))=(无符号字符*)(&tmp.b[2])

是的,好的,我知道不允许直接对空指针取消引用。。但我假设,由于在同一行中有一些强制转换,编译器会将c视为指向的类型,至少对于该行是这样。我猜我的假设是错误的,但是演员阵容是无用的,因为c=&tmp.b[0];等于c=(无符号短*)&tmp.b[0];是的,好的,我知道不允许直接取消对空指针的引用。。但我假设,由于在同一行中有一些强制转换,编译器会将c视为指向的类型,至少对于该行是这样。我猜我的假设是错误的,但是演员阵容是无用的,因为c=&tmp.b[0];等于c=(无符号短*)&tmp.b[0];对于3字节变量,可以使用3个无符号字符的数组。分别分配每个字节,并通过指针指向起始位置来使用。对于3字节变量,可以使用3个“unsigned char”的数组。分别分配每个字节,并使用指向起始的指针。