Structure in C Programming

Structures in C Programming

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.

Table of Contents

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
M. Saqib: Saqib is Master-level Senior Software Engineer with over 14 years of experience in designing and developing large-scale software and web applications. He has more than eight years experience of leading software development teams. Saqib provides consultancy to develop software systems and web services for Fortune 500 companies. He has hands-on experience in C/C++ Java, JavaScript, PHP and .NET Technologies. Saqib owns and write contents on mycplus.com since 2004.
Related Post