我正在使用带有mingw GCC编译器的代码块来为Windows编写我的C程序。我有一个函数定义,其中输入是类型为int
的数组。我有另一个struct
定义为
typedef struct {
float re;
float im;
}complex_float;
我想将int类型数组转换为complex_float
类型数组,因为我需要处理complex_float
格式的数据。我使用以下指针方法进行转换
complex_float *comSig = (complex_float *) sigbuf;
其中sigbif
是指向整数数组起始地址的int
指针。
但是当我做printf("%f",comSig[0].re);
时,我会得到一些像-1.#QNAN0
这样的垃圾值。
我已经在LINUX上多次使用这种技术进行数组之间的数据转换,但它确实有效。这是一个与mingw编译器无法正常工作相关的问题,还是与我使用不正确的方法将int数组转换为struct数组的事实有关。
答案 0 :(得分:4)
你正在做的事情绝对错误。转换值的类型不会“转换”值,而只是告诉编译器将其视为不同的类型。作为一个int和你的结构很可能有不同的大小,从它们创建的数组也是如此,所以你甚至可以写/读过整数数组的边界。如果你真的想将整数转换为复数,你必须自己编写代码:
int number_of_items = 10; // e. g. there are 10 integers
int *int_arr = // however you obtain the integer array
complex_float *cpx_arr = malloc(sizeof(*cpx_arr) * number_of_items);
int i;
for (i = 0; i < number_of_items; i++)
{
cpx_arr[i].re = (float)(int_arr[i]);
cpx_arr[i].im = 0.0f;
}
当然,使用后不要忘记free(cpx_arr)
。
答案 1 :(得分:2)
在C中,没有这样的转换功能。你所做的只是一个pointer cast
。
当你这样做时会发生什么:
sigbuf指向一个整数数组。当你将它转换为(complex_float *)并尝试访问第一个struct元素的实部时,你实际上访问了数组的第一个整数值,但它似乎是垃圾,因为你隐式地将它转换为浮点值。
让我为你说明一下, 当你有一个数组大小为n的整数。实际上你有这样的顺序数据:
[INT0] [INT1] [INT2] [INT3] [INT4] [INT5] [INT6] [INT7] [INT8] ... [INTN]
当你像这样投射时:complex_float *comSig = (complex_float *) sigbuf;
编译器会像这样处理你的数据(注意,现在它们被视为float):
[RE0] [IM0] [RE1] [IM1] [RE2] [IM2] [RE3] [IM3] [RE4] [IM4] ... [RE(N / 2)] [IM(N / 2 )]
因此,演示结果只是告诉编译器将整数数据视为float,这将导致似乎垃圾输出。对于解决问题的正确方法,H2CO3提供了另一个答案。
答案 2 :(得分:0)
结构的大小可能与编译时的大小不同。有关更多信息,请查看http://en.wikipedia.org/wiki/Data_structure_alignment。但是,您可以使用gcc的扩展名来禁用它(http://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html)。 除此之外,您可能存在潜在的未对齐访问问题。 x86是由架构处理的,但是为了便于移植代码,而不是类型转换,我会使用memcpy。
答案 3 :(得分:0)
到目前为止,答案已经指出了您的方法的大部分问题,即显式值转换,结构对齐以及结构数组与int数组。我还要补充一点:
int and float types are both of size 4 bytes, I have checked that...
Int和float在内存中以完全不同的方式表示。
整数值在所谓的Two's complement中表示,它允许在没有额外操作的情况下添加整数,并提供数字0
的单个表示:
151
表示为00000000 00000000 00000000 10010111(2)
= 2^7 + 2^4 + 2^2 + 2^1 + 2^0
。-151
表示为11111111 11111111 11111111 01101001(2)
(与正数比较)。另一方面,单精度浮点表示为IEEE 754-2008标准中的binary32:
所以151.0
表示为01000011 00010111 00000000 00000000
,其指数为134
(7
无偏),尾数为0.1796875
({ {1}}因为整数部分是隐式的。
这就是为什么,如果你将1.1796875
转换为float *
,这相当于你所做的,那么当你以后取消引用它时,你会得到垃圾值。 H2CO3 通过赋值运算符指出了正确的转换方法。