Master structure 1 (C language) from the shallower to the deeper

Foreword
Structure, as a major part of custom types, is naturally very important. In this blog, we will take you to understand the structure from the simple to the deep. . If you are interested in learning C language, please don’t forget to follow the blogger~ So without further ado, let’s get to the point
Insert image description here

1. Introduction to structure

The structure stores collections of different types. How do you say this? Suppose we want to describe a student's name, age, and grades.
First of all, the name should be a string, the age should be an integer, and the grade should be a floating point number. The information we want to store about this student cannot be stored in a single type, so our structure should be used. In the structure we can define various types.

2. Creation and initialization of structure variables

Creation and use of structure variables
I will explain it in code.
Take the student’s information just now to create a structure. The example is as follows.

#include<stdio.h>
struct student
{
    
    
	char name[20];//成员名这三个都是成员
	int age;
	float score;
};
int main()
{
    
    
	struct student stu1 = {
    
     "zhangsan",18,114.514 };//创建结构体变量stu1,struct student为类型名,其中储存了张三的名字年龄和成绩。//我们会发现输入数据是按照定义结构体成员的顺序输入的。
//那么我们能不能不按顺序输入呢?当然可以请看下面这种方法。
	struct student stu2 = {
    
     .age = 18,.score = 114.514,.name = "lisi" };//这样也可以吧数据储存到相应的位置。
	//打印出来stu1和stu2中的数据
		printf("%s %d %f\n%s %d %f", stu1.name,stu1.age,stu1.score, stu2.name, stu2.age, stu2.score);//在结构体变量后加.再加所需要的成员名即可找到相应的数据
	return 0;
}



Insert image description here

Creation and use of structure pointers
Please see the following code.

#include<stdio.h>
struct student
{
    
    
	char name[20];
	int age;
	float score;
};
int main()
{
    
    
	struct student stu1 = {
    
     "zhangsan",18,114.514 };
	struct student* s1 = &stu1;//结构体指针自然是用来储存结构体的地址的
	//那么我们怎么样通过指针取出所需要的数据呢?
	printf("%s %d %f\n%s %d %f", (*s1).name, (*s1).age, (*s1).score, s1->name, s1->age, s1->score);
	//显然是还有两种方法的一种是对结构体指针解引用找到其所指向的结构体,另一种则是同一个箭头->直接指向结构体中的成员,后者比较方便且可读性高
	return 0;
}

Insert image description here

In this way we understand the use of structure variables and structure pointers.

3. Memory alignment of structures

First, let’s take a look at what the following code will output?

#include<stdio.h>
struct s1
{
    
    
	char a;
	char b;
	int c;
};
struct s2
{
    
    
	char a;
	int c;
	char b;
};
int main()
{
    
    
	struct s1 w1;
	struct s2 w2;
	printf("%zd %zd", sizeof(w1), sizeof(w2));
	return 0;
}

There seems to be no difference between s1 and s2. They are both composed of two character data and an integer data, so the size of the structure should be 6 bytes. Let's take a look at the result.
Insert image description here
We found that the result is not 6 bytes and both are different. This is because the structure has memory alignment.

Rule:
Each compiler on a specific platform has its own default "alignment factor" (also called alignment modulus). Programmers can change this coefficient through the precompilation command #pragma pack(n), n=1,2,4,8,16, where n is the "alignment coefficient" you want to specify. The default coefficient on the vs compiler is 8.
1. Data member alignment rules: data members of the structure (struct), the first data member is placed at offset (offset) Where it is 0, each data member will be aligned according to the smaller value between the value specified by the alignment coefficient and the length of the data member itself. For example, the current offset is 18, and the data type to be allocated occupies 4 bytes, which is smaller than 8 (vs the default alignment number)
Then this time the number of pairs should be 4, we The starting point of the memory allocated to this data type must be a multiple of 4. 18 is obviously not a multiple of 4, so we have to find 19 later and come to 20. 20 is a multiple of 4, so the space allocated for this data type It’s the space between 20-24.
Insert image description here

2. Overall alignment rules of the structure: After the data members complete their respective alignments, the structure itself must also be aligned. The alignment will be based on the smaller of the value specified for its coefficient and the maximum data member length of the structure (or union). For example, after allocating the member's memory space, the offset at this time is 18, and the maximum data member is 4 bytes, which is smaller than 8, then 4 will be used as the overall alignment number, which means that the end of the memory must be A multiple of 4, 18 is obviously not a multiple of 4, then we will look back until we find 20. 20 bytes is the space allocated (i.e. size) of the structure.

So back to this question, based on this knowledge let us see why 8 and 12 are output.
First of all, the order in which we allocate space in s1 is to give a first and then b and then c. as the picture shows.
Insert image description here
First allocate a. A is a char type so it only occupies one byte. This value is smaller than the default alignment number, so 1 is the alignment coefficient this time. You can put it directly, then allocate b, the size is 1, you can put it directly again, and then c, which occupies 4 bytes, so the alignment number this time is 4, and the offset at this time is 2, not 4 is a multiple of, so we need to leave two spaces empty and go to the offset of 4 to fill in c. After filling in, the overall offset is 8. The overall pair number at this time is 4, and 8 is a multiple of 4. So s1 is allocated 8 bytes of space.
Then let’s look at s2 again.
Insert image description here
First, a is assigned a byte, and then it is the turn of c. The size of c is 4, which is smaller than 8, so 4 is the alignment number at this time, and the offset at this time is 1. Obviously, that It is not a multiple of 4, so it is moved back to 4, and then allocated to c4 bytes of space. The offset after the allocation is 8, and then starts to be allocated to b. The size of b is 1, and the alignment number is 1 at this time. You can directly allocate b. After the allocation, the offset at this time is 9. Start the overall alignment. The largest size in abc is c, 4 bytes, smaller than 8, so 4 is the overall alignment number at this time, 9 Obviously it is not a multiple of 4, so we have to move the offset back to stop at 12, and then 12 is the memory size allocated by s2.

Alignment reasons
1. Platform reasons (transplantation reasons): Not all hardware platforms can access any data at any address; some hardware platforms can only access certain data on certain addresses. Get certain types of data at the address, otherwise a hardware exception is thrown.
2. Performance reasons: Data structures (especially stacks) should be aligned on natural boundaries as much as possible. The reason is that in order to access unaligned memory, the processor needs to make two memory accesses; aligned memory access requires only one access.
Generally speaking: The memory object of the structure is to trade space for time.

4. Ending

We will leave the rest of the structure knowledge to the next blog, be sure to remember to learn it~
If you think the blogger’s lecture is good, please give the blogger a free follow. Like and collect it! See you next time. Click me for the next link!

Guess you like

Origin blog.csdn.net/Tokai___Teio/article/details/134773286