문제

I have an array of floating point values which represents an a series of complex numbers (so the first value of the array, say x[0], is the real part of the first complex number, x[1] is the imaginary part of the first complex number, x[2] is the real part of the second, and so on...).

My problem is that I want to be able to access these numbers as if they were in a structure format, i.e.

struct cmpx
{
    float real;
    float imag;
};
typedef struct cmpx COMPLEX;

So I create a union like so:

typedef union complexdata 
{
    float numbers[2];
    COMPLEX cart; //Stands for cartesian

}complexpair;

So my simplified main() function looks like this:

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;
}

This is clearly wrong and I get the error:

a value of type "float *" cannot be assigned to an entity of type "float" for the line "x_ptr->number[0] = x;"

Is it possible to use a pointer of union type the way I've defined above to point to an array of floating point values? So that I can access the data in the structure/cartesian format as well treating it as an array of two floating point values?

Thank you for your help.

UPDATE: Just to make it clear why I want to do this;

I have an FFT function with the prototype:

 void fft(COMPLEX *Y, int M, COMPLEX *w) 

So would like to pass x as the first argument, I have variable w which is exactly the same format as x. When I try something like:

fft((COMPLEX)x->cart, N, (COMPLEX)w_ptr->cart);

this throws an error. I hope the motivation behind this is clearer? Many thanks.

도움이 되었습니까?

해결책

Well, I unfortunately was unable to understand what exactly you are desiring to have, but I do have a vague guess about what you want from the upper half of your question, so here's what I've understood:

  • You have an array of float values that are to be interpreted as real and imag parts of the COMPLEX data type.
  • 2n - 1'th element of the array is to be interpreted as the real part of the n'th element, and 2n'th element is to be interpreted as the imag part.

  • Now this will be an assumption: You want to access them in some desirable fashion.

If I am right about those, you can achieve that by using pointers in a smart fashion. With the declaration/initialization of float x[2n], you have the following in your hands:

float x[10] = { 1.0, 1.5, 2.0, 2.5, 3.0, ... } //changed numbers for better distinction

Inside memory, you have the following for the thing above:

 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             ...

Now, by simply making the assignment complexpair * x_ptr = x; during initialization, or x_ptr = x; afterwards, you make the same memory locations to be accessible with following:

x_ptr                          x_ptr+1                         x_ptr+2           ...

And that's all! You now have an easy method to access all that, simply with these two lines:

...
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;
...

To access the real and imag parts of the COMPLEXes with this, you can simply write:

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
...

For the reference, here's the whole code I have here that I've used for behavioural examination:

#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;
}

다른 팁

EDITED after OP's comment.

You should be able to do what you want, You'll need to reformat that long initializer (on the stack):

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;

}   

OR just re-cast the data:

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;
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top