Explain the custom data types in C language

Table of contents

1. Structure

1.1 Declaration of structure

1.2 Self-reference of structure

1.3 Definition and initialization of structure variables

1.4 Memory alignment of structures

1.5 Modify the default alignment of the structure

1.6 Structure parameter passing

2. Bit segment

2.1 What is a bit segment

2.2 Memory allocation for bit segments

3. Enumeration

3.1 Definition of enumerated types

3.2 Values ​​of enumerated types

4. Commonwealth - Commonwealth

4.1 Definition of Consortium

4.2 Calculation of the size of the union


1. Structure

A structure is a variable of some values, these values ​​are called member variables, and each member of a structure can be a variable of a different type.

1.1 Declaration of structure

To declare a student type is to create a student variable (object) through the student type, attribute-name-age-gender-student number.

Example:

struct Stu
{
    char name[20]; //名字;
    int age;// 年龄;
    char sex[5];  //性别;
    char id[20]; //学号;
} s4,s5,s6;//分号不能丢,s4,s5,s6都是全局的结构体变量;
struct Stu s3;// 全局变量;
int main()
{
    //创建结构体变量;
    struct Stu s1;
    struct Stu s2; 
}

Anonymous struct:

struct
{
    int a;
    char c;
}sa;   //该方式为匿名结构体,只能用一次;
struct 
{
    int a;
    char c;
}* psa;
int main()
{
    psa=&sa;  //是不行的,因为上面两种匿名结构体,系统当成了不同的两种类型;
}

1.2 Self-reference of structure

As the name implies, there are structures in the member variables of the structure.

Example:

struct Node
{
    int data;
    struct Node* next; //链表中,节点中,一个存放数值,一个存放下一个节点的地址;
}

1.3 Definition and initialization of structure variables

struct Point
{
    int x;
    int y;
}p1;  //声明结构体变量的同时定义变量p1;
struct Point p2;  //定义结构体变量p2;

initialization:

struct s
{
    char c;
    int a;
    double d;
    char arr[20];
};
int main()
{
    struct s s1={'c',100,3.14,"hello bit"};  //结构体的初始化;
    printf("%c %d %lf %s",s1.c,s1.a,s1.d,s1.arr);  //打印结构体成员;
}

Initialization of nested structures:

struct T
{
    double weight;
    short age;
};
struct S
{
    char c;
    struct T st;   //嵌套结构体的初始化;
    int a;
    double d;
    char arr[20];
};
int main()
{
    struct S s{'c',{55.6,30},100,3.14,"hello bit"};
    printf("%lf\n",s.st.weight);
}

1.4 Memory alignment of structures

Consider the following example:

struct S1
{
    char c1;
    int a;
    char c2;
};
struct S2
{
    char c1;
    char c2;
    int a;
};
int main()
{
    struct S1 s1={0};
    printf("%d\n",sizeof(s1));
    struct S2 s2={0};
    printf("%d\n",sizeof(s2));  //结果为12 和 8
    return 0;
}

We can find that the size of the structure S1 is 12, and the size of the structure S2 is 8. The size of each member variable is not simply added. This is mainly due to the memory alignment of the structure. The calculation rules are as follows:

Calculation rules: the first member is at the address with an offset of 0 from the structure variable, and other member variables must be aligned to an address that is an integer multiple of a certain number (alignment number);

Alignment = the compiler's default alignment and the smaller value of the member size; (the default value in VS is 8)

The total size of the structure is an integer multiple of the maximum alignment.

Explanation: Like the structure S1 above, the first type of char is a byte, and the size is 1 at this time, and then the second data type is int, and the size of int is 4. Compared with the default alignment number, 4 <8, so the alignment number is 4 at this time, so if the place where the next data starts to be stored is a multiple of 4, that is, the second data should be stored from the place of 4, and then the int type occupies 4 bytes, and the total size at this time is 8; Then, the third one is char type, at this time 8 is an integer multiple of char, so the total size at this time is 9, the alignment numbers of the three data are 1, 4, 1 respectively, the maximum value of which is 4, and finally If the total size of is an integer multiple of the maximum alignment number, so at this time 9 should find 3 more spaces, making the size of the structure become 12.

Similarly, looking at the structure S2, its memory calculation process is the same. The first one occupies 1 byte, the second is still of char type and occupies 1 byte at this time, and the third is of int type, so the third To store 4 bytes from a multiple of 4, that is, 4 to 8, and then 8 is an integer multiple of 4, so the final size is 8.

Here are two examples for you to practice:

Exercise 1:

struct s3
{
    double d;
    char c;
    int i;
};
printf("%d\n",sizeof(struct s3));

Exercise 2:

struct s4
{
    char c1;
    struct s3 s3;
    double d;
};
printf("%d\n",sizeof(struct s4)); 

1.5 Modify the default alignment of the structure

You can use the #pragma pack() preprocessing command to modify the default alignment of the structure

Example:

#pragma pack(4)  //设置默认对齐数为4;
struct s
{
    char c1; //
    //7
    double d;// 8
};
#pragma pack()  //取消设置的默认对齐数,为了性能故不会设置成1;

1.6 Structure parameter passing

When using a structure, there are two commonly used ways of passing parameters: passing by value and passing by address. The following is an example, and it is best to use the method of passing by reference.

Example:

struct S
{
    int a;
    char c;
    double d;
};
void Init(struct S* ps)
{
    ps->a=100;
    ps->c='w';
    ps->d=3.14;
}
void Print1(struct S tmp)
{
    printf("%d %c %lf\n",tmp.a,tmp.c,tmp.d);
}
void Print2(struct S* ps)
{
    printf("%d %c %lf\n",ps->a,ps->c,ps->d);
}
int main()
{
  struct S s={0};
    Init(&s);
        Print1(s);
    Print2(&s);  //尽量使用这种传址的方式,原因:Print1需要压栈的,如果传过去的结构体大小过大,会导致性能的下降。
}

2. Bit segment

After the structure is finished, it is necessary to talk about the ability of the structure to realize the bit segment.

2.1 What is a bit segment

The declaration of a bit field is similar to a structure, but there are two differences

1. The members of the bit field must be int, unsigned int or signed int;

2. There is a colon and a number after the member name of the bit segment;

for example:

//位段——其中的位为二进制位;
struct A
{
    int a:2;  //a只需要2个bit位,对应2个二进制位;
    int b:5;  //b只需要5个bit位, 对应5个二进制位; 
    int c:10;
    int d:30;
};  //A就是一个位段类型; //总共需要47个bit位,换算可以得到4个字节(一个字节8个bit位)
int main()
{
    struct A a;
    printf("%d\n",sizeof(a));  //结果为8,单位为字节;

Int has 4 bytes and 32 bits. When 2, 5, and 10 are put down, there are only 15 bits left, and 30 cannot be put down. At this time, the remaining 15 is discarded, and a new piece of 32 is put in 30, so Ultimately two 4 bytes, or 8 bytes

2.2 Memory allocation for bit segments

1. The members of the bit field can be int, unsigned int , signed int or char type;

2. The space of the bit segment is opened up according to the need for 4 bytes or 1 byte;

3. Bit segments involve many uncertain factors and cannot be cross-platform. Note that portable programs should avoid using bit segments.

Bit segments can save space very well, but there are cross-platform problems.

3. Enumeration

Enumeration, as the name suggests, is - enumeration, enumerating the possible values ​​one by one.

3.1 Definition of enumerated types

//枚举类型
enum Sex //性别
{
    //枚举的可能取值,也叫枚举常量
    MALE,
    FEMALE,
    SECRET
};

3.2 Values ​​of enumerated types

enum Sex
{
    MALE,
    FEMALE,
    SECRET
};
enum Color
{
    RED=2,
    YELLOW=4,
    BLUE=8
};
int main()
{
    enum Sex s=MALE;
    s=FEMALE;
    enum Color c=BLUE;
    printf("%d %d %d",MALE,FEMALE,SECRET); //打印结果为0  1  2,第一个默认为0,后面的+1;
    printf("%d %d %d",RED,YELLOW,BLUE); //打印结果为2,4,8;
    return 0;
    
}

If the enumeration type is initialized, it will be printed according to the initialized value. If not, the first one will default to 0, and the latter will be added by one. If the above blue is not initialized, the value of Blue will become 5 at this time. , that is, add one to the value of yellow.

4. Commonwealth - Commonwealth

4.1 Definition of Consortium

Union is also a special custom type. This type of variable contains a series of members, and the characteristic is that these members share a space.

for example:

union Un
{
    char c;
    int i;
};
int main()
{
    union Un u;
    printf("%d\n",sizeof(u));  //大小为4,联合变量的大小是最大成员的大小;
    printf("%p\n",&(u.c));
    printf("%p\n",&(u.i));
    printf("%p\n",&u);  //三个得到的地址完全相同;
    return 0; 
}

4.2 Calculation of the size of the union

1. The size of the union is at least the size of the largest member;

2. When the maximum member size is not an integer multiple of the maximum alignment number, it must be aligned to an integer multiple of the maximum alignment number.

Example:

union Un
{
    int a;//4 ,默认对齐数为8,4比较小,所以为4
    char arr[5];//5,char 为1,1比8小,为1;
    //最大对齐数为4
};
int main()
{
    union Un u;
    printf("%d\n",sizeof(u));  //结果为8
    return 0;
}

Supongo que te gusta

Origin blog.csdn.net/yss233333/article/details/123761594
Recomendado
Clasificación