You will never be able to declare an array in program.c without having a structure definition in scope. The header file does not provide sufficient information to make the compiler know the size of Transform, so you can't declare an array of it in program.c.
The allocations for pointer to pointer to Transform work because the compiler doesn't need to know the size of Transform, since the pointed-to object is a pointer itself.
Move the structure definition into the header file. In other words, header.h should be:
header.h
struct _Transform{
char c;
//the actual operation which is an union
Operation o;
};
typedef struct _Transform Transform;
And now, in program.c, you can declare a statically allocated array like so:
Transform transform[MAX_NO_OF_TRANSFORMS];
There is no need to use dynamically allocated memory in your code; it is overkill and utterly unnecessary, given the discussion we had in the comments section.
UPDATE
Since you seem to be new to this sort of stuff, I will give you another hint: always use include guards in your header files to avoid weird errors from the compiler due to multiple inclusion. For example, if you include header1.h and header2.h in program.c, and header2.h already includes header1.h, you will get multiple definition errors when compiling program.c (it's as if you included the same file twice). An include guard protects against this. A typical usage goes like this:
header.h
#ifndef TRANSFORM__STRUCT__HEADER
#define TRANSFORM__STRUCT__HEADER
struct _Transform{
char c;
//the actual operation which is an union
Operation o;
};
typedef struct _Transform Transform;
#endif
This is a widely used technique. Basically, it works by defining a preprocessor symbol the first time the file is included - if it is included again, #ifndef will evaluate to false, and nothing will be included.
struct _Transformis as simple asstruct Transform array[ARRAY_LENGTH], but from your code it looks like you want something else.struct _Transformis in scope, you can declare an array of it. You can include the header and then declare the array asTransform transform[MAX_NO_OF_TRANSFORMS]in the source file. It is overkill to use dynamic memory in this case, especially since you seem to have an upper bound for the array size known at compile time.struct _Transform tr[MAX_NO_OF_TRANSFORMS];I get an error in return:array type has incomplete element type|