# 1, Structure

## 1.1 basic knowledge of structure

Definition: a structure is a collection of values called member variables. Each member of the structure can be a different type of variable.

## 1.2 declaration of structure

Syntax:

```struct tag
{
member-list;
}variable-list;//Variable list can be omitted
```

## 1.3 special declaration

When declaring a structure, you can declare it incompletely

```//Anonymous structure type
struct
{
int a;
char b;
float c;
}x;
```

🔵 Features: can only be used once.
🔴 be careful:

```struct
{
int a;
char b;
float c;
}x;
struct
{
int a;
char b;
float c;
}a[20], * p;
int main()
{
//p = &x;// The err compiler treats the two declarations as different types
return 0;
}
```

## 1.4 self reference of structure

If a structure of the same type is also defined inside the structure, the value of sizeof (structure) will be infinite. To solve the above problem, we can define pointers to structures of the same type.

```struct Node//node
{
int data;//Data domain
struct Node* next;//Pointer field
};
```

🔴 Note: do not be anonymous when the structure is self referenced

```typedef struct
{
int data;
//Node* next;// The err anonymous structure is called node only after it is named, but it is obviously wrong to use node in the declaration
}Node;
```

## 1.5 definition, initialization and access of structure variables

```struct book
{
char name[20];
char author[20];
int price;
}b1 = { "xxx","xxx",12 };//Creation and initialization of global variables

struct book b2 = { "xxx","xxx",12 };//Creation and initialization of global variables
//There are structures in the structure
struct S
{
int x;
struct book b4;
};
int main()
{
struct book b3 = { "xxx","xxx",12 };//Creation and initialization of local variables
struct S s = { 1,{"xxx","xxx",12} };//The structure body contains the creation and initialization of the structure body
printf("%d\n", b1.price);
printf("%s\n", s.b4.author);
return 0;
}
```

## 1.6 structure memory alignment

```struct S1
{
char c1;
int i;
char c2;
};
struct S2
{
char c1;
char c2;
int i;
};
struct S3
{
double d;
char c;
int i;
};
//Structure nesting problem
struct S4
{
char c1;
struct S3 s3;
double d;
};
int main()
{
printf("%d\n", sizeof(struct S1));//？
printf("%d\n", sizeof(struct S2));//？
printf("%d\n", sizeof(struct S3));//？
printf("%d\n", sizeof(struct S4));//？
}

```

Rules for structure memory alignment:
① The first member of the structure is always placed at the beginning of the structure with an offset of 0.
② Structure members start with the second member and are always placed at an offset of an integer multiple of the alignment number. (alignment number: the smaller value between the compiler's default alignment number and the size of the variable itself. There is no default alignment number in Linux, and the default alignment number in VS is 8)
③ The total size of the structure must be an integral multiple of the largest number of alignments of each member.
④ Nesting exists. If a structure is nested, the nested structure is aligned to an integer multiple of its maximum alignment number, and the overall size of the structure is an integer multiple of all the maximum alignment numbers (including the alignment number of nested structures)

🔴 Note: the declaration of structure type does not occupy memory space. Only after the variable is created can the memory space be opened up

❗ Why memory alignment exists:

① Platform reason (migration reason): not all hardware platforms can access any data at any address; Some hardware platforms can only get certain types of data at certain addresses, otherwise hardware exceptions will be thrown.
② Performance reason: data structures (especially stacks) should be aligned on natural boundaries as much as possible. The reason is that in order to access misaligned memory, the processor needs to make two memory accesses; Aligned memory access requires only one access.

Summary: the memory alignment of structures is to exchange space for time.
Therefore, when designing the structure, we should not only meet the alignment, but also save space, so that the members with small space can be concentrated together as much as possible.

## 1.7 modify the default alignment number

When the alignment of the structure is inappropriate, we can change the default alignment number ourselves# The pragma preprocessing instruction can change our default alignment number.

```#pragma pack(8) / / set the default alignment number to 8
struct S1
{
char c1;// 1 8 1
int i;  // 4 8 4
char c2;// 1 8 1
}s1;
#pragma pack() / / unset the default alignment number and restore it to the default (8 in VS)

#pragma pack(1) / / set the default alignment number to 1
struct S2
{
char c1;//1 1 1
int i;  //4 1 1
char c2;//1 1 1
}s2;
#pragma pack() / / unset the default alignment number and restore it to the default

int main()
{
printf("%d\n", sizeof(s1));//12
printf("%d", sizeof(s2));//6
}
```

## 1.8 structural transmission parameters

There are two methods to transmit: ① transmit structure ② transmit address

```struct S
{
int data[1000];
int num;
};
struct S s = { {1,2,3,4}, 1000 };
//Structural transmission parameters
void print1(struct S s)
{
for (int i = 0; i < 4; i++)
{
printf("%d", s.data[i]);
}
printf("\n");
printf("%d\n", s.num);
}
//Structure address transfer parameter
void print2(struct S* ps)
{
for (int i = 0; i < 4; i++)
{
printf("%d", ps->data[i]);
}
printf("\n");
printf("%d\n", ps->num);
}
int main()
{
print1(s);  //Transmission structure
return 0;
}
```

🔴 Note: when transferring parameters to a function, the parameters need to be pressed on the stack, which will have system overhead in time and space.
If the structure is too large when passing a structure object, it will lead to performance degradation. Therefore, it is best to use the way of address transmission.
If you are afraid that the pointer will modify the data inside the structure, the solution can be protected with const

```//The structure address is passed to const protection
void print2(const struct S* ps)
{
for (int i = 0; i < 4; i++)
{
printf("%d", ps->data[i]);
}
printf("\n");
printf("%d\n", ps->num);
}
```

# 2, Enumeration

## 2.1 definition of enumeration type

🔵 characteristic:
① The constants inside {} are called enumeration constants
(constants include const modified constant variables, #define defined identifier constants, and enumeration constants)
② By default, it starts from 0 and increments by 1

```enum Day//week
{
Mon, //be careful! The tail is,
Tues,
Wed,
Thur,
Fri,
Sat,
Sun
};
int main()
{
printf("%d\n", Mon);//0
printf("%d\n", Tues);//1
return 0;
}
```
```//assignment
enum Color//colour
{
RED = 1,
GREEN = 2,
BLUE = 4
};
int main()
{

printf("%d\n", RED);//1
printf("%d\n", BLUE);//4
}
```

## 2.2 advantages of enumeration

① Increase the readability and maintainability of the code
② Compared with #define defined identifiers, enumeration has type checking, which is more rigorous# Define is a direct replacement, while enumeration is reserved.
③ Prevents naming contamination (encapsulation)
④ Easy to use, you can define multiple constants at a time

## 2.3 use of enumeration

```enum Color//colour
{
RED = 1,
GREEN = 2,
BLUE = 4
};
int main()
{
//In c + +, it is not considered that enum and int types do not match
//
//enum Color c1 = 2;
//if (c1 == GREEN)
//{
//	printf("green");
//}

enum Color c2 = GREEN;
if (c2 == GREEN)
{
printf("green");
}
}
```

# 3, United

## 3.1 definition of association type

🔵 Features: members share the same space

```//Declaration of union type
union Un
{
char c;//1
int i;//4
};
//Definition of joint variables
union Un un;

//Verify common space
int main()
{
printf("%p\n", &un);       //000DA13C
printf("%p\n", &(un.c));   //000DA13C
printf("%p\n", &(un.i));   //000DA13C
}
```

## 3.2 large and small end of consortium test

Other test methods

```int check()
{
union  UN
{
int i;
char c;
}un;
un.i = 1;
return un.c;
}
int main()
{
if (1 == check())
{
printf("Small end storage mode");
}
else
{
printf("Big end storage mode");
}
}
```

## 3.3 calculation of joint size

Calculation rule of union size:
① Union members share the same memory space, so the size of a union variable is at least the size of the largest member.
② When the maximum member size is not an integer multiple of the maximum alignment number, it should be aligned to an integer multiple of the maximum alignment number.

```//eg1
union Un
{
char c;//1 8 1
int i; //4 8 4
};
union Un un;
int main()
{
printf("%d\n", sizeof(un));//4
}
```
```//eg2
union Un1
{
char c[5];//1 8 1
int i;    //4 8 4
};
union Un2
{
short c[7];//2 8 2
int i;     //4 8 4
};
int main()
{
printf("%d\n", sizeof(union Un1));//Not 5, but 8
printf("%d\n", sizeof(union Un2));//    7     16
}
```

Tags: C C++

Posted on Sun, 10 Oct 2021 06:08:23 -0400 by thoand