I found this structure in the slides of my professor:
struct point{
int x;
int y;
} p;
What does p mean? So far I used only the classical struct like this:
struct point{
int x;
int y;
};
struct point{
int x;
int y;
} p;
defines a variable p of type struct point
it is same as
struct point{
int x;
int y;
};
struct point p;
struct point{
int a;
int b;
}p;
This is the same as using struct point p
When we use typedef struct p as in
typedef struct point{
int a;
int b;
}p;
We can use p to declare a structure pointer or structure variable later on
To create a structure pointer p *abc
To create a structure variable p xyz
Related
Having the following C code:
struct Point2_s;
struct Point1_s{
int x;
int y;
Point2_s P2;
} Point1;
struct Point2_s{
int x;
int y;
} ;
int main() {
...
return 0;
}
I'm getting an error:
unknown type name ‘Point2_s’
Can anyone can please explain me WHY it doesn't work? Why doesn't the struct Point2_s declaration is insufficient when defining the Point1_s member P2?
In this line
struct Point2_s;
there is declared an incomplete structure specifier struct Point2_s.
In this declaration
struct Point1_s{
int x;
int y;
Point2_s P2;
} Point1;
there is used an unknown name Point2_s. It is not the same as struct Point2_s.
But even if you will write
struct Point1_s{
int x;
int y;
struct Point2_s P2;
} Point1;
nevertheless you may not use an incomplete type in a data member declaration.
From the C Standard (6.7.2.1 Structure and union specifiers)
3 A structure or union shall not contain a member with incomplete or
function type (hence, a structure shall not contain an instance of
itself, but may contain a pointer to an instance of itself), except
that the last member of a structure with more than one named member
may have incomplete array type; such a structure (and any union
containing, possibly recursively, a member that is such a structure)
shall not be a member of a structure or an element of an array.
Instead you need to write
struct Point2_s{
int x;
int y;
} ;
struct Point1_s{
int x;
int y;
struct Point2_s P2;
} Point1;
Or you could write
typedef struct Point2_s{
int x;
int y;
} Point2_s;
struct Point1_s{
int x;
int y;
Point2_s P2;
} Point1;
In this case the name Point2_s is an alias for the type specifier struct Point2_s.
On the other hand, as it is pointed out in other answers you may use pointers to incomplete types because pointers themselves are always complete types. That is you may write
struct Point2_s;
struct Point1_s{
int x;
int y;
struct Point2_s *P2;
} Point1;
A forward declaration can only be used to declare pointers to the forward-declared struct. It doesn't know how big it is though, so it can't use the type directly (how does it know how much space to reserve for the P2 member?).
Just reverse the order of declaration:
struct Point2_s{
int x;
int y;
};
struct Point1_s{
int x;
int y;
struct Point2_s P2; // You didn't typedef, so by the C standard, you need struct to declare the member
} Point1;
or you'll need to use pointers:
struct Point2_s;
struct Point1_s{
int x;
int y;
struct Point2_s *P2; // Pointer, again adding struct; P2 will need to be allocated separately, e.g. by malloc
} Point1;
struct Point2_s{
int x;
int y;
};
Forward declaration will not work in this case (abstracting from missing struct) as compiler needs to know the size of the member P2. You need to declare it before the the declaration which uses it.
struct Point2_s{
int x;
int y;
} ;
struct Point1_s{
int x;
int y;
struct Point2_s P2;
} Point1;
Forward declaration will only work only for pointers:
struct Point2_s;
struct Point1_s{
int x;
int y;
struct Point2_s *P2;
} Point1;
struct Point2_s{
int x;
int y;
} ;
Option 1:
typedef struct s{
int x;
double y;
char z;
}mystruct;
Option 2:
typedef struct {
int x;
double y;
char z;
}mystruct;
What's the difference between these 2 options?
With option 1 you can declare a variable like this:
struct s foo;
or
mystruct foo;
With option 2 the only possibility is:
mystruct foo;
I am still new in C. I know you can just use the already-declared struct as new data type such as int, double, etc. However, I encounter a struct written like this:
struct AdjListNode
{
int dest;
int weight;
struct AdjListNode* next;
};
In this struct, the data type of "next" pointer is struct AdjListNode*. What does struct have to do with the already-declared AdjListNode*? Thanks!
What does struct have to do with the already-declared AdjListNode*?
The answer is that the c syntax requires it.
You do not get a type AdjListNode by writing struct AdjListNode { ... };
AdjListNode is a struct tag and you always have to use struct AdjListNode when declaring variables.
See this simple example (without pointer inside the struct):
#include <stdio.h>
struct sSomeName
{
int x;
};
int main(void) {
struct sSomeName var; // OK, variable of type struct sSomeName
struct sSomeName* pVar; // OK, pointer to variable of type struct sSomeName
// sSomeName var2; // ERROR: unknown type name 'sSomeName'
var.x = 5;
pVar = &var;
printf("%d\n", pVar->x);
return 0;
}
So if you want to add a pointer inside the struct, you must write struct sSomeName just as you have to do inside main, i.e. like:
struct sSomeName
{
int x;
struct sSomeName* p;
};
Using typedef
If you want a type named AdjListNode you must use typedef.
A typedef example could look like:
#include <stdio.h>
typedef struct sSomeName sSomeName;
struct sSomeName
{
int x;
sSomeName* p;
};
int main(void) {
sSomeName var;
sSomeName* pVar;
var.x = 5;
var.p = NULL;
pVar = &var;
printf("%d\n", pVar->x);
printf("%p\n", (void*)pVar->p);
return 0;
}
Here with that declaration pointer to structure is declared. This is basically used for implementing linked list or for other data structures like tree.
It does'nt mean that struct is re-declared. It is similar to declare a struct variable.
The structure is created as follows: typedef struct AdjListNode. Example:
#include <stdio.h>
#include <stdlib.h>
typedef struct AdjListNode
{
int dest;
int weight;
struct AdjListNode* next;
}AdjListNode;
typedef struct Nodo{
char *nombre;
int *edad;
struct Nodo *siguiente;
}Nodo;
int main(int argc, char **argv) {
AdjListNode *nodo=malloc(sizeof(AdjListNode));
nodo->dest=1;
nodo->weight=2;
nodo->next=NULL;
printf("Nodo-->dest: %d", nodo->dest);
free(nodo);
}
Is it possible to form a two way link between structs? I tried to achieve it like this:
typedef struct
{
int foo;
b *b;
} a;
typedef struct
{
int bar;
a *a;
} b;
But the struct a does not know what b is because it's declared afterwards.
Try this,
typedef struct a a;
typedef struct b b;
struct a
{
int foo;
b *b;
} ;
struct b
{
int bar;
a *a;
} ;
When you need to reference other structs that may have not been defined up until then, make your declaration like this and it should work:
typedef struct
{
int foo;
struct b *b;
} a;
typedef struct
{
int bar;
struct a *a;
} b;
I need to reference a struct that's not yet defined because the struct actually conatins the typedef'd function prototype.
For example,
typedef int (MyCallbackFunction)(X * x, void * ctx);
typedef struct CallbackData {
MyCallbackFunction * callback;
void * ctx;
} CallbackData;
typedef struct X {
char a;
int b;
int c;
double d;
CallbackData e;
} X;
What's the valid way to actually write this code/header ?
Just forward declare the relevant types - and you can make the function pointer part of the typedef:
struct X_;
typedef int (*MyCallbackFunction)(struct X_ * x, void * ctx);
typedef struct CallbackData_ {
MyCallbackFunction callback;
void * ctx;
} CallbackData;
typedef struct X_ {
char a;
int b;
int c;
double d;
CallbackData e;
} X;
Just forward declare your typedefs
typedef struct X X;
typedef struct CallbackData CallbackData;
and then declare the structs later.
Yes, you can forward declare the struct and use it in the declaration of MyCallbackFunction where you don't need it to be a complete type.
struct X;
typedef int (MyCallbackFunction)(struct X * x, void * ctx);