catalogue
1.2 special declaration: anonymous struct type
1.4 definition and initialization of structure variables
1.5 structure memory alignment
1.5.1 why is there memory alignment?
1.6 modify the default alignment number
1.8 structural transmission parameters
2.2 memory allocation of bit segment
2.3 cross platform problem of bit segment
1.2 use of enumeration constants
1.1 characteristics of the Consortium
1.3 calculation of consortium size
1, Structure
1.1 declaration of structure
//Declare a struct type //A structure is a collection of values called member variables. Each member of the structure can be a different type of variable. struct Book { char name[20]; char author[20]; int price; }b1,b2;//overall situation struct Book b3;//overall situation int main() { struct Book b4;//local variable return 0; }
1.2 special declaration: anonymous struct type
//Anonymous structure -- can only be used once struct //Structure labels are omitted { char a; int b; double c; }x;//Global variable, which will be destroyed at the end of the program
On the basis of the above code, declare a structure pointer p with the same members, then
p = &x; Is it legal?
struct { char a; int b; double c; }x;//Global variable, which will be destroyed at the end of the program struct { char a; int b; double c; }*p; int main() { p = &x;//The types from '*' to '*' are incompatible. They are two different types }
1.3 structure self reference
//Self reference of structure: include a member whose type is the structure itself in the structure struct Node { int data; struct Node* Next; }; typedef struct Node//The structure label node cannot be omitted { int data; struct Node* Next; } Node;
1.4 definition and initialization of structure variables
struct Point { int x; int y; }p3 = { 5,6 }, p4 = { 7,8 }; //Define variables P3 and P4 while declaring types struct Point p2 = { 1,2 };//Initialization: define variables and assign initial values at the same time struct S { double d; struct Point p;//The structure contains the structure char name[20]; char data[20]; }; int main() { struct Point p1 = { 3,4 }; struct S s = { 3.14,{3,4},"zhangsan",{1,2,3} };//Structure nesting initialization printf("%lf\n", s.d); printf("%d %d\n", s.p.x, s.p.y); printf("%s\n", s.name); int i = 0; for (i = 0;i < 20;i++) { printf("%d ",s.data[i]); } return 0; }
1.5 structure memory alignment
Illustration:
1.5.1 why is there memory alignment?
1. 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.
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 misaligned memory, the processor needs to make two memory accesses; Second aligned memory access requires only one access.
in general:
Memory alignment of structures is a method of trading space for time.
When designing the structure, we should not only meet the alignment, but also save space: let the members with small space gather together as much as possible
Summary: the members of S1 and S2 are the same, but the space occupied by S1 and S2 is different
1.6 modify the default alignment number
When the alignment is not appropriate, we can change the default alignment number, which is generally modified to the power of 2
1.7 offsetof:
Implementation of macro -- > calculate the offset of a variable in the structure relative to the first address
1.8 structural transmission parameters
struct S { int data[1000]; int num; }; void print(struct S tmp) { int i = 0; for (i = 0;i < 6;i++) { printf("%d ",tmp.data[i]); } printf("\nnum = %d\n",tmp.num); } void print1(const struct S* s1) { int i = 0; for (i = 0; i < 6; i++) { printf("%d ",(s1->data)[i]); } printf("\nnum = %d\n", s1->num); } int main() { struct S s = { {1,2,3,4,5,6},100 }; print(s);//pass by value print1(&s);//Address delivery return 0; }
Which of the above print and print1 functions is better?
print1 is preferred because the parameters need to be stacked when the function passes parameters, which will have system overhead in time and space.
If the structure is too large when passing a structure object, the system overhead of parameter stack pressing is relatively large, which will lead to performance degradation.
Conclusion: when the structure passes parameters, the address of the structure should be passed.
2.1 what is a bit segment
The declaration and structure of bit segments are similar, with two differences:
1. The member of the bit segment must be int, unsigned int or signed int.
2.2 memory allocation of bit segment
2.3 cross platform problem of bit segment
//enumeration constant enum Color //Enumeration type { Red,//Enumeration constant, whose size is fixed, is an integer variable with size bit 4B Green = 3, Blue }; int main() { //These enumeration constants start from 0 by default and increase by 1 at a time. They can also be given initial values when defined printf("%d\n",Red);//0 printf("%d\n", Green);//3 printf("%d\n", Blue);//4 return 0; }
//Usage: enum Color { Red = 2, Green = 3, Blue = 5 }; int main() { enum Color c = Green; //You can only assign values to enumeration variables with enumeration constants, so that there will be no type difference. if (c == Green) { printf("green\n");//green } return 0; }
2, Enumeration
1.1 advantages of enumeration
We can use #define to define constants. Why do we have to use enumeration?
Advantages of enumeration:
1. Increase the readability and maintainability of the code
2. Compared with #define defined identifiers, enumeration has type checking, which is more rigorous
3. Prevent naming pollution (packaging)
4. Enumeration can be debugged, but #define cannot be seen during debugging
5. It is easy to use, and multiple constants can be defined at one time
1.2 use of enumeration constants
//Use of enumerated constants: void menu() { printf("*****************************\n"); printf("****1.add 2.sub*************\n"); printf("****3.mul 4. div************\n"); printf("****0. exit **************\n"); } enum { exit,//0 add,//1 sub,//2 mul,//3 div//4 }; int main() { int input = 0; do { menu(); printf("Please select:>"); scanf("%d", &input); switch (input) { case add: break; case sub: break; case mul: break; case div: break; case exit: break; } } while(input); }
3, Consortium (Consortium)
1.1 characteristics of the Consortium
union Un { char c; int i; }; int main() { union Un u = {0}; printf("%d\n",sizeof(u));// 4 printf("%p\n",&u); //012FFE8C printf("%p\n", &(u.c));// 012FFE8C printf("%p\n", &(u.i)); //012FFE8C return 0; }
1.2} face to face questions
Determine the storage size of the current computer?
int main() { int a = 1; //Writing method 1: //0x 00 00 00 01 //01 00 00 small end storage //00 01 big end storage char* pc = (char*)&a; if (*pc == 1) { printf("Small end\n");//Small end } else { printf("Big end\n"); } //Writing method 2: in the form of consortium, the same space is shared, but the two variables cannot be used at the same time union U { char c; int i; }u; u.i = 1; if (u.c == 1) { printf("Small end\n");//Small end } else { printf("Big end\n"); } return 0; }
1.3 calculation of consortium size
1. The size of the consortium shall be at least the size of the largest member
2. When the 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
int main() { union Un1 { char c[5]; int i; }; union Un2 { short c[7]; int i; }; printf("%d\n", sizeof(union Un1)); //8 printf("%d\n", sizeof(union Un2)); //16 }
This article is the sorting of knowledge points of user-defined types: structure, enumeration and Consortium (common body). If there are errors, please comment more in the comment area. Ha, come on! 😄