I have a very simple question: I want to use structs inside another structs but I want to be able to define them in any order I want.
Something like this:
// User type definition
typedef struct type1{
int i;
type2 t;
};
// User type definition
typedef struct type2{
int i;
type3 t;
};
// User type definition
typedef struct type3{
int i;
};
How can I do this?
The only way this can be accomplished is by using pointers to the structs instead of static members:
typedef struct type1 {
int i;
struct type2 *t;
} type1;
// User type definition
typedef struct type2 {
int i;
struct type3 *t;
} type2;
// User type definition
typedef struct type3 {
int i;
} type3;
The reason for this is the compiler MUST know how large the struct is as it gets to it. If you use pointers, all the compiler needs to know is that that struct type simply exists, since pointer types on a given architecture are a known size at compile time
Related
The graph adjacency list code in my book is given by:
typedef struct vertexNode //vertexNode in an AdjacencyList
{
VertexType data;
EdgeNodeType *firstEdgeNode;
} VertexNode, AdjList[MAXVEX];
AdjList adjList; # adjList is a MAXVEX-size array
I was confused by the last line in the typedef: typedef struct{...} AdjList[MAXVEX].
The forms I can understand are:
typedef struct{
...
} VertexNode,
VertexNode AdjList[MAXVEX]; # AdjList is a MAXVEX-size array
or
struct{
...
} AdjList[MAXVEX]; # AdjList is a MAXVEX-size array
Grammatically speaking, typedef is actually a storage class, like static or extern, and type alias declarations are read like variable declarations. E.g.
int x;
declares x to be a variable of type int, while
typedef int x;
declares x to be a type alias meaning int.
Similarly,
struct vertexNode {
...
} VertexNode;
would declare VertexNode to be a struct vertexNode variable, but adding typedef makes it an alias for struct vertexNode. Note that struct vertexNode { ... } (the whole thing) is a type, just like int. It first defines struct vertexNode, and then refers to it.
Additionally, array declarations may appear to behave strangely when you use commas:
int x, y[5];
declares x to be an int, while declaring y to be an array of 5 ints. (Functions and pointers are also like this.) There are other questions on this site about it.
Putting everything together, your question looks like this if you take away the typedef:
struct vertexNode
{
VertexType data;
EdgeNodeType *firstEdgeNode;
} VertexNode, AdjList[MAXVEX];
This would declare the type struct vertexNode, the variable VertexNode of type struct vertexNode, and the array AdjList of MAXVEX struct vertexNodes. Adding the typedef means that VertexNode becomes an alias for struct vertexNode and that AdjList becomes an alias for an array of MAXVEX struct vertexNodes. Personally, I wouldn't recommend writing it like this, but I guess it's concise.
This is a sample code.
#include <stdio.h>
typedef char STR[1024];
int main() {
STR a = "1234"; // == char a[1024]
printf( "%s\n", a );
return 0;
}
I wrote a example with data type char.
You can replace it with any class or struct..
so.. Your code..
AdjList a is same with VertexNode a[MAXVEX]
Is there any difference between those two:
typedef struct ddwq{
int b;
}ta;
typedef struct {
int b;
}ta;
In the former case, you can reference the type of the struct as either struct ddwq or ta. In the latter case, you can only reference it as ta since the struct has no tag.
The first case is required if the struct will contain a pointer to itself such as:
typedef struct ddwq{
int b;
struct ddwq *p;
}ta;
The type name ta isn't visible inside of the struct, so the struct must have a tag name for it to reference itself.
I have a struct declaration in C that looks something like this:
static struct {
int a;
int b;
} myStruct[10];
I want to declare a struct member variable inside myStruct, so I try to add this:
static struct {
int c;
int d;
struct myStruct[10] s;
} myNestedStruct[100];
I'm getting a bunch of errors i.e. syntax error before or at: [ and
syntax requires ";" after last struct/union member. What would the better way to implement the nested structs be?
EDIT: My code now looks like this:
static struct {
int a;
int b;
} myStruct[10];
static struct {
int c;
int d;
struct myStruct s[10];
} myNestedStruct[100];
However I'm getting an error: incomplete struct/union/enum myStruct: s
You need to declare myStruct first before using it as a struct type.
struct myStruct {
int a;
int b;
};
static struct {
int c;
int d;
struct myStruct s[10];
} myNestedStruct[100];
This creates a variable called myNestedStruct which is an array of 100 structs, each containing two ints and an array of 10 mystructs.
When you write code like
struct { ... } Foo;, it's not declaring a type named Foo but a variable. Its type is an anonymous struct corresponding to what you put in the curly braces. If you want to declare a type, write struct Foo { ... };.
That's where your error is coming from -- myStruct is not a type name, so when you write struct myStruct in the definition of myNestedStruct the compiler thinks you're about to define a struct by that name. But then it encounters an [ which shouldn't be the next token in a struct declaration ever so it tells you can't make sense of the code.
int main()
{
int a;
typedef struct
{
int i;
int j;
}type1;
typedef type1 type[10]; //Please explain this line ?
typedef struct
{
int l;
type c;
}type2;
type2 x;
x.c[0].i=1; //How can we write this??
x.c[0].j=2;
x.c[2].j=3;
printf("%d",x.c[2].j);
return 0;
}
Program is compiling successfully which I'm expectecting not to because of
typedef type1 type[10];
Please explain the behavior of typeded here.All I know is that we can define an alias with the help of typedef.
output:3
The way to read typedef is as a regular variable declaration, with the variable's type being the type that is being given an alias, and the variable name being the name of the new alias.
So, in
typedef type1 type[10];
if we drop the typedef we get:
type1 type[10];
This clearly defines type to be an array of 10 type1. So, the typedef is then introducing the name type for the type "array of 10 type1".
What is the best way to resolve the following circular dependency in typedef-ing these structs?
Note the C language tag - I'm looking for a solution in standard gcc C.
typedef struct {
char* name;
int age;
int lefthanded;
People* friends;
} Person;
typedef struct {
int count;
int max;
Person* data;
} People;
The answer lies in the difference between declaration and definition. You are attempting to declare and define in the same step (in the case of a new type via typedef). You need to break these up into different steps so the compiler knows what you are talking about in advance.
typedef struct Person Person;
typedef struct People People;
struct Person {
char* name;
int age;
int lefthanded;
People* friends;
};
struct People {
int count;
int max;
Person* data;
};
Note the addition of the two 'empty' typedefs at the top (declarations). This tells the compiler that the new type Person is of type 'struct Person' so that when it sees that inside the definition of struct People it knows what it means.
In your particular case, you could actually get away with only predeclaring the People typdef because that is the only type used before it is defined. By the time you get into the definition of struct People, you have already fully defined the type Person. So the following would also work but is NOT RECOMMENDED because it is fragile:
typedef struct People People;
typedef struct {
char* name;
int age;
int lefthanded;
People* friends;
} Person;
struct People {
int count;
int max;
Person* data;
};
If you swap the order of the structure definitions (moving struct People above the typedef of Person) it will fail again. That's what makes this fragile and, therefore, not recommended.
Note that this trick does NOT work if you include a struct of the specified type rather than a pointer to it. So, for example, the following WILL NOT compile:
typedef struct Bar Bar;
struct Foo
{
Bar bar;
};
struct Bar
{
int i;
};
The above code gives a compiler error because the type Bar is incomplete when it tries to use it inside the definition of struct Foo. In other words, it doesn't know how much space to allocate to structure member 'bar' because it hasn't seen the definition of struct bar at that point.
This code will compile:
typedef struct Foo Foo;
typedef struct Bar Bar;
typedef struct FooBar FooBar;
struct Foo
{
Bar *bar;
};
struct Bar
{
Foo *foo;
};
struct FooBar
{
Foo foo;
Bar bar;
FooBar *foobar;
};
This works, even with the circular pointers inside Foo and Bar, because the types 'Foo' and 'Bar' have been pre-declared (but not yet defined) so the compiler can build a pointer to them.
By the time we get to defining FooBar, we have defined how big both Foo and Bar are so we can include the actual objects there. We can also include a self-referential pointer to type FooBar because we have pre-declared the type.
Note that if you moved the definition of struct FooBar above the definitions of either struct Foo or Bar, it would not compile for the same reason as the previous example (incomplete type).
Forward-declare one of the structs:
struct people;
typedef struct {
/* same as before */
struct people* friends;
} Person;
typedef struct people {
/* same as before */
} People;
As for readability :
typedef struct Foo_ Foo;
typedef struct Bar_ Bar;
struct Foo_ {
Bar *bar;
};
struct Bar_ {
Foo *foo;
};
It might be a good idea to avoid typedef struct altogether;
Since Person just wants a pointer to People, it should be fine to just predeclare the latter:
typedef struct People People;
Then change the second declaration to just declare using the struct tag, like so:
struct People {
int count;
int max;
Person data[];
};
struct _People;
typedef struct {
char* name;
int age;
int lefthanded;
struct _People* friends;
} Person;
struct _People {
int count;
int max;
Person data[1];
};
Note: Is Person data[]; standard?
struct People_struct;
typedef struct {
char* name;
int age;
int lefthanded;
struct People_struct* friends;
} Person;
typedef struct People_struct {
int count;
int max;
Person data[];
} People;