Structure, enumeration, joint knowledge points

Structure: A collection of elements with the same or different types.

Structure is also a type.
The structure can only be defined when it is initialized, not in the form of assignment. If you want to operate, you can ·use operators.
The same is true for arrays, if you want to assign values, you can use loops.

struct stu {
	char name[20];
	char sex[5];
	int age;
	char number[10];
};

It is not allowed to be empty in the structure (C standard requirement). Empty words have no practical meaning.

The members of the structure can be scalars, arrays, pointers, and other structures.

1. Member access in the structure:

  1. Structure variables access members, and the members of structure variables are accessed through ·operators. Such as:
struct stu {
	char name[20];
	char sex[5];
	int age;
	char number[10];
};

int main()
{
	struct stu s;
	s.age = 20;
	return 0;
}
  1. The structure pointer accesses the member that points to the variable, the pointer to the structure.
struct stu {
	char name[20];
	char sex[5];
	int age;
	char number[10];
};

int main()
{
	struct stu s = {"小花","女",18,"192001"};
	struct stu *p = &s;
	printf("姓名:%s\n性别:%s\n年龄:%d\n学号:%s\n", p->name, p->sex, p->age, p->number);
	return 0;
}

Use ->operators to access.
 
 
 
2. Structure parameter transfer

When the structure is passed, the parameters need to be pushed on the stack (formal parameter instantiation), and the structure does not have problems such as "degeneration and dimensionality reduction", and the corresponding hard copy problem will occur. As a result, the efficiency is very low (the system overhead is large and the performance is reduced). It is generally recommended to use structure pointers.

Even if there are arrays in the structure, dimensionality reduction will not occur, and all are hard copies.

 
Whether the type of the structure is the same depends on whether it is the same structure variable. Even if the member variables of the two structures are exactly the same, they are two structures.
E.g:

struct {
	char name[20];
	char sex[5];
	int age;
	char number[10];
}x;
struct {
	char name[20];
	char sex[5];
	int age;
	char number[10];
}*p;

int main()
{
	p = &x;
	return 0;
}

The above code can run when compiled, but there will be warnings.
 
 
 
3. Structure self-reference : The structure contains a member whose type is the structure itself.

struct Node
{
	int data;
	//struct Node next;//这是一种错误的自引用
	struct Node *next;
};

Look at another code:

typedef struct Node  //①
{
	int data;
	struct Node *next;//②
}node;  //③

This struct Noderedefines. Among them, the Node meanings of ① and ② are the same, and ③ is different from the other two.

For example, such a redefinition is wrong.

typedef struct
{
	int data;
	Node *next;
}Node;

The program will report an error:
Insert picture description here
because Node has not completed the redefinition, it cannot be used first in the structure.

 
 
 
4. Structure memory alignment

There is memory alignment inside the structure, and memory alignment will affect the overall size of the structure.
The basic unit of computer access to memory is byte, so computer can read any byte in memory at will . However, because of the hardware design of the computer, when the computer reads data, it must start from the starting position of the specific requirements.

 
 
①Why memory alignment?
Because of the hardware design, the efficiency becomes low. If you access memory that is not memory aligned, the processor will perform multiple memory accesses.
②What is memory alignment?
Sacrificing memory space to meet the limitations of cpu memory access hardware and improve efficiency is called memory alignment.
The essence of memory alignment: space for time.
③How to align memory:
the rules of memory alignment:

1. The offset of the first member from the structure variable is 0.
2. Other member variables should be aligned to an address that is an integer multiple of a certain number (alignment number).
3. The total size of the structure is an integer multiple of the maximum alignment (each member variable has an alignment).
4. In the case of nested structures, the nested structure is aligned to an integer multiple of the maximum alignment of bytes, and the overall size of the structure is the integer of all maximum alignments (including the alignment of nested structures) Times.
For example:

struct stu{  //42 +2   4 
	char name[20];//20
	char sex[5];//5
	int age;//  3  +  4
	char number[10];//10
};

int main()
{
	printf("%d", sizeof(struct stu));
	return 0;
}

analysis:

char name[20];  大小为20 不需要对齐
char sex[5];    每一个元素大小为1字节,对齐数为1,可以整除  故大小为5
int age;  age为int型,对齐数为4,前面的字节数为25,不能整除,故有偏移量,偏移量为3
char number[10];每一个元素大小为1字节,对齐数为1,可以整除  故大小为10
上述总大小为:42。最大对齐数为:4.
不能整除4,故需进行扩大。为44

result:
Insert picture description here

struct list  //32  最大对齐数:8  32
{
	char num[5];//5
	int add;// 3 +  4
	char *p;//4
	double prt;//8
	char opp;//1
	int div;// 3 + 4
};

int main()
{
	printf("%d\n", sizeof(struct list));
	return 0;
}

Insert picture description here
The case of nested structure:

struct stu{  //50  最大对齐数:8   =  56
	char name[20];//20
	char sex[5];//5
	int age;//3 +  4
	double address;//8
	char number[10];//10
};

struct list  //81   最大对齐数:8   =  88  //这里的最大对齐数为什么是8?
{                                      //因为嵌套的结构体,最大对齐数为8,故,外部结构体最大对齐数也为8
	char num[5];//5
	int add;//  3  +  4
	char p;//1
	struct stu s;//3  +  56
	char opp;//1
	int div;// 3  +  4
	char mul;//1
};
int main()
{
	printf("%d\n", sizeof(struct stu));
	printf("%d\n", sizeof(struct list));
	return 0;
}

result:
Insert picture description here

Of course, the alignment number can also be modified.

#pragma pack()

The default alignment number can be modified.
Note: The value in () must be 1, 2, 4, 8, 16.
Such as the above code: we modify the alignment number to 2:

#pragma pack(2)
struct list  
{
	char num[5];
	int add;
	char *p;
	double prt;
	char opp;
	int div;
};
int main()
{
	printf("%d\n", sizeof(struct list));
	return 0;
}

The number of bytes has changed: 28.
We modify the alignment number to 1:

#pragma pack(1)

The number of bytes has changed: 26.
 
 
 
5. Bit segment: The bit segment declaration and structure are similar, but there are differences.

1. The members of the bit field must be int, unsigned int and signed int
2. The member name of the bit field has a colon and a number after it

struct A
{
	unsigned char a : 2;
	unsigned char b : 3;
	unsigned char c: 6;
	unsigned char d;
	unsigned char e : 4;
};
int main()
{
	printf("%d\n", sizeof(struct A));
	return 0;
}

Insert picture description here
So the byte size of this code is 4 bytes.
Let's try this assignment.

int main()
{
	struct A s;
	s.a = 4;
	s.b = 5;
	s.c = 6;
	s.d = 7;
	s.e = 8;
	return 0;
}

Analysis:
Insert picture description here
When it is a signed number, we must pay attention to what the sign bit of the highest bit is.

struct A
{
	char a : 2;
	char b : 3;
	char c: 6;
	char d;
	char e : 4;
};
int main()
{
	struct A s;
	s.a = 4;//100 发生截断00
	s.b = 5;//101 最高位为1,最后会原反补转换  结果为-3
	s.c = 6;//1100 
	s.d = 7;//1101
	s.e = 8;//1000  原反补转换  结果为-8
	printf("%d\n%d\n%d\n%d\n%d\n", s.a, s.b, s.c, s.d, s.e);
	return 0;
}

Insert picture description here
Segments can achieve a good space saving effect, but there are problems with cross-platform.
The entire bit field can take the address, but it cannot be taken alone.

 
 
 
 
Enumeration : The nature of the enumeration type is int, and the default condition (can be changed, both positive and negative) starts from 0 and increases sequentially.

Enumeration is a type, and type checking is performed during compilation. Macros are based on the principle of replacement, and during this process, no checks are performed.

enum Day
{
	MON,
	TUES,
	WED,
	THUR,
	FRI,
	SAT,
	SUN
};//一般都习惯于大写。(默认为常量)

Advantages of enumeration:

  1. Increase code readability and maintainability
  2. Compared with macro-defined identifiers, enumerations have type checking and are more rigorous.

 
 
 
 
Union : Union is also a special custom type, which also contains a series of members, but these members share a space.

The size of the union is not the sum of all types.
Generally speaking, the size of the union is determined by the size of the largest element of the union. After the decision, all elements share space.
When using union, only one element is accessed at a time.
The union should also consider the memory alignment problem. The final size of the union should be able to divide the maximum number of alignments in the union.

union un
{
	int i;
	char c[6];
};//该联合体字节大小为8

The members of the union share a common memory space. Changing the value of a member will affect the subsequent value.
There is a more practical example: to determine the size of the current computer?

union un
{
	int i;
	char c;
};

union un temp;
temp.i = 1;
printf("%d\n", temp.c);

Output 0, big-endian storage, output 1, little-endian storage.

Guess you like

Origin blog.csdn.net/w903414/article/details/106922417