Custom structure type

Custom type: structure enumeration union
1. Declaration of structure type
2. Self-reference of
structure 3. Definition and initialization of
structure variable 4. Structure memory alignment
5. Structure parameter transfer
6. Structure realization bit segment (Position filling & portability)

1. Declaration of structure type

struct Tag
{
    
    
	member-list;
}variable-list;

2. The self-reference of the
structure The self-reference of the structure does not contain itself in its own structure, which is wrong. E.g

struct Node
{
    
    
	int date;
	struct Node next;
};
//这样的结构体是错的,你的每个struct Node里面都包含了一个int 和struct Node的类型,那么这个计算机得创建多大的空间才能够你使用呢?

Correct writing

struct Node
{
    
    
	int date;
	struct Node* next; // 这个所占的空间大小只是一个4/8个字节的
};

3. Definition and initialization of
structure variables Definition of structure variables

struct Stu
{
    
    
	char name[20];
	char tele[12];
	char sex[10];
	int age;
}s4,s5,s6; // 这里是变量列表
struct Stu s3;  // 这里创建的s3,s4,s5,s6 都是全局变量
int main()
{
    
    
	struct Stu s1;//其中s1,s2为局部变量
	struct Stu s2;
	return 0;
}

initialization

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', {
    
    78.8,30}, 20, 3.14, "zhangsan" };
	printf("%c  %lf %d %d %lf %s", s.c,s.st.weight,s.st.age, s.a, s.d, s.arr);
	return 0;
}

4. Structure memory alignment (a type of multiple-choice questions in the written test I like very much)
What is the result?
First of all, you should master the rules of structure alignment
1. The first member is at the address where the offset of the structure variable is 0

2. Other members should be aligned to an address that is an integer multiple of a certain number (alignment number)

Alignment number = the smaller value of the compiler's default alignment number and the member size. The default alignment number in the
VS compiler is 8 The
gcc compiler has no default alignment number, so the member size is its alignment number

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 maximum alignment, and the overall size of the structure is the integer of all maximum alignments (including the alignment of nested structures) Times

struct S1
{
    
    
	char c1;
	int a;
	char c2;
};    //12   

struct S2
{
    
    
	char c1;
	char c2;
	int a;
}; // 8

int main()
{
    
    
	struct S1 s1 = {
    
     0 };
	printf("%d\n", sizeof(s1));
	struct S2 s2 = {
    
     0 };
	printf("%d\n", sizeof(s2));
	return 0;
}

S1
Insert picture description here
S2
Insert picture description here
exercise
Calculate the size of the memory occupied by this structure.

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

The fourth of the rules: the case of nested structures in structures

struct S3
{
    
    
	double d;
	char c;
	int i;
};
struct S4
{
    
    
	char c1;
	struct S3 s3;
	double d;
};
int main()
{
    
    
	struct S4 s4 = {
    
     0 };
	printf("%d\n", sizeof(s4));
	return 0;
}
//结果32

So why is there memory alignment?
1. Platform reason (transplant reason): Not all hardware platforms can access any data at any address; some hardware platforms can only fetch specific types of data at certain addresses, otherwise hardware exceptions will occur.
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 the unaligned memory, the processor needs to make two memory accesses; while the aligned memory access only needs one access.

In general: the memory alignment of the structure is a practice of trading space for time.

So when designing the structure, we must not only meet the alignment, but also save space, how to do it:
let the members occupying a small space together as much as possible

Modify the default alignment number: #pragma this preprocessing directive

#pragma pack(4)  //  这样就可以修改掉原来的默认对齐数了,设置为4
struct S
{
    
    
	char c1; 
	// 原本中间会浪费掉7个字节的空间,但是现在修改完以后只会浪费掉3个字节
	double d; 
};
#pragma pack()  // 取消设置的默认对齐数

offsetof A macro used to find the offset

#include<stddef.h>
//size_t offsetof(structName,memberName);  声明
struct S
{
    
    
	char c;
	int i;
	double d;
};
int main()
{
    
    
	printf("%d\n", offsetof(struct S, c));
	printf("%d\n", offsetof(struct S, i));
	printf("%d\n", offsetof(struct S, d));
}

5. Structure parameter transfer

struct S
{
    
    
	int a;
	char c;
	double d;
};
void Init(struct S* ps)
{
    
    
	ps->a = 100;
	ps->c = 'd';
	ps->d = 3.14;
}
void Print1(struct S tmp)
{
    
    
	printf("%d\n", tmp.a);
	printf("%c\n", tmp.c);
	printf("%lf\n", tmp.d);
}  
void Print2(const struct S* ps)
{
    
    
	printf("%d\n", ps->a);
	printf("%c\n", ps->c);
	printf("%lf\n", ps->d);
}
int main()
{
    
    
	struct S s = {
    
     0 };
	Init(&s);
	Print1(s); // 因为这里我并不打算修改里面变量的内容,我只是想把它打印出来
	Print2(&s);
}

6. The structure realizes the bit segment (filling of the bit segment & portability)
What is the bit segment?
The declaration and structure of the bit segment are similar, with two differences:
1. The members of the bit segment must be int, unsigned int or signed int (preferably of the same type)
2. The member name of the bit segment is followed by a colon and
The purpose of using a number segment is to save space.

Memory allocation of the
bit segment 1. The members of the bit segment can be int unsigned int signed int or char (belonging to the integer family) type
2. The space of the bit segment is 4 bytes (int) or one byte ( char) method to develop
3. There are many uncertain factors in bit segment design, bit segment is not broken platform, and portable programs should avoid using bit segment.

struct S
{
    
    
	int a : 2;
	int b : 5;
	int c : 10;
	int d : 30;  // bit位不能超过32,也就是他的类型
};   //a占两个bit位,b占5个,c占10个bit为,这样一共占用了17个bit位,还剩下15个bit位,放不下30个bit位,
//所以剩下的30个bit位我需要重新开辟一个空间来放置,每次开辟是以int类型开辟的,32个字节,所以一共需要的是8个字节的空间
int main()
{
    
    
	struct S s;
	printf("%d\n", sizeof(s)); // 8个字节
	return 0;
}

Enumeration (as the name implies, enumerate one by one)
1. Definition of
enumeration 2. Advantages of
enumeration 3. Use of enumeration

//枚举的类型
enum Day
{
    
    
	//枚举的可能取值
	//枚举的默认值是从0开始的
	//但是当你不想要这个默认顺序的时候,可以给你的枚举常量进行初始化的赋值,改变其数值的大小
	Mon,  // 0
	Tues, // 1
	Wed,// 2
	Thur,// 3
	Fri,//4
	Sat,//5
	Sun//6
};
int main()
{
    
    
	enum Day s = Thur; // 这里的Thur必须是枚举里面所定义过的类型变量
	return 0;
}

The advantages of enumerations
We could have used #define to define constants. Why do we have to use enumerations?
1. Increase the readability and maintainability of the code.
2. Comparing with the written test defined by #define, the enumeration has type checking and is more rigorous
. 3. Put the name pollution
4. Easy to debug
5. Easy to use, multiple definitions can be made at one time The constant
switch-case statement is very suitable for matching with enumeration, increasing the readability of the code (for example, multiple functions in the address book)

Union
1. Definition of union type
Union is also a special custom type. The variables defined by this type also contain a series of members. The feature is that these members share a common space (so the union is also called a union-sharing the same space )

union Un
{
    
    
	char c;
	int i;
};// 这里你以为所占空间的大小会是5,错误的,是4。因为他们公用同一块空间,所以所占空间的大小是里面类型最大的空间
int main()
{
    
    
	union Un u;
	printf("%d\n", sizeof(u));
	
	
	printf("%p\n", &u);
	printf("%p\n", &(u.c));
	printf("%p\n", &(u.i));
	return 0;
}

Insert picture description here

2. The characteristics of the joint
sharing the same space, the smallest space should also be the largest size of the type inside.

3. Calculation of joint size
1. The size of the joint is at least the size of the largest member.
2. When the maximum member size is not an integral multiple of the maximum alignment, it must be aligned to an integral multiple of the maximum alignment.

union Un
{
    
    
	int a;
	char arr[5];  //拿类型来算最大对齐数
};

int main()
{
    
    
	union Un u;
	printf("%d\n", sizeof(u)); //结果为8   int大小是4个字节,整体的大小应该是里面最大成员的整数倍
	return 0;
}

Guess you like

Origin blog.csdn.net/MEANSWER/article/details/110228920