Structures, unions and enumerations

1. Structure

Definition: The structure is a new data type composed of a batch of data. Each data that composes structured data is called a "member" of structured data.

1.1 Declaration of structure type

For example, below I declare a student structure type to
describe the student: attribute-name + phone + gender + age

struct Stu
{
    
    
	 char name[20];	//名字
	 short age;		//年龄
	 char sex[5];	//性别
	 char id[20];	//学号
};//这里的分号不能丢
struct stu s1;   //全局变量
int main()
{
    
    
	//创建的结构体局部变量
	struct stu s1;
	system("pause");
	return 0;
}

1.2 Definition and initialization of structure variables

struct Stu        	//类型声明
{
    
    
	 char name[20];		//名字
	 int age;     	 	//年龄
};
struct Stu s = {
    
    "lisi", 19};//初始化
/*也可以采用如下初始化
s.name="lisi";
s.age=19;
*/

Structure nested structure

struct Point
{
    
    
	 int x;
	 int y;
}p1;		//声明类型的同时定义变量p1

struct Node
{
    
    
	 int data;
	 struct Point p;
	 struct Node* next; 
}n1 = {
    
    15, {
    
    32}NULL};		//结构体嵌套初始化

struct Node n2 = {
    
    11, {
    
    3, 2}, NULL};//结构体嵌套初始化

1.3 Structure memory alignment

In the above study, we have mastered the basic use of structure.
Now we discuss a question in depth: how to calculate the size of the structure?
This involves a particularly popular test point: structure memory alignment.

So why is there structure memory alignment? What is the meaning of structure memory alignment?

  1. Platform reason (transplant reason): Not all hardware platforms can access any data at any address; some hardware platforms can only fetch certain types of data at certain addresses, otherwise a hardware exception 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 unaligned memory, the processor needs to make two memory accesses; while aligned memory access only requires one access. In
    general:

The memory alignment of the structure is the practice of trading space for time.
When designing the structure, we must not only satisfy the alignment, but also save space.
How to do it: Just put the small memory variables in front, and let the members with small space be concentrated as much as possible.

How to calculate? First, you have to master the alignment rules of the structure:

The first member is stored at an address with an offset of 0 from the structure variable.
Other member variables 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 default alignment number and the member size.
The total size of the structure is an integer multiple of the maximum alignment number (each member variable has an alignment number).
If the structure is nested, the nested structure is aligned to an integer multiple of its own maximum alignment, and the overall size of the structure is an integer multiple of all maximum alignments (including the alignment of nested structures).
The default value of alignment in VS is 8

When we have mastered the calculation method, we will directly take the test

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

Insert picture description here
After running the code, I see that the structure of S1 is 12, so why is it equal to 12? Please see the analysis below
Insert picture description here

1.4 Structure parameter transfer

struct A
{
    
    
	int data[200];
	int num;
};
struct A a.num;
}
//结构体地址传参
void print2(struct A* ps)
{
    
    
	 printf("%d\n", ps->num);
}
int main()
{
    
    
	 print1(a);  //传结构体
	 print2(&a); //传地址
	 return 0;
}

Which of the above print1 and print2 functions 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 the structure is too large when passing a structure object, the system overhead of parameter stacking is relatively large, so it will cause performance degradation.
Conclusion: When the structure is passed, the address of the structure must be passed.

1.5 Structure realization bit segment

What is a bit segment:
The declaration and structure of a bit segment are similar, with two differences:
1. The members of a bit segment must be int, unsigned int, signed int or char.
2. There is a colon and a number after the member name of the bit segment.

As shown in the code below:

//位段
/*位段的声明和结构是类似的,有两个不同:
1.位段的成员必须是 int、unsigned int 或signed int 。
2.位段的成员名后边有一个冒号和一个数字。*/
#include<stdio.h>
#include<stdlib.h>
/*位段的内存分配
1. 位段的成员可以是 int unsigned int signed int 或者是 char (属于整形家族)类型
2. 位段的空间上是按照需要以4个字节( int )或者1个字节( char )的方式来开辟的。
3. 位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段。
*/
struct A				//	A是一个位段类型
{
    
    
	char _a : 3;		//_a----占3个比特位
	char  _b : 4;		//_b----占4个比特位
	char  _c : 5;		//_c----占5个比特位
	char  _d : 4;		//_d----占3个比特位
};
int main()
{
    
    
	printf("%d\n", sizeof(struct A));			//------------3
	struct A a={
    
    0};
	a._a=10;
	a._b=12;
	a._c=3;
	a._d=4;
	system("pause");
	return 0;
}

How was the space opened up? As shown below:
Insert picture description here

Cross-platform issues of position:

  1. It is uncertain whether the int bit field is treated as a signed number or an unsigned number.
  2. The number of largest bits in the bit segment cannot be determined. (The 16-bit machine has a maximum of 16, and the 32-bit machine has a maximum of 32, written as 27, which will cause problems on a 16-bit machine.
  3. The members of the bit segment are allocated from left to right in the memory, or the criteria for allocation from right to left have not been defined.
  4. When a structure contains two bit segments, and the second bit segment member is relatively large and cannot fit in the remaining bits of the first bit segment, it is uncertain whether to discard the remaining bits or use them. Summary: Compared with the structure, the bit segment can achieve the same effect, but it can save space very well, but there are cross-platform problems.

2. Enumeration

What is enumeration? Enumeration, as the name implies, enumerates one by one. List the possible values ​​one by one.
For example, in our real life: Monday to Sunday of a week are limited 7 days, which can be listed one by one.
The genders are: male, female, confidential, or they can be listed one by one.
There are 12 months in the month, and you can also list the colors one by one. Enumeration can be used here.

2.1 Definition of enumerated types

enum Color//颜色
{
    
    
	 RED,		//0
	GREEN,		//1
	 BLUE		//2
};

The content in {} is the possible value of enumeration type, also called enumeration constant. These possible values ​​are all valued, starting from 0 by default, and incrementing by 1 at a time. Of course, you can also assign initial values ​​when defining them. E.g:

#include<stdio.h>
enum color
{
    
    
	//枚举的可能取值---常量
	Red,
	Yellow=5,
	Blue
};
int main()
{
    
    
	enum Color clr = Blue;//只能拿枚举常量给枚举变量赋值,才不会出现类型的差异。
	//	clr = 7;-----error
	//					   各数值得大小如下
	//					  0		5		6
	printf("%d %d %d\n", Red, Yellow, Blue);
	//枚举类型的大小-----一个整形大小(4)
	printf("%d\n", sizeof(enum color));			//-----4
	return 0;
}

3. Consortium

3.1 Definition of Union Type

Definition of union type Union is also a special custom type. Variables defined by this type also contain a series of members. The characteristic is that these members share the same space (so union is also called union).

such as:

union un
{
    
    
	char c;
	int i;
};

3.2 Characteristics of Consortium Type

The characteristics of the
union : the members of the union share the same memory space. The size of such a union variable is at least the size of the largest member.

union Un 
{
    
     
	 int i; 
	 char c; 
}; 
union Un un; 
// 下面输出的结果是一样的吗?
int main()
{
    
    
	printf("%d\n", &(un.i)); 
	printf("%d\n", &(un.c)); 
	//下面输出的结果是什么?
	un.i = 0x11223344; 
	un.c = 0x55; 
	printf("%x\n", un.i);		//un.i==11223355
}

3.3 Calculation of the size of the consortium

#include<stdio.h>
union un
{
    
    
	char c;
	int i;
};
int main()
{
    
    
	//联合体大小的计算
	/*联合的大小至少是最大成员的大小。
	当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。*/
	printf("%d\n", sizeof(union un));			//-----4
	return 0;
}

Finally, we end this section with an interview question.

Topic: Determine the current computer's large and small storage

#include<stdio.h>

void check()
{
    
    
	union _un
	{
    
    
		int _b;
		char _ch;
	}un;
	un._b = 1;
	if (un._ch == 1)
	{
    
    
		printf("小端\n");

	}
	printf("大端\n");

}
int main()
{
    
    
	check();
	return 0;
}

Insert picture description here

Guess you like

Origin blog.csdn.net/weixin_47812603/article/details/114559365
Recommended