Deeply understand the union (common body) and struct of C language

Posted by afern03 on Thu, 20 Jan 2022 13:36:24 +0100

A Union is defined in the following format:

union Common body name
{
    Member list
};            //A common body is sometimes called a Union or a Union, which is also the original meaning of the word Union.

Difference between structure and common body: each member of structure will occupy different memory and have no influence on each other; All members of the community occupy the same memory. Modifying one member will affect all other members.

Explanation of memory occupied by structure:

Memory alignment rules

         1. The starting address is an integer multiple of the memory occupied by the variable type. If it is insufficient, the insufficient part will be filled with data to an integer multiple of the memory occupied.  

        2. The total memory occupied by the structure is an integer multiple of the maximum data type in the structure member variable.

Rule 2 of memory occupied by structures can clearly tell us that the memory occupied by structures is not simply the sum of all members, which can be illustrated by a simple example

Example:

struct str1
    {
        char a;
        int b;
        float c;
        double d;
    };

In the above code, a accounts for 4 bytes, b for 4 bytes, c for 4 bytes, and d for 8 bytes. The total is 20 bytes. However, in fact, sizeof this structure, the size of the structure is 24 bytes

It is used for the total memory occupied by all members (there may be gaps between members, and the sizes of different members are different, but when the system requests memory for the structure), the memory occupied by the community is equal to the memory occupied by the longest member. The common body uses the memory overwrite technology. Only one member's value can be saved at the same time. If a new member is assigned, the value of the original member will be overwritten.

Take an example to understand the UNION community

union data
{
    int n;          //Four bytes
    char ch;        //Occupy one byte       
    short m;        //Two bytes
};
void main()
{

    union data data2;
        
    printf("%d\n",sizeof(data2));

}

The output is 4

Continue with the example

#include <stdio.h>
union data{
    int n;
    char ch;
    short m;
};
int main(){
    union data a;
    printf("%d, %d\n", sizeof(a), sizeof(union data) );
    a.n = 0x40;
    printf("%X, %c, %hX\n", a.n, a.ch, a.m);
    a.ch = '9';
    printf("%X, %c, %hX\n", a.n, a.ch, a.m);
    a.m = 0x2059;
    printf("%X, %c, %hX\n", a.n, a.ch, a.m);
    a.n = 0x3E25AD54;
    printf("%X, %c, %hX\n", a.n, a.ch, a.m);
   
    return 0;
}

Output results:

4, 4
40, @, 40
39, 9, 39
2059, Y, 2059
3E25AD54, T, AD54

This code not only verifies the length of the common body, but also shows that the members of the common body will affect each other. Modifying the value of one member will affect other members
In order to understand the above output results and find out how members interact with each other, it is necessary to understand the distribution of each member in memory. Taking the above data as an example, the distribution of each member in memory is as follows:

Members n, ch and m are "aligned" to one end in memory. The assignment of ch modifies the previous byte, the assignment of M modifies the first two bytes, and the assignment of N modifies all bytes. In other words, ch and m will affect part of the data of N, while n will affect all the data of ch and m.

The above figure shows the memory distribution on most PC s. if it is 51 single chip microcomputer, the situation will be different. I won't repeat it

Application of common body

The common body is less used in general programming and more used in single chip microcomputer. For PC, an example often used is: there is a form about student information and teacher information. Student information includes name, number, gender, occupation and score, and teacher information includes name, number, gender, occupation and teaching subjects. Please see the table below:

Name

Num

Sex

Profession

Score / Course

HanXiaoXiao

501

f

s

89.5

YanWeiMin

1011

m

t

math

LiuZhenTao

109

f

t

English

ZhaoFeiYan

982

m

s

95.0

f and m represent women and men respectively, s represents students and t represents teachers. It can be seen that the data contained by students and teachers are different. Now it is required to put this information in the same table, and design a program to input personnel information and then output it.

If everyone's information is regarded as a structural variable, the first four member variables of teachers and students are the same, and the fifth member variable may be score or course. When the value of the fourth member variable is s, the fifth member variable is score; When the value of the fourth member variable is t, the fifth member variable is course.

After the above analysis, we can design a structure containing a common body. Please see the following code:

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

#define TOTAL 4 / / total personnel

struct{
    char name[20];
    int num;
    char sex;
    char profession;
    union{
        float score;
        char course[20];
    } sc;
} bodys[TOTAL];

int main(){
    int i;
    //Enter personnel information
    for(i=0; i<TOTAL; i++){
        printf("Input info: ");
        scanf("%s %d %c %c", bodys[i].name, &(bodys[i].num), &(bodys[i].sex), &(bodys[i].profession));
        if(bodys[i].profession == 's'){  //If it's a student
            scanf("%f", &bodys[i].sc.score);
        }else{  //If it's a teacher
            scanf("%s", bodys[i].sc.course);
        }
        fflush(stdin);
    }

    //Output personnel information
    printf("\nName\t\tNum\tSex\tProfession\tScore / Course\n");
    for(i=0; i<TOTAL; i++){
        if(bodys[i].profession == 's'){  //If it's a student
            printf("%s\t%d\t%c\t%c\t\t%f\n", bodys[i].name, bodys[i].num, bodys[i].sex, bodys[i].profession, bodys[i].sc.score);
        }else{  //If it's a teacher
            printf("%s\t%d\t%c\t%c\t\t%s\n", bodys[i].name, bodys[i].num, bodys[i].sex, bodys[i].profession, bodys[i].sc.course);
        }
    }
    return 0;
}

Operation results:

Input info: HanXiaoXiao 501 f s 89.5↙
Input info: YanWeiMin 1011 m t math↙
Input info: LiuZhenTao 109 f t English↙
Input info: ZhaoFeiYan 982 m s 95.0↙

Name            Num     Sex     Profession      Score / Course
HanXiaoXiao     501     f       s               89.500000
YanWeiMin       1011    m       t               math
LiuZhenTao      109     f       t               English
ZhaoFeiYan      982     m       s               95.000000

 

Topics: C++ lwip