structure in C: you should know in depth

structure in c

The C language supports the user-defined data type like union, enum, and structure in C.  Using the struct keyword we can create the structure in C (User-defined data type). In this article, I will not only discuss the structure but also discuss the new feature that is introduced by the C99 and C11.

What is the structure in C?

A structure is used to store the different types of data and every data (structure member) has own independent memory that means we can access any member anytime.

Generally, a structure is used to bind the different data types in a single entity that helps to manage the information. For example, if you want to track the information of your employees, like their name, age, salary, etc, you can do it very easily with the help of structure.

Syntax of structure in C:

struct [name of structure] {member-list };

Parameters of struct
name
The type name was given to the structure.
member-list
Members that the structure can contain.

 

Defining a structure in C

At the time of structure declaration, a structure tag is optional and each member of structure define as a normal variable. The number of member variables depends on the requirement.

In C language, at the end of the structure (close braces), before the final semicolon, we can define a structure variable but it is optional and depend on the developer.

In the below structure, data is a structure variable and Age, fees, name are member variables. Using the data (structure variable), we can store an integer, a floating-point number or a string.

struct MyData
{
    int Age;

    float fees;

    char name[4];

} data;

 

A structure does not contain a member with incomplete or function type (except the flexible array) that is the reason at the time of structure declaration, it cannot contains the instance of itself but contains a pointer to itself.

struct MyData
{
    int a;

    struct MyData b; // illegal

} data;






struct MyData
{
    int a;

    struct MyData *b; // valid

} data;






struct MyData
{
    int a;

    int b[]; //valid in C99 and C11

};





struct MyData
{

    int b[];       //illegal

};

 

Note: GCC permits a C structure to have no members.

struct MyData
{

};

 

 

Initialization of structure in C

We cannot initialize the member of the structure at the time of the structure declaration because there is no memory is allocated to the members at the time of declaration.

See the below programming example,

struct Mydata
{
    int a = 0;  //illegal

    int b = 0;  //illegal

};

 

Note:  A structure type declaration is only a template. There is no memory reserved for the structure until a variable is declared.

We can initialize the structure members using the curly braces { }.

Suppose Mydata is a structure and members are a and b.

struct Mydata
{
    int a;

    int b;
};

 

If I create a variable InfoData and need to initialize the members of InfoData by 2 and 3, there are the following ways.

Method1:

struct Mydata InfoData = { 2 , 3 };

 

Method2:

struct Mydata InfoData;

InfoData.a = 2;

InfoData.b = 3;

 

In C99 and C11 have designated initializer feature that means we can initialize the members of the structure in any order using the dot (.) and member name ( .member_name).

See the below example,

struct Mydata InfoData = {.a = 2, .b = 3};

or

struct Mydata InfoData = {.b = 3, .a = 2};

 

The above expression is equivalent to

struct Mydata InfoData = { 2 , 3 };

 

Use of  typedef with a structure

When we use typedef with structure then it creates the alias of the structure. There is no need to write struct keyword every time with a variable declaration that means typedef save extra keystroke and make the code cleaner and readable.

typedef struct
{
    char acName[20];
    int iAge;
    int iTotalMarks;

} sStudentInfo;

sStudentInfo amlendra;

 

You can also see,  Application of typedef

 

Accessing structure Members using variable and pointer

structure members access by a dot ( . ) or arrow ( -> ) operator, the left (first) operand of the operator should be variable of structure or pointer to the structure and right (second) operand shall name of a member that you want to access.

Let’s take an example to understand the above expression.

struct Laptop
{
    float price;

    int ProductId;

    char name[24];

} Laptop1, *Laptop2;


In the above example, there is a three-member variable of a structure, price, ProductId, and name. I have created a Laptop1 a variable structure and a Laptop2 pointer to the structure.

Now, suppose you want to access the ProductId using Laptop1
(structure variable), so it can be accessed like:

Laptop1. ProductId

Likewise, if you want to access the ProductId using Laptop2 (pointer to a structure), so it can be accessed like:

Laptop2-> ProductId

You can also write the above expression using the dot ( .) operator.

(*Laptop2). ProductId

 

Program example to understand how to access members of the structure

#include <stdio.h>
#include <string.h>
#include <stdlib.h>


//Declaration of structure in c
struct Laptop
{

    float price;

    int ProductId;

    char name[24];

} Laptop1, *Laptop2;


int main( )
{
    printf("Access members using the variable of struct\n\n");

    Laptop1.price = 20045.56;

    Laptop1.ProductId = 345;

    strcpy( Laptop1.name, "Lenovo");


    printf( "Laptop price : %f\n", Laptop1.price);

    printf( "Laptop product Id : %d\n", Laptop1.ProductId);

    printf( "Laptop name : %s\n", Laptop1.name);


    printf("\n\nAccess members using the pointer to struct\n\n");

    //Assign memory to the pointer to structure
    Laptop2 = malloc(sizeof(struct Laptop ));
    if(Laptop2 == NULL)
    {
        printf("Failed to allocate the memory");
        return -1;
    }


    Laptop2->price = 10045.56;

    Laptop2->ProductId = 245;

    strcpy(  Laptop2->name, "Dell");


    printf( "Laptop price : %f\n",  Laptop2->price);

    printf( "Laptop product Id : %d\n",  Laptop2->ProductId);

    printf( "Laptop name : %s\n",  Laptop2->name);


    //Now free the allocated memory
    free(Laptop2);

    Laptop2 = NULL;

    return 0;
}

I have already explained that all member of the structure has own independent memory location, so you can access any member at any time frame.

 

If you want to learn more about the c language, here 10 Free days (up to 200 minutes) C video course for you.

Your free trial is waiting

 

 

How to calculate the size of a structure in c?

Using the sizeof operator or own created macro or function we can calculate the size of a structure. The size of a structure in c is the sum of the size of its all member (including the required structure padding).

#include <stdio.h>


typedef struct
{
    char Name[12];
    int Age;
    float Weight;
    int RollNumber;

} sStudentInfo;



int main()
{
    //create variable of the structure;
    sStudentInfo RamInfo;

    //Size of the structure
    printf("Size of structure  =  %d\n\n",sizeof(RamInfo));
    
    return 0;
}

 

For more detail see this:  Calculate the size of structure without using the sizeof operator

 

 

Some important features and applications of structure in C.

 

Anonymous structure in C11

A struct or union with no tag is called an anonymous structure or union. An anonymous structure or union is introduced in C11 not supported by the c99 or older compiler.

struct //anonymous struct
{
short int b;
};

 

union //anonymous union
{
    short int b;
};

 

If a structure contains the anonymous structure or union(only in C11), The members of an anonymous structure or union are considered to be members of the containing structure or union.

#include <stdio.h>
#include<string.h>

struct myData
{
    union   // anonymous union
    {
        short int a;

        short int b;
    };

    short int c;

};


int main()
{
    //Variable of structure
    struct myData sMydata;

    sMydata.a =10; //valid

    sMydata.b = 20;  //valid

    sMydata.c = 40;  //valid

    return 0;
}

 

The above describe rule applies recursively if the containing structure or union is also anonymous.

#include <stdio.h>

struct myData
{
    union   // anonymous union
    {
        struct
        {
            short int a;

        } data; //data is struct variable
        struct //anonymous struct
        {
            short int b;
        };

    };

    short int c;

};


int main()
{
    struct myData sMydata; //struct variable

    sMydata.a = 5; //invalid

    sMydata.data.a =10; //valid

    sMydata.b = 20; //valid

    sMydata.c = 40; //valid
}

 

 

Designated initialization of the structure in C

C11 and C99 support the designation initialization of the structure. In the initialization section, I have described the designation initialization of structure.

 

struct hack in C

Previously when C99 had not introduced a flexible array, people used the technique of struct hack to create a flexible length member. The struct hack technique permits the user to create a variable length member in the structure.

In the struct hack techniques, we need to create an array whose length is 0 (some compiler does not support the 0 size array). When we create a zero-size array then structure becomes the incomplete type. An incomplete type structure is a type that has a lack of information about its members.

Let’s take an example to understand the techniques of struct hack,

As I have mentioned above, if we create an incomplete type member in the structure, the structure becomes incomplete types and this technique is called struct hack.

In the below structure I am creating a character array to store student name, I am giving the length of the array 0 (some compiler does not support 0 length array, in that scenario we have to take the length of the array 1).

typedef struct
{
    int RollNumber;

    int TotalMarks;

    char Name[0];

} sStudentInfo;

 

For more detail see this article: Importance of struct hack in c

 

Flexible array member in c

The C99 introduced the concept of the flexible array. This feature enables the user to create an empty array in a structure, the size of the empty array can be changed at runtime as per the user requirements. This empty array should be declared as the last member of the structure and the structure must contain at least one more named member.

An example of a flexible array in c

typedef struct
{
    int iTrackNumber;
    float fAmount;
    char acAddress[];
} sInformation;

 

For more detail see this article: Flexible array in c

 

 

structure bit-field in C

In C language, a structure supports the bit-field. The bit field allows the packing of data in a structure or union and prevents the wastage of memory.

Syntax:

In C language declaration of the bit-field structure or union is similar to the declaration of the normal structure or union, the main difference is that bit-field member is declared with a specified number of bits preceded by the colon.

struct
{
 type-specifier declarator opt : constant-expression
};

Here, constant-expression specifies the width of the field in bits and it must be a non-negative integer value. If the value is zero, the declaration has no declarator.

The type-specifier for the declarator must be _Bool, signed int, unsigned int, or some other implementation-defined type. It is implementation-defined whether atomic types are permitted.

Example,

Let’s see an example to understand the structure bit field.

struct packed_data
{
    unsigned int data1:1;
    unsigned int data2:1;
    unsigned int data3:1;
    unsigned int data4:1;
    unsigned int data5:1;
    unsigned int data6:3;
    unsigned int data7:6;
} sPackData;

 

In the above example, structure packed_data contains 7 members. In which five-member (data1 to data5) has 1 bit and 6th and 7th member has the 3 and 6 bits.

Way to access the member:

sPackData.data6 = 3;

Note: The layout of the bit-fields is implementation-defined that is the reason a lot of people are avoiding the use of bit-filed.

 

For more detail see this article: Understanding bit field in C

 

 

Polymorphism in C with the help of function pointer

We know that C is not an object-oriented language and it does not provide the concept oops. So if you want to implement a polymorphism concept in c, you need to combine structure and function pointer.

For example,

In our case, we are communicating with the server in two ways, with SSL, and without SSL and most important thing is that it is not an end. Maybe in the future, we need to select the other way for server communication.

So here we think to create a structure with some function pointers. This structure represents the generic containers and the function pointers behave like C++ member function.

typedef struct
{

    int (*OpenSocket)(void);

    int (*CloseSocket)(int);

    int (*ReadFromServer)(int,char*,short);

    int (*WriteToServer) (int,char*,short);

} sCommStructure;

 

The above-declared structure behaves like a generic container for the server communication API.

We have created the above typedef structure for the general-purpose communication library. We have to initialize the member of this structure as per the communication protocol types.

See the below code,

Initialize the structure variables for TCP/IP communication

sCommStructure *CreateTcpComm(void)
{

    sCommStructure *psComTcpIp = malloc (sizeof (sCommStructure));

    if (psComTcpIp != NULL)
    {

        psComTcpIp -> OpenSocket = &TcpSocketCreate;
        psComTcpIp -> CloseSocket = &TcpSocketClose;
        psComTcpIp -> ReadFromServer = &TcpSocketReceive;
        psComTcpIp -> WriteToServer = &TcpSocketSend;

    }

    return psComTcpIp;
}

 

Initialize the structure variables for UDP communication

sCommStructure *CreateUdpComm(void)
{

    sCommStructure *psComUdp = malloc (sizeof (sCommStructure));

    if (psComUdp!= NULL)
    {

        psComUdp -> OpenSocket = &UdpSocketCreate;
        psComUdp -> CloseSocket = &UdpSocketClose;
        psComUdp -> ReadFromServer = &UdpSocketReceive;
        psComUdp -> WriteToServer = &UdpSocketSend;

    }
    return psComUdp;

}

 

Suppose, now required to communicate with the server by the TCP/IP, then just call the CreateTcpComm function in your application.

Sample program,

int CommunicationWithTcp(char *Rqst, short lenRqst, char *Rsp,short RvcSize)
{

    int	hSocket = -1;
    short shortRetval = -1;

    //Call Create TcpComm function for tcp/Ip communication
    sCommStructure *psTcpcomm = CreateTcpComm ();

    //Create Socket

    hSocket = psTcpcomm->OpenSocket();
    if(hSocket < 0)
    {
        printf("Socket Creation Failed: SOCKET_HANDLER = %d", hSocket);
        return SOCKET_FAILED;
    }
    else
    {
        printf("Socket Creation Success: SOCKET_HANDLER = %d", hSocket);

    }

    //Send data
    shortRetval = psTcpcomm->WriteToServer(hSocket, Rqst, lenRqst);
    if(shortRetval<0)
    {
        printf("Socket Request Send Failed: RET_VALUE = %d", shortRetval);

        return SEND_FAILED;
    }
    else
    {
        printf("Socket Request Send Success: RET_VALUE = %d", shortRetval);

    }

    shortRetval = psTcpcomm->ReadFromServer(hSocket, Rsp, RvcSize);

    if(shortRetval<0)
    {
        printf("Socket REsponse Receive Failed: RET_VALUE = %d", shortRetval);

        return RECV_FAILED;
    }
    else
    {
        printf("Socket Request Receive Success: RET_VALUE = %d", shortRetval);

    }

    psTcpcomm->CloseSocket(hSocket);



    return 0;
}

 

In this way, a single type could be used for UDP, SNA, and RS232 with the same interface.

In server communication

At the time of client-server communication, we carry a huge amount of data. Here the advantage of the structure is that we can read and write the data at the appropriate field without hurdle and it helps to manage the data.

Reading and writing a file

A structure is also beneficial at the time of reading and writing in a file. We can read and write the proper data without calculating any offset.

You can see an article, Learn file handling in a few hours.

 

Difference between structure and union

The key difference between structure and union is that structure allocates enough space to store all the fields but unions only allocate enough space to store the largest field. In union, all fields are stored in the same space.

In the below table, I have listed some common differences between structure and union.

difference between union and structure

 

 

 

Recommended Post