Programming‎ > ‎C‎ > ‎

Structure

1. Find the offset of member in the structure.
    offsetof (type,member)
This macro with functional form returns the offset value in bytes of member member in the structure type type.
     
/* offsetof example */
#include <stdio.h>
#include <stddef.h>

struct mystruct {
  char singlechar;
  char arraymember[10];
  char anotherchar;
};

int main ()
{
  printf ("offsetof(mystruct,singlechar) is %d\n",offsetof(mystruct,singlechar));
  printf ("offsetof(mystruct,arraymember) is %d\n",offsetof(mystruct,arraymember));
  printf ("offsetof(mystruct,anotherchar) is %d\n",offsetof(mystruct,anotherchar));
  
  return 0;
}


Output:
offsetof(mystruct,singlechar) is 0
offsetof(mystruct,arraymember) is 1
offsetof(mystruct,anotherchar) is 11

    struct mystruct my;
    anotherchar offset = &(my.anotherchar) - &my;


2. What is forward reference in C, wrt to pointers\structure.
 
    The pointer is declared before the structure it points to is declared.    
    The compiler can get away with this because the pointer stores an address, and you don't need to know what is at that address.
 
    typedef struct Node *NodePtr;  // this is a forward reference
    NodePtr ptr;
    // ptr->link;  //Illegal
    // typedef struct Node node; //Illegal
 
    typedef struct Node {
        NodePtr link;    // another forward reference
    };


3. Bit Field

Both C and C++ allow integer members to be stored into memory spaces smaller than the compiler would ordinarily allow. These space-saving structure members are called bit fields, and their width in bits can be explicitly declared. Bit fields are used in programs that must force a data structure to correspond to a fixed hardware representation and are unlikely to be portable.

A bit field declaration may not use either of the type qualifiers, const or volatile.

The following restrictions apply to bit fields. You cannot:

  • Define an array of bit fields
  • Take the address of a bit field
  • Have a pointer to a bit field
  • Have a reference to a bit field

If a series of bit fields does not add up to the size of an int, padding can take place. The amount of padding is determined by the alignment characteristics of the members of the structure.

The following example demonstrates padding, and is valid for all implementations. Suppose that an int occupies 4 bytes. The example declares the identifier kitchen to be of type struct on_off:

struct on_off {
                  unsigned light : 1;
                  unsigned toaster : 1;
                  int count;            /* 4 bytes */
                  unsigned ac : 4;
                  unsigned : 4;
                  unsigned clock : 1;
                  unsigned : 0;
                  unsigned flag : 1;
                 } kitchen ;

The structure kitchen contains eight members totalling 16 bytes. The following table describes the storage that each member occupies: 

Member NameStorage Occupied
light1 bit
toaster1 bit
(padding -- 30 bits)To the next int boundary
countThe size of an int (4 bytes)
ac4 bits
(unnamed field)4 bits
clock1 bit
(padding -- 23 bits)To the next int boundary (unnamed field)
flag1 bit
(padding -- 31 bits)To the next int boundary

All references to structure fields must be fully qualified. For instance, you cannot reference the second field by toaster. You must reference this field bykitchen.toaster.

The following expression sets the light field to 1:

  kitchen.light = 1;

When you assign to a bit field a value that is out of its range, the bit pattern is preserved and the appropriate bits are assigned. The following expression sets the toaster field of the kitchen structure to 0 because only the least significant bit is assigned to the toaster field:

  kitchen.toaster = 2;


Comments