我有一个浮点数组,我通过一个函数获取它们的值,该函数接收一个void指针并将数据写入指针 . (我的想法是不仅将它用于花车)
float fArray[3];
GetValue( fArray ); //this function makes the filling
printf( "IN:%f\n", fArray[0] );
printf( "IN:%f\n", fArray[1] );
printf( "IN:%f\n", fArray[2] );
fArray[0] = *( (float *) fArray );
fArray[1] = *( (float *) fArray + 4 );
fArray[2] = *( (float *) fArray + 8 );
printf( "DEREF:%f\n", fArray[0] );
printf( "DEREF:%f\n", fArray[1] );
printf( "DEREF:%f\n", fArray[2] );
的GetValue:
void GetValue(void * array ){
for ( BYTE i = 0; i < MAX_POINTS; i++ ) {
float f = dataRegisters[i].fData;
memcpy( array + sizeof(float)*i, &f, sizeof(float) );
}
}
此代码的输出是:
IN:677.000000
IN:0.000000
IN:0.000000
DEREF:677.000000
DEREF:23.600000
DEREF:58.299999
为什么会这样?使用void指针是个好主意吗?有一种更清洁的解除引用方式吗?
提前致谢 .
4 回答
Oups,C根据指向的类型自动处理指针算术 . 因此无论
p
指向何种类型,每个定义的以下等式都是正确的:回答新版本!
我在猜测
你期望
fArray + 4
指向fArray[1]
假设sizeof(float) == 4
.但
(float *) fArray + 4
相当于&fArray[4]
,或记忆明智哪个指向未知区域(未定义fArray [4]) .
这是未定义的行为,你可能会从最后的打印中获得任何 Value ,即使是运气不错的好消息,也可能是段错等...
(
*( (float *) fArray + 8 )
的相同推理是fArray[8]
,也是未定义的)你正在做的“解除引用”就是那种 . 你只是在数组中移动元素 .
让我们仔细看看:
由于
fArray
的类型为float[3]
,因此在大多数表达式中它会衰减为float *
,因此不需要强制转换 . 所以上面是这样的:此外,由于指针算法的规则,
a[i]
与*(a + i)
相同 . 所以上面是这样的:鉴于
fArray
的大小为3,现在应该明白问题是什么 . 彻底摆脱这三条线 . 他们没有做任何有用的事情 .您的
GetValue
函数已经在进行正确的指针运算,以将值加载到数组中 . 您无需进行任何后处理 .尝试在
fArray + 4
和fArray + 8
周围添加括号或者将其更改为
fArray + 1
和fArray + 2
(首选方法)您遇到的问题是您是指向
(float *)
的指针,因此编译器认为当您想要向其添加+4
时,您希望通过4 * sizeof((float))
递增指针