C 空指针:怎么了?
我有一个3字节的变量,但因为C中没有3字节的变量,所以我使用了长32位。然后我只想在总线上发送3个字节。我以ext Ram 8位宽度访问总线。 为了只发送3个字节,我需要将长值分解为2字节(短)和1字节(字符) 我所做的是: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
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”的数组。分别分配每个字节,并使用指向起始的指针。