Detailed explanation of C language structure types


Preface

A structure is a collection of values ​​called member variables. Each member of the structure can be a variable of different types.


1. Declaration of structure

struct tag
{
    
    
    member - list;//成员列表
}variable - list;//变量列表
//变量列表可以省略

For example, describe a student:

struct Stu
{
    
    
	char name[20];//名字
	int age;//年龄
	char sex[5];//性别
	char id[20];//学号
}; //分号不能丢

2.Special statement

can be incompletely declared when declaring a structure.
For example:

//匿名结构体
struct
{
    
    
	int a;
	char b;
	float c;
}x;
struct
{
    
    
	int a;
	char b;
	float c;
}a[20], * p;
//上面的两个结构在声明的时候省略掉了结构体标签(tag)。
//在上面代码的基础上,下面的代码合法吗?
p = &x;

Warning:
Although the members of these two anonymous structures are the same, the compiler will treat the above two declarations as two completely different types! So it's illegal.


3. Self-reference of structure

Is it okay to include a member in a structure that is of type the structure itself?

//代码1
struct Node
{
    
    
	int data;
	struct Node next;
};
//可行否?
//你会发现,这个结构体将会不知道自己有多大

Correct way to self-reference:

struct Node
{
    
    
	int data;
	struct Node* next;
};

Let’s look at another error case:

//代码3
typedef struct//typedf是类型重命名
{
    
    
	int data;
	Node* next;
}Node;
//这样写代码,可行否?
//不行,重命名都还没有结束,你已经都用了
//解决方案:
typedef struct Node
{
    
    
	int data;
	struct Node* next;
}Node;

4. Definition and initialization of structure variables

struct Stu//类型声明
{
    
    
	char name[15];//名字
	int age;      //年龄
};
struct Point
{
    
    
	int x;
	int y;
}p1; //声明类型的同时定义变量p1
struct Point p2; //定义结构体变量p2
struct Point p3 = {
    
     x, y };//初始化:定义变量的同时赋初值。
struct Stu s = {
    
     "zhangsan", 20 };//初始化
struct Node
{
    
    
	int data;
	struct Point p;
	struct Node* next;
}n1 = {
    
     10, {
    
    4,5}, NULL }; //结构体嵌套初始化
struct Node n2 = {
    
     20, {
    
    5, 6}, NULL };//结构体嵌套初始化

5. Structure memory alignment

We have mastered the basic use of structures.
Now let’s discuss a problem in depth: calculating the size of a structure.

Insert image description here
How to calculate ?
First, you must master the alignment rules of the structure:

  1. The first member is at offset 0 from the structure variable.
  2. Other member variables should be aligned to addresses that are integer multiples of a certain number (alignment number).
    Alignment number = The smaller of the compiler's default alignment number and the size of the member.
    The default value in the compiler VS shown in the picture is 8
  3. The total size of the structure is an integer multiple of the maximum alignment number (each member variable has an alignment number).
  4. If the structure is nested, the nested structure is aligned to an integer multiple of its own maximum alignment number, and the overall size of the structure
    is the maximum alignment of all An integer multiple of the number (including the alignment number of nested structures).

Why does memory alignment exist?
Most of the reference materials say this:

  1. Platform reasons (transplantation reasons):
    Not all hardware platforms can access any data at any address; some hardware platforms can only fetch certain data at certain addresses. Some specific types of data, otherwise a hardware exception is thrown.
  2. Performance reasons:
    Data structures (especially stacks) should be aligned on natural boundaries whenever 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.

When designing a structure, we must not only satisfy alignment but also save space. How to do this:

Keep members who take up less space together as much as possible.

//例如:
struct S1
{
    
    
	char c1;
	int i;
	char c2;
};
struct S2
{
    
    
	char c1;
	char c2;
	int i;
};

6. Structure parameter passing

Go directly to the code:

struct S
{
    
    
	int data[1000];
	int num;
};
struct S s = {
    
     {
    
    1,2,3,4}, 1000 };
//结构体传参
void print1(struct S s)
{
    
    
	printf("%d\n", s.num);
}
//结构体地址传参
void print2(struct S* ps)
{
    
    
	printf("%d\n", ps->num);
}
int main()
{
    
    
	print1(s);  //传结构体
	print2(&s); //传地址
	return 0;
}

Which of the print1 and print2 functions above is better?
The answer is: the print2 function is preferred.
Reason:

When the function passes parameters, the parameters need to be pushed onto the stack, which will cause system overhead in time and space.
If a structure object is passed and the structure is too large, the system overhead of pushing parameters onto the stack will be relatively large, which will lead to a decrease in performance.

Conclusion:
When passing parameters to a structure, the address of the structure must be passed.


Summarize

The above is the content of the structure that I will talk about today. This article only briefly introduces the structure types and their precautions. Let’s learn together, make progress together, and work hard together! ! !

Guess you like

Origin blog.csdn.net/weixin_61661271/article/details/123991009