1. Problem with Pointers

Hi guys!
I'm new to this world, and I'm finding some problems on pointers (as most of people on the 1st time they encounter them).

I'm going to explain my problem step by step. First of all i try to define a new struct for complex numbers (maybe some already exist).

My code is:
Code:
```typedef struct  {
float real;
float img;
} complex;```
Now I need to write a function that, when called, generates a vector of complex numbers.
These numbers must have img part =0 and real part = +1.0 or -1.0, in random way. So I thinked I could use rand() function to generate random int numbers. If generated int %2 ==0 then real part of my complex number is +1.0, in the other case -1.0.
Maybe there's a finer way to implement this, but it should work I think. After I filled my vector, I return a pointer to the 1st element of the vector.
My code:
Code:
```#include "complesso.c"
#include <time.h>
#define LENGTH 1023

complex* randomarray(){

complex vettore[LENGTH];
complex *first;
int i, iseed;
iseed = time(NULL);
srand (iseed);
for (i=0; i<LENGTH; i++)
{
vettore[i].img=0.0;
if(rand()%2==0)
vettore[i].real=-1.0;
else
vettore[i].real=1.0;
}
first=&vettore[0];
return first;

}```
At this point, my main function should get this pointer and print, for each element of the vector, real part and img part. It compiles but it sometimes gives strange values, like 0.0, or extremely big numbers, or img parts =/=0, so I tought there's some problem with pointers.
My code:
Code:
```#include <stdio.h>#include "complesso.c"

int main(){
int i;
complex *first;
complex x;
first=randomarray();
for (i=0;i<1023;i++){
x= *(first+i);
printf("%d %1.1f  %1.1f \n", i, x.real, x.img);

}

system("PAUSE");
}```
Any suggestion will be appreciated

2. Code:
`complex vettore[LENGTH];`
This is defined on the stack frame local to randomarray, which you then assign to a pointer:

Code:
`  first=&vettore[0];`
so when you return, the stack frame is reset to the previous state, anything declared and/or defined local to the function is "lost."

If you need to return an array, you can pass it as a parameter to randomarray or malloc it within randomarray and return it.

3. The problem is that things you declare inside functions are destroyed as soon as you return from the function. You're returning a pointer to memory locations that are not preserved. The way to do things like this is along the lines of

Code:
```int main( void ) {
int derp[NUM_ELEMS];
fill_array( derp );
return 0;
}
void fill_array( int *array ) {
int i;
for(i=0; i<NUM_ELEMS; i++ ) {
array[i] = i*i;
}
return;
}```
So what you're doing is creating your array in main. This array is preserved as long as main is active, ie. as long as the program is running. You pass a pointer to the array to your function, which allows you to modify the array contents through the pointer. The only things that are destroyed when fill_array finishes are the index variable i you declared in there, and the copy of the pointer to the array that you passed to it as the argument.

4. So you suggest to create the empty array on the main function and then pass a pointer to the first element to the randomarray function, that will fill it?
In this case randomarray should return nothing right? Because my array will be the same I passed to the randomarray function from main function...

So I think I got the thread, but in this case how can I do something more "modular"? Creation of this vector will be a marginal part of my software, so I tought to delegate the creation to a function, but maybe this is the best and easiest solution...

Gonna try.

5. Correct.

6. Call srand(time(NULL)); only once, at the very beginning of main(). Also, you should explicitly return an int from main, usually 0.

You can't return an array in C. Read my reply to another poster here: http://cboard.cprogramming.com/c-pro...ml#post1096704. Hopefully that clears it up. I would probably declare the array in main and pass it in. By the way, you have unnecessary variables (x in main), and you can use array syntax (i.e. [ ]) with pointers. You could just do:
Code:
```complex array[LENGTH];
...
for (i = 0; i < LENGTH; i++) {
printf("%d %1.1f %1.1f\n", i, array[i].real, array[i].img);
}```
Note, C99 does have a complex number type, but not all compilers support it. It might be worth looking into if this is more than a simple exercise.

7. Thank you all.
These pointers are blowing my mind...
I tried to change both functions:
main now should create the vector, I defined a pointer to the 1st element and pass it to randomarray function. Then inside the for cycle it points to the next element (or better, I think it does), and returns nothing because it already changed original array.

Problem is always the same :\

Code:
```#include "complesso.c"#include <time.h>
#define LENGTH 1023
randomarray(complex* index){

int i, iseed;
complex x;
iseed = time(NULL);
srand (iseed);
for (i=0; i<LENGTH; i++)
{
*(index+i).img=0.0;
if(rand()%2==0)
*(index+i).real=-1.0;
else
*(index+i).real=1.0;
}

}```
Code:
```#include <stdio.h>#include "complesso.c"

int main(){
int i;
complex vettore[1023];
complex *first;
complex x;
first=&vettore[0];
randomarray(first);
for (i=0;i<1023;i++){
x= *(first+i);
printf("%d %1.1f  %1.1f \n", i, x.real, x.img);

}

system("PAUSE");
}```

8. Code:
`randomarray(first);`
Don't pass the pointer to the vector, just pass the vector:

Code:
`randomarray(vettore);`

9. Oh now it works.

*(index+i).real=-1.0; is wrong, because all the line is considered pointer I think. I tried with (*(index+i)).real and now it works (or it seems to do).

If you have something to suggest me, here I am.

10. Originally Posted by Cynic
Code:
`randomarray(first);`
Don't pass the pointer to the vector, just pass the vector:

Code:
`randomarray(vettore);`
Uhm, if I pass the vector to the randomarray function, don't I work on a copy of the vector? Shouldn't I use pointers? Really, this stuff is blowing me out

11. Originally Posted by DeliriumCordia
Uhm, if I pass the vector to the randomarray function, don't I work on a copy of the vector? Shouldn't I use pointers? Really, this stuff is blowing me out
No. When you pass an unsubscripted array, you're passing the address where the array is stored, thus you end up working on the original since you're working on locations where the values are stored, not copies of values. I think this is part of the reason people tend to think of arrays and pointers as the same, but it's not true.

12. Ok I try this solution.
Is it suggested or more elegant then the one I used?

13. Originally Posted by DeliriumCordia
Uhm, if I pass the vector to the randomarray function, don't I work on a copy of the vector? Shouldn't I use pointers? Really, this stuff is blowing me out
No, you pass a copy of the pointer to the first element. The array "degrades" into a pointer to the first element when passed to a function. That means that when you do vettore[i] in the function, you are working on the same array that you have back in your main function. Look at my post #6.

• The array notation array[i] is shorthand for *(array + i), most people probably find it easier to read the array version, so use that when possible.
• You don't need the x variable in main. It's just unnecessary copying of values. Use vettore[i].real and vettore[i].img directly. It's clearer.
• Don't use magic numbers. Wherever you see a 1023, replace it with LENGTH.
• Don't include .c files, or any file that has actual code in it. A header should just contain the declarations you need to "export" the functionality in a library or other .c file. You should make a complesso.h file that has the prototype for randomarray as well as #define LENGTH 1023. Include that header in main.c and complesso.c.

14. Originally Posted by DeliriumCordia
Ok I try this solution.
Is it suggested or more elegant then the one I used?
There is value in passing a pointer to an array, but not in this case, so pass the array and be good.

15. Originally Posted by anduril462
No, you pass a copy of the pointer to the first element. The array "degrades" into a pointer to the first element when passed to a function. That means that when you do vettore[i] in the function, you are working on the same array that you have back in your main function. Look at my post #6.

• The array notation array[i] is shorthand for *(array + i), most people probably find it easier to read the array version, so use that when possible.
• You don't need the x variable in main. It's just unnecessary copying of values. Use vettore[i].real and vettore[i].img directly. It's clearer.
• Don't use magic numbers. Wherever you see a 1023, replace it with LENGTH.
• Don't include .c files, or any file that has actual code in it. A header should just contain the declarations you need to "export" the functionality in a library or other .c file. You should make a complesso.h file that has the prototype for randomarray as well as #define LENGTH 1023. Include that header in main.c and complesso.c.
Woah that's nice, that's what I was trying to understand. Very good.
By the way I didn't understand why shouldn't I use .c in include, and how to go for .h (what should I do and change). And i should use #define LENGTH 1023 in all my function? Or i can "import" or "inherit" from another function?