union 类型的指针(也包含一个结构体),指向浮点数 C
Posted
技术标签:
【中文标题】union 类型的指针(也包含一个结构体),指向浮点数 C【英文标题】:Pointer of type union (which also contains a struct) to an array of floats C 【发布时间】:2014-03-07 15:17:42 【问题描述】:我有一个浮点值数组,它表示一系列复数(所以数组的第一个值,比如 x[0],是第一个复数的实部,x[1] 是第一个复数的虚部,x[2] 是第二个复数的实部,依此类推……)。
我的问题是我希望能够像访问结构格式一样访问这些数字,即
struct cmpx
float real;
float imag;
;
typedef struct cmpx COMPLEX;
所以我像这样创建一个联合:
typedef union complexdata
float numbers[2];
COMPLEX cart; //Stands for cartesian
complexpair;
所以我简化的 main() 函数如下所示:
void main(void)
float x[10]=1.0,0.0,1.0,0.0,1.0,0.0,1.0,0.0,1.0,0.0;// In reality this is much longer
complexpair *x_ptr;
x_ptr->numbers[0] = x;
这显然是错误的,我得到了错误:
对于“x_ptr->number[0] = x;”行,“float *”类型的值不能分配给“float”类型的实体
是否可以按照我上面定义的方式使用联合类型的指针来指向浮点值数组?这样我就可以访问结构/笛卡尔格式的数据并将其视为两个浮点值的数组?
感谢您的帮助。
更新:只是为了说明我为什么要这样做;
我有一个带有原型的 FFT 函数:
void fft(COMPLEX *Y, int M, COMPLEX *w)
所以想将 x 作为第一个参数传递,我有变量 w,它与 x 的格式完全相同。当我尝试类似:
fft((COMPLEX)x->cart, N, (COMPLEX)w_ptr->cart);
这会引发错误。我希望这背后的动机更清楚? 非常感谢。
【问题讨论】:
w 是错字,现在改了。 我需要更多信息来提供帮助。你到底想要什么结果?例如,您是否希望能够通过键入x_ptr->cart.real
来访问第一个1.0
,并通过键入x_ptr->cart.imag
来访问第一个0.0
?
是的,但也能够以 x_ptr->numbers[0] 和 x_ptr->numbers[1] 的形式访问它们,因此是联合体。
不应该像fft((COMPLEX *)x_ptr, N, (COMPLEX *)w_ptr);
那样使用正确的转换为COMPLEX指针的fft调用工作吗?
【参考方案1】:
好吧,很遗憾,我无法理解您到底想要什么,但我确实从您的问题的上半部分对您想要什么有一个模糊的猜测,所以这就是我所理解的:
您有一个float
值数组,这些值将被解释为COMPLEX
数据类型的real
和imag
部分。
数组的2n - 1
'th 元素将被解释为n
'th 元素的real
部分,2n
'th 元素将被解释为imag
部分。
现在这是一个假设:您希望以某种理想的方式访问它们。
如果我说得对,您可以通过巧妙地使用指针来实现这一点。通过float x[2n]
的声明/初始化,您拥有以下内容:
float x[10] = 1.0, 1.5, 2.0, 2.5, 3.0, ... //changed numbers for better distinction
在内存中,上面的内容有以下内容:
1.0 1.5 2.0 2.5 3.0 ...
//addresses or memory locations of which are:
x x+1 x+2 x+3 x+4 ...
现在,只需在初始化期间分配 complexpair * x_ptr = x;
或之后分配 x_ptr = x;
,您就可以通过以下方式访问相同的内存位置:
x_ptr x_ptr+1 x_ptr+2 ...
仅此而已!您现在有一个简单的方法来访问所有这些,只需使用以下两行:
...
float x[10] = 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5 ;
complexpair *x_ptr = x;
...
要访问COMPLEX
es 的real
和imag
部分,您可以简单地编写:
x_ptr[0].cart.real; //is 1.0
x_ptr[0].cart.imag; //is 1.5
x_ptr[2].cart.imag; //is 3.5
x_ptr[4].numbers[0]; //is 5.0
...
作为参考,这里是我用于行为检查的整个代码:
#include <stdio.h>
typedef struct cmpx
float real;
float imag;
COMPLEX;
typedef union complexdata
float numbers[2];
COMPLEX cart;
complexpair;
int main( )
float x[10] = 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5 ;
complexpair *x_ptr = x;
for ( int i = 0; i < 5; i++ )
printf( "%f %f\n", x_ptr[i].cart.real, x_ptr[i].cart.imag );
putchar( 10 );
for ( int i = 0; i < 5; i++ )
printf( "%f %f\n", x_ptr[i].numbers[0], x_ptr[i].numbers[1] );
getchar( );
return 0;
【讨论】:
好的,谢谢你的回复,当我尝试类似 complexpair *x_ptr = x;它会产生错误。我可能应该添加更多信息,稍后查看更新的问题。 @bluefocs 我不明白它是如何产生错误的......上面的代码完全一样,不会产生任何错误,只是一个警告。您可以将类型转换的x
分配给x_ptr
以消除该错误,例如:complexpair *x_ptr = (complexpair *) x;
也可以消除该警告。但这应该只是一个警告,而不是错误......
这就是我解决错误的方法。我正在为嵌入式系统编写此代码,因此编译器可能会出现奇怪的行为。
@bluefocs 关于您上次的编辑,函数fft
需要一个COMPLEX
结构的地址,但是您通过调用它来将结构本身赋予它fft((COMPLEX)x->cart, N, (COMPLEX)w_ptr->cart);
。那里的类型转换也应该是完全多余的,因为这些值已经是COMPLEX
es。如果您想要实现的是能够在fft
中操作x->cart
和w_ptr->cart
,那么只需像这样调用函数:fft(&x->cart, N, &w_ptr->cart);
。或者你想合法地玩弄例如 Y
,不仅仅是*Y
,在fft
里面?
我只需要在 fft 函数中操作 x->cart 和 w_ptr->cart,即只要它保留 COMPLEX 结构,我就对联合感到烦恼,所以 fft(&x->cart, N,&w_ptr->cart),有效。谢谢。【参考方案2】:
在 OP 发表评论后编辑。
你应该能够做你想做的事,你需要重新格式化那个长的初始化器(在堆栈上):
void main(void)
complexpair x[5]= 1.0,0.0,
1.0,0.0,
1.0,0.0,
1.0,0.0,
1.0,0.0 ;// In reality this is much longer
complexpair *x_ptr = x;
或者只是重新投射数据:
void main(void)
float x[10]=1.0,0.0,1.0,0.0,1.0,0.0,1.0,0.0,1.0,0.0;// In reality this is much longer
complexpair *x_ptr = (complexpair *)x;
【讨论】:
你确定complexpair *x_ptr = x;
是正确的吗?以上是关于union 类型的指针(也包含一个结构体),指向浮点数 C的主要内容,如果未能解决你的问题,请参考以下文章