Custom type (1): structure


1. Basic knowledge of structure

(1) Structure

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

(2) The declaration of the structure

The code is as follows (example):

struct tag//结构体的名称
{
    
    
	member - list1;//内部可以定义多个不同类型的成员变量
	member - list2;
	member - list3;
	//...
};

For example, use a structure to describe part of a student's information

The code is as follows (example):

struct student//用来描述学生的结构体
{
    
    
	//定义成员变量
	char name[10];
	int age;
	char telephone[20];
	char address[50];
}s1;//可以在这里直接创建变量
//这个结构体类型的名称是struct student而不是student

//通过struct student创建变量s2
struct student s2 = {
    
    "zhang san", 18, "123456789", "shang hai"};
//可以通过typedef来重新定义结构体的名称以简化代码
typedef struct student student
student s3;
//以上s1, s2, s3的三种创建变量的方式都是合法的

(3) Declaration of special structure

The code is as follows (example):

//匿名结构体
struct
{
    
    
	int a;
	char b;
	float c; 
}x;
struct
{
    
    
 	int a;
 	char b;
 	float c; 
 }
 a[20], *p;

The compiler will treat these two structure types as completely different types
. The declaration of this structure can only directly define variables here, and can only be used here

(4) Access to structure member variables

The code is as follows (example):

typedef struct birthday
{
    
    
	int year;
	int month;
	int day;
}birthday;

typedef struct student
{
    
    
	char name[10];
	int age;
	char telephone[20];
	char address[50];
	birthday b;
}student;
int main()
{
    
    
	student s1 = {
    
     "zhang san", 18, "123456789", "shang hai",
					 {
    
     2000, 1, 1 } };
	//结构体变量访问成员变量用.操作符			 
	printf("name:%s age:%d telephone:%s address:%s\nbirthday:%d.%d.%d\n",
		s1.name, s1.age, s1.telephone, s1.address, s1.b.year, s1.b.month, s1.b.day);
	//结构体指针访问成员变量用->操作符
	student* ps = &s1;
	printf("name:%s age:%d telephone:%s address:%s\nbirthday:%d.%d.%d\n",
		ps->name, ps->age, ps->telephone, ps->address, ps->b.year, ps->b.month, ps->b.day);
	return 0;
}

2. Self-reference of the structure

It is not allowed to include a member whose type is the structure itself.

Such as the following code is illegal

struct student
{
    
    
	char name[10];
	int age;
	char telephone[20];
	char address[50];
	struct student next;//不合法
};

The correct self-referencing method is as follows:

The code is as follows (example):

//可以在创建结构体时直接typedef
typedef struct student
{
    
    
	char name[10];
	int age;
	char telephone[20];
	char address[50];
	struct student* next;//通过指针找到下一个结构体变量
	//注意虽然外面已经typedef,但是这里不能写成student
}student;

It is allowed to include another type of structure inside the structure

The code is as follows (example):

typedef struct birthday
{
    
    
	int year;
	int month;
	int day;
}birthday;

typedef struct student
{
    
    
	char name[10];
	int age;
	char telephone[20];
	char address[50];
	birthday b;
}student;

student s1 = {
    
     "zhang san", 18, "123456789", 
					"shang hai", {
    
     2000, 1, 1 } };
								//注意初始化b时要再加一个大括号

2. Calculate the size of the structure

As a custom type, structure does not have the same fixed size as built-in types such as int and double. The following describes how to calculate the size of a structure type.

First of all, you must master the alignment rules of the structure:
(1) The first member is at the address with an offset of 0 from the structure variable.
(2) Other member variables should be aligned to addresses that are integral multiples of the alignment number.
The alignment number = the smaller value of the compiler default alignment number and the member size.
(The default value in VS is 8, and the default value in Linux is 4)
(The VS compiler is used in the following example)
(3) The total size of the structure is 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 maximum alignment, and the overall size of the structure is the maximum alignment (including the alignment of the nested structure) Integer multiples.

Here are a few examples of calculating the size of the structure

struct S1
{
    
    
	char c1;
	int i;
	char c2;
};


Calculate the size of struct s1


struct S2
{
    
    
	double d;
	char c;
	int i;
};

Insert picture description here
Calculate the size of struct s2

Due to the memory alignment of the structure, it is possible to save space as much as possible when designing the structure

//例如:
struct S1
{
    
    
	char c1;
	int i;
	char c2;
 };
struct S2
{
    
    
	char c1;
	char c2;
	int i;
};
//S1、S2的成员变量相同,但S2所占的空间小

3. Modify the default alignment number

The default alignment can be modified by the preprocessing directive #pragma pack()

The code is as follows (example):

#include <stdio.h>

#pragma pack(8)//设置默认对齐数为8
struct S1
{
    
    
	char c1;
	int i;
	char c2;
};
#pragma pack()//取消设置的默认对齐数,还原为默认

#pragma pack(1)//设置默认对齐数为1
struct S2
{
    
    
	char c1;
	int i;
	char c2;
};
#pragma pack()//取消设置的默认对齐数,还原为默认

int main()
{
    
    
    printf("%d\n", sizeof(struct S1));//12
    printf("%d\n", sizeof(struct S2));//6
    return 0; 
}

4. Structure parameter transfer

When the function passes parameters, the parameters need to be pushed onto the stack, which will cause system overhead in time and space.
If you pass a structure object, the structure is too large, and the system overhead of parameter stacking is relatively large, which will lead to a decrease in performance, so the structure address is generally passed when passing parameters.

The code is as follows (example):

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;
}

Thanks for reading, please criticize and correct any errors

Guess you like

Origin blog.csdn.net/weixin_51983604/article/details/115298310