int数组到C中的struct数组

时间:2012-08-27 07:09:53

标签: c arrays struct

我正在使用带有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数组的事实有关。

4 个答案:

答案 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的单个表示:

  • 正整数简单地转换为基数2.例如,151表示为00000000 00000000 00000000 10010111(2) = 2^7 + 2^4 + 2^2 + 2^1 + 2^0
  • 负整数表示为其绝对值的二进制表示,然后将其所有位反转,并将1加到结果数中。例如,-151表示为11111111 11111111 11111111 01101001(2)(与正数比较)。

另一方面,单精度浮点表示为IEEE 754-2008标准中的binary32

  • 第一位是符号位:0表示正数,1表示负数。
  • 接下来的8位是指数,以2的补码表示。 偏向:从此值中减去127以获得实际指数。
  • 接下来的23位表示归一化的小数部分(小数点前只有1位数)。

所以151.0表示为01000011 00010111 00000000 00000000,其指数为1347无偏),尾数为0.1796875({ {1}}因为整数部分是隐式的。

这就是为什么,如果你将1.1796875转换为float *,这相当于你所做的,那么当你以后取消引用它时,你会得到垃圾值。 H2CO3 通过赋值运算符指出了正确的转换方法。