I am studying structures in C from K&R book and encountered this:
struct{
int len;
char *str
} *p;
I am confused by this, because where the name of the struct variable should be, they have given a pointer *p. Can anyone please help me here? What does this declaration mean?
This declaration is a pointer to a struct which is composed of 2 fields — an int and a char*. This struct doesn't have a name and if you want to declare another pointer of the same struct, you will have to write it again.
Notice you can write something like this:
struct MyStruct {
int data1;
char data2;
};
This will define a new struct type which you can use later like this to declare a variable: struct MyStruct myVar;. The difference from what you wrote is that this struct doesn't declare a new variable but a new type since the struct in my example has a name and yours does not.
Another option is to use a typedef and give this struct a name and then you can use the name you have given it to declare more variables of that type.
You can read more about it at http://en.wikipedia.org/wiki/Typedef in the "Simplifying a declaration" section.
Related
We all know how to declare a structure in C:
struct Label1{ /* variables */ } Label2; // As I learned
But I want to know why this code works without declaring 'struct name':
typedef struct name s_name;
Or is in fact, does typing the code
struct name;
mean that I declared 'struct name' as a void structure or something like this?
Example of code:
typedef struct Data Data;
struct Data{ /*variables*/ };
If in the first line struct Data is declared as a void one, then in the second it's like I'm redeclaring it with members.
What is the explanation for this point?
Something like:
struct MyStruct;
Is called a forward reference. It creates an incomplete type and tells the compiler there will be a type of that name (and it's a struct - it works likewise for unions), and the details "follow later". Of such a type you cannot define variables, until you complete the type.
typedef struct MyStruct MyType;
Will just define the type name to be that struct. This is still an incomplete type.
However, you can take a pointer to an incomplete type:
MyType *my_t_pointer;
struct MyStruct *my_s_pointer;
This is useful for a struct to have pointers to objects of the same type when you provide the full declaration, "completing" the type:
struct MyStruct {
struct MyStruct *next;
};
Actually this is the only way to create nodes for lists, trees, and all other recursive data-structures. This is a major part of C programs (sometimes hidden).
Also, this mechanism is used to hide implementation details. Functions in the header need only know the struct exists to take/pass pointers to it. The use of these functions need not to know the details of the struct (but this way it cannot allocate it, so the module has to cover all aspects which need to know details on the struct). The full declaration is only inside the implementation file of the module.
These pointers are called "opaque" as one cannot "look through", i.e. access the fields of the struct as they are simply not known to it.
my_module.h:
struct MyStruct;
extern void my_init(struct MyStruct *obj);
my_module.c:
struct MyStruct {
int f1;
...
};
my_init(struct MyStruct *obj)
{
...
}
The typedef declares s_name as an alias for struct name so that you can declare variables, e.g.:
s_name *sptr;
The line
struct name;
declares that there is a struct type called name without defining its content. This is usually done in order to be able to declare variables as pointers to the struct type. You cannot declare variables of the actual struct type until it has been defined.
I've recently started to study about structs and pointers but there is something I didn't fully understand about the design of a struct. I understand the declaration of the struct i.e typedef struct Alias and its content but I don't understand Get_noAllyp and *no_getOf at the end of the statement. What are they? I couldn't really find a good source either.
typedef struct Alias {
char *s_a_name;
char **s_aliases;
short *s_dumr;
int s_get_sum;
}Get_noAllyp, *no_getOf; /*Here, I don't understand this one.
Where did these two variables come from?
And one of them is a pointer.*/
It defines multiple typedefs, i.e multilple "names" for the same thing, while the second is a pointer to it.
The first one Get_noAllyp is the name given for the struct, while no_getOf represents a pointer to it.
I.e, writing no_getOf is completely the same as writing Get_noAllyp * in function signatures or variable declarations.
Here, there are two typedefs being crated in a short-hand manner. The above typedef can be broken down like
typedef struct Alias {
char *s_a_name;
char **s_aliases;
short *s_dumr;
int s_get_sum;
}Get_noAllyp;
typedef struct Alias * no_getOf;
So,
Get_noAllyp represents struct Alias
no_getOf represents struct Alias *
The code:
struct Alias {
char *s_a_name;
char **s_aliases;
short *s_dumr;
int s_get_sum;
}
defines a new data type that has the name Alias and is a struct. The original design of the C language is a bit clumsy here as it requires the struct type names to be always prefixed with the struct keyword when they are used.
This means the code:
struct Alias {
char *s_a_name;
char **s_aliases;
short *s_dumr;
int s_get_sum;
} Get_noAllyp, *no_getOf;
declares the variable Get_noAllyp of type struct Alias and the variable no_getOf of type pointer to struct Alias.
By placing the typedef keyword in front, the identifiers Get_noAllyp and no_getOf become types (and not variables).
Get_noAllyp is the same as struct Alias and no_getOf is the same as struct Alias * (i.e. a pointer to a struct Alias`).
Now you can write:
struct Alias x;
struct Alias *y;
or
Get_noAllyp x;
no_getOf y;
to declare x as a variable of type struct Alias and y as a variable of type pointer to a struct Alias.
I try to do this in C :
typedef struct s_match_fptr
{
char *str;
int (*funcptr)(t_client *client, char **command);
} t_match_fptr;
typedef struct s_client
{
int socket_fd;
int port;
char *server_ip;
struct sockaddr_in s_in;
t_match_fptr *db;
} t_client;
The point is I try to declare a function pointer that takes in parameter a t_client struct in my t_match_ptr struct.
Also, my struct t_client have an array of t_match_ptr.
For simplify, A need to be declared after B AND B needs to be declared after A.
So, is there a way to "predeclare" t_client before the declaration of t_match_ptr?
Thank you and sorry for bad english.
Forward declaration.
Add at the beginning: typedef struct s_client t_client;
Now the compiler will know the type t_client when encountered in s_match_fptr.
Note, the type must be used only by reference in the s_match_fptr definition (i.e. using a pointer). This way the compiler doesn't need to know the actual contents of the type when parsing the code.
I have a typedef for a struct in sampleHeader.h that is similar to:
typedef struct example Example;
and I have in my sampleSource.c:
struct example{
char a[4];
char b[4];
char c[5];
}
Now for some reason when I return a pointer back to my main function which references a struct that has been created ( and malloc'd) and try to print out the values of each member I get an error along the lines of "cannot derefence incomplete type"
Any ideas?
In the header file you have only forward declared the struct. That's fine and you'll be able to declare pointers and references to the struct in the header (and any other header or cpp file that includes this header too).
As the compiler has only seen the definition in the cpp module, this is the only place that you'll be able to declare variables of type struct example by value or to dereference pointers to access members. Outside of the cpp file the compiler doesn't know how big the struct is or what is members are.
If you need to use the struct in multiple modules declare and define the struct together in the header.
Hard to say for sure without seeing the actual code, but....
struct example{
char a[4];
char b[4];
char c[5];
};
^ note the new semi colon.
As usual, Wikipedia's article on structs is less than clear. It gives the syntax for structs as this:
[typedef] struct [struct_name]
{
type attribute;
type attribute2;
/* ... */
[struct struct_name *struct_instance;]
} [struct_name_t] [struct_instance];
What would the typedef keyword do here?
What does the [struct_name] mean? (Is it the name you're giving to the new struct data type?)
What does the [struct_name_t] mean?
what does the [struct_instance] mean? (Is it creating a single instance of the struct?)
I presume [struct struct_name *struct_instance;] creates a pointer in the struct which would point to a second instance of the struct). Correct?
I would greatly appreciate an example: Say I have three files: main.c, sub.c and sub.h. I want to declare an instance of a struct in sub.h, and instantiate and use it it in sub.c. Say I want a Song type struct, with members char name[20] and char artist[10], and say I want to make an instance, mySong, {"Me singing", "Me"}, how would this look in sub.c and sub.h?
Thanks
•What would the typedef keyword do here?
It would allow you to create a typedef of your structre, just like any other type. This allow you to not have to type struct xxx struct_name everytime. You don't need this, hence the []
•What does the [struct_name] mean? (Is it the name you're giving to the new struct data type?)
Yes, if you chose too. You can also make a nameless struct so you don't need to give it a name.
•What does the [struct_name_t] mean?
That's the typedef'd name, if you chose to typedef the struct
•what does the [struct_instance] mean? (Is it creating a single instance of the struct?)
Yes, it's for creating one or more instance(s) of the sturct
•I presume [struct struct_name *struct_instance;] creates a pointer in the struct which would point to a second instance of the struct). Correct?
Right, this would be usefull for a "next" type pointer in a linked list.
struct example:
typedef struct foo{
int count;
struct foo *next;
} foo_t myfoo;
is an example of that filled in; this allows you to declare a new struct via:
foo_t new_foo_struct;
because of the typedef and typedef'd name. If you omit those like this:
struct foo{
int count;
struct foo *next;
} myfoo;
Now you'd have to use the struct key word for every instance, such as:
struct foo new_foo_struct;
to break it up over more than 1 file:
/*sub.h*/
typedef struct{
char name[20];
char artist[10];
}song;
Then in the source:
/*sub.c*/
#include "sub.h"
/*this needs to go into a function or something...*/
song mysong;
strcpy(mysong.name, "Mesinging");
strcpy(mysong.artist, "Me");
That article is just wrongly mixing different concepts, rectified this now. A struct is declared through
struct tagname {
... fields ...
};
that's just it, only that the tagname part is optional in some contexts.
In addition you may
declare an alias for the struct type through typedef
or a variable of the struct type
"in one go", but I don't think that it is good style and should be separated.
sub.h
------
typedef struct{
char name[20];
char artist[10];
}song;
sub.c
----
song mysong={"Me Singing","Me"};
typedef struct struct_name
{
char name[20];
char artist[10];
}struct_name_t structInstance;
typedef - this means that you are creating a new type (struct_name_t)
So, in C code you can create an instance like this:
struct_name_t myVariable;
or you can explicitly write:
struct struct_name myVariable;
The structInstance at the end means that you want to create an instance of your struct at the same moment you defined it (and the name of that variable is structInstance). It's not something you will use all the time, but it is useful in some situations.
If you want to create an instance of your struct and assign/initialize members at the creation time, you can do it like this:
struct_name_t myVariable = { "Foo", "bar" };
The 'name' member will contain "Foo" and the artist member will contain "bar".
Note:
If you write this:
struct_name_t myVariable = { 0 };
That will fill your entire struct with zeroes!