Novice: Pointing to arrays in array of structures
Author Message
Novice: Pointing to arrays in array of structures

Hi,

I get what I want, but have not seen it done anywhere else (properly
because there are better ways to do it). Is this illigal/stupid to do
the following fx:

struct particle{
float x[3];
double f;

Quote:
};

typedef struct particle PA;

void init(PA *ptr, int N, int M){
int n,m;

srand(129);
for (n=0; n<N; n++){
for (m=0; m<M; m++)
(*(ptr+n)).x[m]=rand()/(RAND_MAX+1.0);
}

Quote:
}

int main(void){
PA sys[2];
init(&sys[0],2,3);

return 0;

Quote:
}

--

Sun, 25 May 2003 03:00:00 GMT
Novice: Pointing to arrays in array of structures

Quote:
>Hi,

>I get what I want, but have not seen it done anywhere else (properly
>because there are better ways to do it). Is this illigal/stupid to do
>the following fx:

Is what stupid?  I don't see anything obviously wrong.  Maybe some
clumsy syntax, but nothing wrong...

Some suggestions follow...

Quote:

What is "headers"?  This may be non-standard...

Quote:

>struct particle{
>  float x[3];
>  double f;
>};

It's a Good Idea to remove magic numbers wherever possible.  Something
like

#define NUM_AXES 3

struct particle{
float x[NUM_AXES];
double f;

Quote:
};

>typedef struct particle PA;

>void init(PA *ptr, int N, int M){

Since we know M is fixed at 3, we can (and should) eliminate that
parameter, and use the constant defined above

void init(PA *ptr, int N){

Quote:
>  int n,m;

>  srand(129);
>  for (n=0; n<N; n++){
>    for (m=0; m<M; m++)

for (m=0; m<NUM_AXES; m++)

Quote:
>      (*(ptr+n)).x[m]=rand()/(RAND_MAX+1.0);

The field access here is kinda clumsy.  Here you have a couple better
alternatives.

(ptr+n)->x[m]
ptr[n].x[m]

And, of course, several worse ones...

*((*(ptr+n)).x+m)

etc...

Quote:
>  }

>}

>int main(void){
>  PA sys[2];

More magic number removal.

#define ELTS 2
...
PA sys[ELTS];

Quote:
>  init(&sys[0],2,3);

init(sys, ELTS);

(Remember I changed the parameters of the function)

Or you could get fancy:

#define mNum_Elts(a)  (sizeof(a)/sizeof(*a))
...
init(sys, mNum_Elts(sys));

Quote:

>  return 0;
>}

Regards,

I Don't Do Windoze
--

Mon, 26 May 2003 14:56:35 GMT
Novice: Pointing to arrays in array of structures
Hello

This way of achieving is worth getting the desired results. But, some
improvements can be made.It's not stupid to do this way, though

Quote:

> struct particle{
>   float x[3];
>   double f;
> };

> typedef struct particle PA;

> void init(PA *ptr, int N, int M){
>   int n,m;

>   srand(129);
>   for (n=0; n<N; n++){
>     for (m=0; m<M; m++)
>       (*(ptr+n)).x[m]=rand()/(RAND_MAX+1.0);/*this statement

can be improved as
ptr[n].x[m] = rand()/(RAND_MAX+1.0);
Quote:
>   }

> }

> int main(void){
>   PA sys[2];
>   init(&sys[0],2,3);/*this statement can be improved as*/

init(sys,2,3);/*there is no meaning in sending address of first
element explicitly as the array name is the

Quote:
>   return 0;
> }
> --

And, u can combine typedef and structure declaration with the following.

Quote:
> typedef struct{
>   float x[3];
>   double f;
> }PA;

which is a minor improvement :)

with regards
--

Sun, 08 Jun 2003 06:51:57 GMT
Novice: Pointing to arrays in array of structures

Quote:

>... But, some improvements can be made ...
>>       (*(ptr+n)).x[m]=rand()/(RAND_MAX+1.0);/*this statement
>                                              can be improved as
>          ptr[n].x[m] = rand()/(RAND_MAX+1.0);

This one is, I agree, an improvement: the subscript version is
much easier to read, as well as being shorter.

Quote:
>>   init(&sys[0],2,3);/*this statement can be improved as*/
>    init(sys,2,3);/*there is no meaning in sending address of first
>                  element explicitly as the array name is the

The array name *becomes* a pointer to its initial element.  This
is not the same as "is" a pointer to its initial element.  Just as
a chicken is a bird, but a chicken's egg is not (yet) a bird, an
array is not a pointer -- not right away, anyway.  If you prevent
the array from "hatching", as it were, you can see quite clearly
that the egg (array) is not a bird (pointer):

printf("sizeof arr = %lu\n", (unsigned long)sizeof arr);
printf("sizeof ptr = %lu\n", (unsigned long)sizeof ptr);

and:

arr++;
ptr++;

are two situations in which the array has not "hatched".

In this case, I think that "&sys[0]" vs "sys" is at best a toss-up
-- even though the latter is shorter, and not at all hard to read,
I sometimes prefer the former.

Finally:

Quote:
>> struct particle{
>>   float x[3];
>>   double f;
>> };
>> typedef struct particle PA;
>And, u can combine typedef and structure declaration with the following.
> typedef struct {
>   float x[3];
>   double f;
>} PA;

>which is a minor improvement :)

I think *this* one is a definite (if minor) degradation.  In
particular, combining "typedef" -- which makes an alias for an
existing type -- with the construct that actually defines a type
(i.e., "struct") misleads people into thinking that "typedef"
defines a type.

The ANSI C standard quite clearly states that typedef *never*
defines a new type:

6.5.7  Type definitions
...
A typedef declaration does not introduce a new type, only a
synonym for the type so specified. ...

The name "typedef" is obviously highly misleading to begin with,
and the fact that "struct {" creates a new type, that the typedef
can then alias, finishes the illusion.  Unfortunately, people then
think that typedef creates new types, and are confounded when it
fails to do so.

I therefore recommend that the "combo thing" that "u" suggest above
*never* be used.  Instead, if you want to have a typedef for a
structure type, I recommend putting it *before* the structure
definition.  For instance:

typedef struct zog ZOG;
struct zog {
ZOG *next;      /* now you can use the typedef here! */
ZOG *prev;      /* (doubly linked list) */
char *key;
int value;
};

I prefer not to use the typedef at all (I am not afraid of typing
the letters 's' 't' 'r' 'u' 'c' 't' repeatedly :-) ), but sensible
people can disagree here. :-)
--