Reputation: 15
first post here
I have been looking into the fft and in particular the Rosetta Code C implementation http://rosettacode.org/wiki/Fast_Fourier_transform#C
I have been trying to actually understand the code rather than just copy it however I have a problem with a particular line and more specifically a part of the line.
_fft(out+step, buf+step, n , step*2);
so we have a
typedef double complex cplx;
then an array of type cplx is declared
cplx buf[] = {1, 1, 1, 1, 0, 0, 0, 0};
We have step as an int 1
now the problem I am having understanding is what is happening when the int is added to the cplx
so I wrote a test program
#include <stdio.h>
#include <math.h>
#include <complex.h>
typedef double complex cplx;
void test(cplx buff[])
{
for(int a = 0; a < 8; a++) {
printf("%g \n", creal(buff[a]));
}
}
int main(int argc, char **argv)
{
cplx buff[] = {1,1,1,1,0,0,0,0};
int step = 1;
test(buff);
test(buff + step);
getchar();
return 0;
}
what I get is:
1 1 1 1 0 0 0 0
1 1 1 0 0 0 0 2.1231e-314
I cannot make heads or tails of it, I may be missing something pretty fundamental about C99 as I cannot seem to be able to find it on here or by google
Upvotes: 1
Views: 143
Reputation: 162164
now the problem I am having understanding is what is happening when the int is added to the cplx
Actually the addition is not <int> + <cplx>
but <int> + <cplx>*
(in words an integer plus a pointer to a complex). So what you're dealing with here is what's called pointer arithmetic. Why a pointer you ask? Because in C array types degrade into a pointer to the array's element type when used in an expression which expects a pointer at its place.
So what is pointer arithmetic?
Well, let' s assume we got an object a
which is an array of int (the length doesn't matter, as long as we don't access past its boundaries).
int a[N];
Then pointer arithmetic has been defined that the following three expressions have exactly the same meaning:
*(a + i)
a[i]
i[a]
Yes, the last one is perfectly valid C, go ahead, try it out.
What does it mean for your code snippet. Well for one thing, when you add 1 to the buffer pointer you pass to test
, you're adding an offset of one. But since the buffer is only 8 elements long and your test
function accesses 8 consecutive elements starting from the pointer given it performs an out-of-bounds access which invokes undefined behavior any in fact anything may legally happen.
Upvotes: 1
Reputation: 17573
It looks to me like you are calling test twice. The first time with the address of buff[0]
and the second time with the address of buff[step]
where the variable step
is equal to 1 so it is the same as buff[1]
.
This is why you are seeing the rotated output with
1 1 1 1 0 0 0
1 1 1 0 0 0 0
I left off the last digit. The last digit in the second line is just garbage after the end of the array or after the last element of the array buff
.
buff is an array and if you just specify the name buff
then it is treated like a pointer. So in the second call to test you are specifying &buff[step]
rather than &buff[0]
which is the same as buff
.
So buff[step]
is the same as *(buff + step)
just as buff[0]
is the same as *(buff + 0)
or just *buff
. You can either use the braces to do an index or you can do pointer arithmetic.
Upvotes: 0