# Question 1

Can structures be assigned to variables and passed to and from functions?
Â

Yes, they can!

But note that when structures are passed, returned or assigned, the copying is done only at one level (The data pointed to by any pointer fields is not copied!.

# Question 2

Can we directly compare two structures using the == operator?
Â

No, you cannot!

The only way to compare two structures is to write your own function that compares the structures field by field. Also, the comparison should be only on fields that contain data (You would not want to compare the next fields of each structure!).

A byte by byte comparison (say using memcmp()) will also fail. This is because the comparison might fonder on random bits present in unused "holes" in the structure (padding used to keep the alignment of the later fields correct). So a memcmp() of the two structure will almost never work. Also, any strings inside the strucutres must be compared using strcmp() for similar reasons.

There is also a very good reason why structures can be compared directly - unions!. It is because of unions that structures cannot be compared for equality. The possibility that a structure might contain a union makes it hard to compare such structures; the compiler can't tell what the union currently contains and so wouldn't know how to compare the structures. This sounds a bit hard to swallow and isn't 100% true, most structures don't contain unions, but there is also a philosophical issue at stake about just what is meant by "equality" when applied to structures. Anyhow, the union business gives the Standard a good excuse to avoid the issue by not supporting structure comparison.

If your structures dont have stuff like floating point numbers, pointers, unions etc..., then you could possibly do a memset() before using the structure variables..

memsetÂ (&myStruct,Â 0,Â sizeof(myStruct));Â

This will set the whole structure (including the padding) to all-bits-zero. We can then do a memcmp() on two such structures.

memcmpÂ (&s1,&s2,sizeof(s1));Â

But this is very risky and can end up being a major bug in your code!. So try not to do this kind of memcmp() operations on structures variables as far as possible!

# Question 3

Can we pass constant values to functions which accept structure arguments?
Â

If you are trying to do something like this

myfunction((structÂ mystruct){10,20});

then, it wont work!. Use a temporary structure variable.

# Question 4

How does one use fread() and fwrite()? Can we read/write structures to/from files?
Â

Its easy to write a structure into a file using fwrite()

fwrite(&somestruct,Â sizeofÂ somestruct,Â 1,Â fp);

A similat fread() invocation can read it back in. But, data files so written will not be portable (specially if they contain floating point numbers). Also that if the structure has any pointers, only the pointer values will be written, and they are most unlikely to be valid when read back in. One must use the "rb/wb" flag when opening the files.

A more portable solution is to write code to write and read a structure, field-by-field, in a portable (perhaps ASCII) way!. This is simpler to port and maintain.

**

# Question 5

Why do structures get padded? Why does sizeof() return a larger size?
Â

Padding enables the CPU to access the members faster. If they are not aligned (say to word boundaries), then accessing them might take up more time. So the padding results in faster access. This is also required to ensure that alignment properties are preserved when an array of contiguous structures is allocated. Even if the structure is not part of an array, the end padding remains, so that sizeof() can always return a consistent size.

# Question 6

Can we determine the offset of a field within a structure and directly access that element?
Â

The offsetof() macro() does exactly this.

A probable implementation of the macro is

#defineÂ offsetof(type,Â mem)Â ((size_t)((charÂ *)&((typeÂ *)0)->memÂ -Â (charÂ *)(typeÂ *)0))

This can be used as follows. The offset of field a in struct mystruct is

offset_of_aÂ =Â offsetof(structÂ mystruct,Â a)

If structpointer is a pointer to an instance of this structure, and field a is an int, its value can be set indirectly with

*(intÂ *)((charÂ *)structpointerÂ +Â offset_of_a)Â =Â some_value;

# Question 7

What are bit fields in structures?
Â

To avoid wastage of memory in structures, a group of bits can be packed together into an integer and its called a bit field.

structÂ tag-name { Â Â Â Â data-typeÂ name1:bit-length; Â Â Â Â data-typeÂ name2:bit-length; Â Â Â Â ... Â Â Â Â ... Â Â Â Â data-typeÂ nameN:bit-length; }

A real example

structÂ student; { Â Â Â charÂ name[30]; Â Â Â unsignedÂ sex:1; Â Â Â unsignedÂ age:5; Â Â Â unsignedÂ rollno:7; Â Â Â unsignedÂ branch:2;Â Â Â  }; structÂ studentÂ a[100]; scanf("%d",Â &sex); a[i].sex=sex;

There are some limitations with respect to these bit fields, however:

1.Â CannotÂ scanf()Â directlyÂ intoÂ bitÂ fields. 2.Â PointersÂ cannotÂ beÂ usedÂ onÂ bitÂ fieldsÂ toÂ accessÂ them. 3.Â CannotÂ haveÂ anÂ arrayÂ ofÂ bitÂ fields.

The main use of bitfields is either to allow tight packing of data or to be able to specify the fields within some externally produced data files. C gives no guarantee of the ordering of fields within machine words, so if you do use them for the latter reason, you program will not only be non-portable, it will be compiler-dependent too. The Standard says that fields are packed into ?storage units?, which are typically machine words. The packing order, and whether or not a bitfield may cross a storage unit boundary, are implementation defined. To force alignment to a storage unit boundary, a zero width field is used before the one that you want to have aligned. Be careful using them. It can require a surprising amount of run-time code to manipulate these things and you can end up using more space than they save. Bit fields do not have addresses?you can't have pointers to them or arrays of them.

# Question 8

What is a union? Where does one use unions? What are the limitations of unions?
Â

A union is a variable type that can contain many different variables (like a structure), but only actually holds one of them at a time (not like a structure). This can save memory if you have a group of data where only one of the types is used at a time. The size of a union is equal to the size of it's largest data member. The C compiler allocates just enough space for the largest member. This is because only one member can be used at a time, so the size of the largest, is the most you will need. Here is an example:

unionÂ person { Â Â Â intÂ age; Â Â Â charÂ name[100]; }person1;

The union above could be used to either store the age or it could be used to hold the name of the person. There are cases when you would want one or the other, but not both (This is a bad example, but you get the point). To access the fields of a union, use the dot operator(.) just as you would for a structure. When a value is assigned to one member, the other member(s) get whipped out since they share the same memory. Using the example above, the precise time can be accessed like this:

person1.age;

In larger programs it may be difficult to keep track of which field is the currently used field. This is usually handled by using another variable to keep track of that. For example, you might use an integer called field. When field equals one, the age is used. If field is two, then name is used. The C compiler does no more than work out what the biggest member in a union can be and allocates enough storage (appropriately aligned if neccessary). In particular, no checking is done to make sure that the right sort of use is made of the members. That is your task, and you'll soon find out if you get it wrong. The members of a union all start at the same address?there is guaranteed to be no padding in front of any of them.

ANSI Standard C allows an initializer for the first member of a union. There is no standard way of initializing any other member (nor, under a pre-ANSI compiler, is there generally any way of initializing a union at all).

It is because of unions that structures cannot be compared for equality. The possibility that a structure might contain a union makes it hard to compare such structures; the compiler can't tell what the union currently contains and so wouldn't know how to compare the structures. This sounds a bit hard to swallow and isn't 100% true, most structures don't contain unions, but there is also a philosophical issue at stake about just what is meant by "equality" when applied to structures. Anyhow, the union business gives the Standard a good excuse to avoid the issue by not supporting structure comparison.