Declare an array of structures - c

I am trying to create an array of structures but it appears this bug:
"Error, array type as incomplete element type"
typedef struct {
char data[MAX_WORD_SIZE];
int total_count;
Occurrence_t reference[MAX_FILES];
int nfiles;
} Word_t;
struct Word_t array[a];

TL;DR
Either change you struct definition
struct Word_t {
char data[MAX_WORD_SIZE];
int total_count;
Occurrence_t reference[MAX_FILES];
int nfiles;
};
Or (and not both), the array declaration:
Word_t array[a];
What you did is define an un-named structure, to which you gave an alternative name with a typedef. There is no struct Word_t, only a Word_t type defined.
The tag namespace (where the names that you use after struct/union/enum reside) is separate from the global namespace (where file scope typedefed names reside).
Many programmers feel that lugging around a struct tag type name is cumbersome, and you should always do a typedef for the struct name. Others feel this is an abuse of typedef-ing, and that the keyword conveys a lot of meaning; to them the typedef is syntactic sugar without any real abstraction.
Whichever way you choose to write you code, stick to it, and don't confuse the two namespaces.

You are using typedef in the first place hence you are not supposed to write the struct anymore . look here
typedef struct {
char data[MAX_WORD_SIZE];
int total_count;
Occurrence_t reference[MAX_FILES];
int nfiles;
} Word_t;
Word_t array[a];
It will work

Related

What is purpose for different ways of naming of typedef statement?

I've the question about typedef statement.
Here is the code how i always write this statement:
typedef struct name
{
}name_t;
And here is the another example how i can write that:
typedef struct
{
}name;
Question is: what is purpose of that ways?
You need to use the first format if you have to refer to the type before the typedef is completed. This is necessary if the structure contains a pointer to the same type. This comes up when defining linked lists.
typedef struct name
{
int value;
struct name *next;
}name_t
You can't use name_t *next; inside the structure declaraction, because name_t isn't defined until later.
typedef struct name
{
}name_t;
name here is a struct tag and superfluous for the normal use-case, since you end up with a typedef anyhow and should only use name_t in your code from there on.
The only reason you'd add a tag there is the special case where you need a self-referencing struct such as a struct name* next; member in a linked list or such. In such cases we have to use the struct tag since the typedef name cannot be used before the typedef statement itself is done. Another alternative to that is to forward declare the struct.
The _t naming is industry standard way of naming types since the dawn of time. Unfortunately, the POSIX standard had the misguided idea to disallow such naming, so if you care about POSIX compliance, you should not name your types with _t in the end. If you don't care about POSIX, you should use _t because it gives proper, self-documenting code.
typedef struct name
{
int a;
double b;
char c;
}name_t;
name is a structure tag while name_t is a new type created by typedef.
To provide a structure tag explicitly is useful, if:
You want to implement a forward-declaration of the structure for use it in f.e. function definitions or other structures before the structure definition occurs (important if you have several translation units/C files).
For example:
File1.c
struct name; // forward declaration of structure `name`.
void foo(struct name *ptr)
{
....
}
struct bar
{
int x;
struct name y;
}
File2.c
typedef struct name
{
int a;
double b;
char c;
}name_t;
You want to define a pointer to an object of the structure itself inside of the structure, like required by linked lists:
typedef struct name
{
int a;
double b;
char c;
struct name *next;
}name_t;

How to make cross pointers in structs

So here's my problem, I want to create a graph-database. My concept idea is a node (which will be of type "Vrtc" in the code. It will cointain an (int) id, a (char*) string (called "str") and a list (l_est) of paths in and out.
The list will contain an "array" of pointers to nodes, the amount of nodes in the list, and the maximum number of nodes.
typedef struct Vrtc
{
int id;
char *str;
l_est *pathsIn;
l_est *pathsOut;
} Vrtc;
typedef struct l_est{
Vrtc **Vert;
int qtdElem;
int maxElem;
} l_est;
As you may know, there'll be a problem of "Unknow type/Type undeclared inside the node. I was hoping anyone could give a tip of how to do it, if it is possible.
You have to use a forward declaration:
typedef struct l_est l_est;
typedef struct {
int id;
char *str;
l_est *pathsIn, *pathsOut;
} Vrtc;
typedef struct l_est {
Vrtc **Vert;
int qtdElem, maxElem;
} l_est;
The first type definition of struct l_est is a so-called "incomplete type". This type may not be used for variables or with sizeof but it may be used to declare pointer.
The incomplete type may later be overridden by a "complete type" without complaints of the compiler.
Similar solutions can be found in other languages (e.g. Pascal).

Structure declaration in c with identifer

I am try to understand this C code:
typedef struct _IntElem *IntList;
typedef struct _IntElem { int head; IntList tail;} IntElem;
I understand that it defines a recursive type, a list. However I don't understand the way it is declared. What I understand is the second line, we define a structure named IntElem which consists of an integer and an IntList. But what is the _IntElem in this declaration?
The first line allocates memory for the list?
The first line
typedef struct _IntElem *IntList;
is to just create a typedef or an alias for struct _IntElem *. The alias is named IntList. FWIW, at this point of time, the definition of struct _IntElem need not to be known to the compiler.
The second line
typedef struct _IntElem { int head; IntList tail;} IntElem;
Actually defines an user-defined type _IntElem, with two members, head as int and tail as IntList(typedefed earlier)
typedef the type to IntElem.
Please Note: There is actually no variable created, for either of the type (s) (I'm not talking about the member variables, of course, they are part of the definition). So, there is no memory allocated , as such.
So, to be explicit
But what is the _IntElem in this declaration?
the _IntElem is the name of the user-defined data type. However, in some cases, it is optional. for example,
typedef struct { char name [32]; int age; float salary;} employee;
is both perfectly fine and legal, except the fact, in this case, we're creating an alias employee to an unnamed data type.
In C, if we have:
struct X
{
stuff....
};
then X is called a struct tag. It means that struct X is the name of a type. X on its own is not the name of a type. In fact X on its own behaves like any other undeclared identifier; this struct definition only defines the specific usage struct X.
We might say that struct tags live in a different namespace to other identifiers (not to be confused with C++ namespaces!)
Sometimes people don't like typing struct X everywhere. So they use typedef (which, confusingly, means to create a type alias) in order to make a single identifier that names the type:
typedef struct X SX;
means that SX is a type. But since struct tags are in their own namespace, you could even write:
typedef struct X X;
which means that X on its own refers to the same type as struct X does.
Hopefully you understand the code you are looking at now. I think it would have been clearer to write:
struct IntElem
{
int head;
struct IntElem *tail;
};
with the optional addition to save typing:
typedef struct IntElem IntElem;
Pointer typedefs are evil, so IntList can be omitted entirely. Possibly you could keep it around to use as an opaque type for the users of your list, but you should avoid using it during your list implementation.

Typedef struct wrong declaration?

I referred to the tutorial below and later realized it is wrong way of declaring struct using typedef.
typedef struct
{
char name[namesize];
char address[addresssize];
int YearOfBirth;
int MonthOfBirth;
int DayOfBirth;
} PersonalData;
then declare:
PersonalData x;
However, I believe the right way is
typedef struct personaldataStruct
{
char name[namesize];
char address[addresssize];
int YearOfBirth;
int MonthOfBirth;
int DayOfBirth;
} PersonalData;
then declare:
PersonalData x;
Did the author mislead me? or both ways are correct? please confirm.
Here is the tutorial http://www.iu.hio.no/~mark/CTutorial/CTutorial.html
There's nothing formally "incorrect" about either approach.
The former declares a tag-less struct type and a typedef name PersonalData for that struct type. The latter declares a struct type struct personaldataStruct and a synonymous typedef name PersonalData for that struct type. The personaldataStruct part of the declaration is commonly referred as a "struct tag".
As long as you use PersonalData typedef name for referring to that struct type, as in
PersonalData x;
you will not see any difference between the two declarations. In both cases x will be declared identically.
The latter approach provides you with an alternative way of referring to the same struct type - struct personaldataStruct - if for some reason you will wish to do so. E.g. when using the latter declaration, you can also declare your x as
struct personaldataStruct x;
which is exactly equivalent to the PersonalData x; declaration.
Personally, I prefer to use the approach with struct tag, since it provides me with alternative way of referring to the type, which might come handy in some situations (for example, when the struct type has to refer to itself). But in most non-self-referential cases one will be perfectly fine with the former approach.
Both are correct. The only real problem with the first form (without the tag) is that, because the typedef name doesn't become visible until the end of the definition, there's no way to refer to the structure from within its own definition. That's a common requirement; for example, a node in a linked list, tree, or other graph-like data structure commonly needs to point to other objects of the same type.
Since struct tags and typedef names are in different namespaces (not to be confused with C++ namespaces), there's no need for them to be distinct. It's perfectly acceptable to use the same identifier for both:
typedef struct PersonalData {
/* ... */
struct PersonalData *next;
} PersonalData;
Or, as long as you're going to have both a tag and a typedef anyway, you can forward declare the typedef:
typedef struct PersonalData PersonalData;
/* At this point, "struct PersonalData is an incomplete type. */
struct PersonalData {
/* ... */
PersonalData *next;
};
/* And now "struct PersonalData" is a complete type. */
(But a misspelling can leave you with a typedef that still refers to an incomplete type that's never completed, which can trigger errors that can be difficult to track down. Copy-and-paste is your friend.)
And there is another alternative. The type you've defined already has a name: struct PersonalData. All the typedef does is give that same type a different name. It's nice to be able to use a single identifier as a type name, but it's really not necessary. My own preference is to omit the typedef altogether, and just refer to the type as struct PersonalData:
struct PersonalData {
/* ... */
struct PersonalData *next;
};
struct PersonalData *head;
struct PersonalData fred;
Unless PersonalData is meant to be an opaque type (meaning that code that uses it doesn't need to know that it's a struct), there's some advantage in being explicit.
Plenty of people strongly disagree with me on this point, and really like using typedefs for structures, as you'll probably see in comments. There's nothing wrong with using typedefs like this; it's just not necessary. You should be prepared to read code written by others using either style.

What's the benefit of a typedef in C?

typedef struct _VIDEO_STREAM_CONFIG_CAPS
{
GUID guid;
ULONG VideoStandard;
SIZE InputSize;
SIZE MinCroppingSize;
SIZE MaxCroppingSize;
int CropGranularityX;
int CropGranularityY;
int CropAlignX;
int CropAlignY;
SIZE MinOutputSize;
SIZE MaxOutputSize;
int OutputGranularityX;
int OutputGranularityY;
int StretchTapsX;
int StretchTapsY;
int ShrinkTapsX;
int ShrinkTapsY;
LONGLONG MinFrameInterval;
LONGLONG MaxFrameInterval;
LONG MinBitsPerSecond;
LONG MaxBitsPerSecond;
} VIDEO_STREAM_CONFIG_CAPS;
Why not define structure VIDEO_STREAM_CONFIG_CAPS directly instead of involving _VIDEO_STREAM_CONFIG_CAPS?
Quite simply (at least for me) because some people like to be able to treat user defined types as "primary" types.
Just like I wouldn't like to have to say:
struct int i;
I prefer:
VIDEO_STREAM_CONFIG_CAPS vscc;
to:
struct VIDEO_STREAM_CONFIG_CAPS vscc;
In fact, I usually get rid of the structure tag altogether, preferring:
typedef struct {
GUID guid;
ULONG VideoStandard;
:
} VIDEO_STREAM_CONFIG_CAPS;
The only time I genarally use the tag is if I have to refer to the type within the type definition itself, such as in linked lists:
typedef struct sNode {
char paylod[128];
struct sNode *next;
} tNode;
That's because, at the time of creating the definition, tNode doesn't yet exist but struct sNode does (you can think of it as a simple sequencing thing if that makes it easier - struct sNode gets created on line 1 above, tNode on line 4, which means on line 3 where you create the next pointer, you have to use the structure name).
In the case you cite, the structure tag is superfluous at least in the code shown. Whether some other piece of the code declares a variable with the structure name rather than the typedef name is unclear.
In c, you have to put struct in front of a declaration of a struct type. Without this typedef, you'd have to write struct VIDEO_STREAM_CONFIG_CAPS each time you wanted to use it. With the typedef, you can say just VIDEO_STREAM_CONFIG_CAPS as you would in c++.
struct a {};
struct a A;
OR
typedef struct a {} a;
a A;
In that case, each time a variable of type VIDEO_STREAM_CONFIG_CAPS is declared, the following syntax would be required:
struct VIDEO_STREAM_CONFIG_CAPS vscc;
With typedef struct it is:
VIDEO_STREAM_CONFIG_CAPS vscc;

Resources