What is a Union?

A union in C programming is a user defined data type which may hold members of different sizes and type. Union uses a single memory location to hold more than one variables. However, only one of its members can be accessed at a time and all other members will contain garbage values.

The memory required to store a union variable is the memory required for the largest element of the union. We can use pointers to unions and can access members using arrow operator (->).

We can use the unions in the following locations.

  1. Share a single memory location for a variable and use the same location for another variable of different data type.
  2. Use it if you want to use, for example, a long variable as two short type variables.
  3. We don’t know what type of data is to be passed to a function, and you pass union which contains all the possible data types.

So, how we can define and declare and initialize a union in a C Program?

How to define a union in C?

Union can be defined by the keyword 

union

  followed by list of member variables contained in curly braces.

union Employee{
	int age;
	long salary;
};

Here we have defined a union with the name union_name and it has two members i.e. age of type int and salary of type long.

How to declare a union in C?

We can declare the union in various ways. By taking the above example we can declare the above defined union as.

union Employee{
	int age;
	long salary;
} employee;

So

employee

  will be the variable of type

Employee

 . We can also declare the above

union

  as:

Employee employee;

How to initialize a union in C?

We can initialize the union in various ways. For example

union Employee{
	int age;
	long salary;
} employee={20000};

or we can initialize it as

employee.age= 30;
employee.salary=20000;

Normally when we declare the union it is allocated the memory that its biggest member can occupy. So here in our example employee will occupy the memory which a long type variable can occupy.

Similarly union values can be accessed via pointer variables.

union Employee{
 int age;
 long salary;
} *employee;

(*employee).age;
or;
employee->age;

What are the uses on Union type?

The important use of a union is allowing access to a common location by different data types. For example hardware input and output access, bit-field and word sharing, or type punning. Unions can also provide low-level polymorphism in C++.

What is a structure?

A structure is a convenient tool for handling a group of logically related data items. Structure help to organize complex data is a more meaningful way. It is powerful concept that we may after need to use in our program Design.

A structure is combination of different data types. Lets take the example of a book, if we cant to declare a book we will be thinking about the name, title, authors and publisher of the book and publishing year. So to declare a book we need to have some complex data type which can deal with more than one data types.

So, how we can define and declare and initialize a structure in a C Program?

How to define a structure in C?

We can define a structure by using the keyword

struct

  followed by list of member variables contained in curly braces

struct Book
{
	char Name[100];
	char Author[100];
	char Publisher[80];
	int Year;
};

The keyword

struct

  defines a book, and each line with in the braces defines the elements of the Book. Now when ever we create an instance of Book it will have all the elements of the structure i.e. Name, Author, Publisher and Year.

How to declare a structure in C?

We can declare the structure just like union by using the following syntax.

Book CProgrammingBook;

How to initialize a structure in C?

Lets initialize the structure variable CProgrammingBook.

Book CProgrammingBook =
{
	"Beginning VC++ 6",
	"Ivor Horton",
	"Wrox",
	2001
};

Accessing the members of a Structure

We can access all the members of a structure by adding a period after the name of the structure variable name and then the name of the field we want to access. For example we want to change the Publish year from 2001 to 2002, we will do
it as

CProgrammingBook.Year = 2002;

Array of Structures

Each element of the array itself is a structure see the following example shown below. Here we want to store data of 5 persons for this purpose, we would be required to use 5 different structure variables, from sample1 to sample 5. To have 5 separate variable will be inconvenient.

#include <stdio.h>
  
int main() {
    struct person {
      char name[25];
      int age;
    };
    
    struct person sample[3];
    int index;

    for (index = 0; index < 3; index++) {
      printf("Enter name: \n");
      scanf("%s", sample[index].name);
      printf("Enter Age: \n");
      scanf("%d", &sample[index].age);
    }
    
    for (index = 0; index < 3; index++) {
      printf("name = %s\n", sample[index].name);
      printf("Age = %d \n", sample[index].age);
    }
    
    return 0;
  }

The structure type person is having 2 elements: Name an array of 25 characters and integer type variable age. Using the statement

struct person sample[5];

  we are declaring a 5 element array of structures. Here, each element of sample is a separate structure of type person. We, then defined 2 variables into index and an array of 8 characters, info. Here, the first loop executes 5 times, with the value of index varying from 0 to 4. The first

printf()

  function displays. For the first time this name you enter will go to

sample[0]

. name.  The second for loop in responsible for printing the information stored in the array of structures.

Nesting Structures in C

Structure with in a structure means nesting of structures. Let us consider the following structure defined to store information about the salary of employees.

struct salary {
  char name[20];
  char department[10];
  int basic_pay;
  int dearness_allowance;
  int city_allowance;
}
employee;

This structure defines name, department, basic pay and 3 kinds of allowance. we can group all the items related to allowance together and declare them under a substructure are shown below:

struct salary
{
  char name [20];
  char department[10];
  str uct
  {
    int dearness;
    int hous_rent;
    int city;
  }
  allowance;
}
employee;

The salary structure contains a member named allowance which itself is a structure with 3 members. The members contained in the inner, structure namely dearness, house_rent, and city can be referred to as :

employee allowance. dearness
employee. allowance. house_rent
employee. allowance. city

An inner-most member in a nested structure can be accessed by chaining all the concerned. Structure variables (from outer-most to inner-most) with the member using dot operator. The following being invalid.

employee. allowance (actual member is missing)
employee. house_rent (inner structure variable is missing)
Passing a Structure as a whole to a Function

Structures are passed to functions by way of their pointers. Thus, the changes made to the structure members inside the function will be reflected even outside the function.

#include <stdio.h>
typedef struct
{
  char *name;
  int acc_no;
  char acc_types;
  float balance;
} account;

int main()
{
  void change(account *pt);
  static account person = {"David", 4323,'R', 12.45};
  printf("%s %d %c %2f \n", person.name, person.acc_no, person.acc_types, person.balance);
  change(&person);
  printf("%s %d %c %2f \n", person.name, person.acc_no, person.acc_types, person.balance);
  
  return 0;
}

void change(account *pt)
{
  pt -> name = "David R";
  pt -> acc_no = 1111;
  pt -> acc_types = 'c';
  pt -> balance = 44.12;
  return;
}

Output of the C Program:

David 4323 R 12.45

David R 1111 c 44.12

How to compare two structures in C?

You can use memcmp() function. If your structure has pointers, then move them to the end and do not compare memory area for the pointer. You have to compare pointers explicitly.

See sample program below.

#include <stdio.h>
#include <conio.h>
struct S {
    int i;
    char sz[4];
    char* ptrC;
} s1, s2, s3;
void compare(void*, void*, int);
#define POPULATE(S, li, lsz, lptr) \
    {                              \
        S.i = li;                  \
        memcpy(S.sz, lsz, 4);      \
        S.sz[3] = 0;               \
        S.ptrC = lptr;             \
    }
char* one = "one";
char* two = "two";
int main(int argc, char* argv[])
{
    POPULATE(s1, 12, "HI", one);
    POPULATE(s2, 12, "HI", one);
    POPULATE(s3, 12, "HI", two);
    compare(&s1, &s2, sizeof(s1));
    compare(&s1, &s3, sizeof(s1));
    compare(&s1, &s3, 8);
    return 0;
}
void compare(void* v1, void* v2, int size)
{
    if (memcmp(v1, v2, size) == 0) {
        printf("Memory  area is same type\n");
    }
    else {
        printf("Memory area is different  type\n");
    }
    return;
}

The

memcmp()

  method needs a bit of extra caution because of memory alignment considerations. For example:

struct A
{
 int n;
 char c;
 int  m;
};

The memory layout of the struct A will be, on a 32 bit system with 4 byte alignment:

4 bytes for n;
1 byte for c;
3 unused bytes (garbage);
4 bytes for m;

If you use memcmp(), it can be that the 4 + 1 + 4 used bytes are identical but that there is a difference between the 3 garbage bytes. I don’t think in this case you want your comparison function to return false.

A workaround can be something like:

bool areEqual(struct A a1, struct A a2)
{
    struct A t1, t2;
    memset(&t1, 0, sizeof(A));
    memset(&t1, 0, sizeof(A));
    t1 = a1;
    t2 = a2;
    return !memcmp(&t1, &t2, sizeof(A));
}

If you have pointers in your structures, I suggest that you use a different structure for your “raw” data and add the pointers later:

struct A {
    int n;
    char c;
    int m;
};

struct APTR {
    A a;
    char* pt;
};
bool areEqualPtr(struct APTR a1, struct APTR a2)
{
    if (!areEqual(a1.a, a2.a))
        return false;
    return !strcpy(a1.pt, a2.pt);
}

Structure and Union specifiers have the same form. [ . . . ] The size of a union is sufficient to contain the largest of its members. The value of at most one of the members can be stored in a union object at any time. A pointer to a union object, suitably converted, points to each of its members (or if a member is a bit-field, then to the unit in which it resides), and vice versa.

— ANSI/ISO 9899:1990 (the ANSI C standard) Section 6.5.2.1