Structure, enumeration, union

Keywords: C data structure list

structural morphology

Why does struct exist?

Computer is to solve people's problems. People know the natural world through "attributes".

The attribute set abstracted from anything can be used to represent a class of things and types. In this work, c, struct.

Declaration of structure type

struct tag
{
member_list;
}variable_list;

Special declaration (incomplete declaration is allowed when declaring the structure)

For example:

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

struct
{
  int  a;
  char b;
  float c;
}a[20],*p;
//Based on the above code, the following code is illegal
p=&x;

Warning: the compiler will treat the above two declarations as two completely different types. So it's illegal.

(as long as there are two structure types, even if the internal elements are the same, they are also different types.)

Self reference of structure (completed by pointer)

Why is there self reference? Variables should form a relationship.

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

Definition and initialization of structure variables:

struct Point
{
 int x;
 int y; }p1; //Define the variable p1 while declaring the type
struct Point p2; //Define structure variable p2
//Initialization: define variables and assign initial values at the same time.
struct Point p3 = {x, y};
struct Stu        //Type declaration
{
 char name[15];//name
 int age;      //Age
};
struct Stu s = {"zhangsan", 20};//initialization
struct Node
{
 int data;
 struct Point p;
 struct Node* next; 
}n1 = {10, {4,5}, NULL}; //Structure nesting initialization
struct Node n2 = {20, {5, 6}, NULL};//Structure nesting initialization

Structure memory alignment

Test site: how to calculate the size of the structure? First, you have to master the alignment rules of the structure

1. The address of the first member at the structure variable offset of 0.

(why doesn't the first member consider alignment?   0 / any number can be divided)

2. Other member variables except the first member shall be aligned to the address of the minimum integer multiple of a number (alignment number).

Number of alignments: its own size.

Minimum integer multiple = starting offset / number of alignments.

3. The total size of the structure is the minimum integer multiple of the maximum alignment number (each member has an alignment number).

Note: Although the first member does not participate in the alignment, he should participate in the comparison of the maximum alignment number.

4. If the structure contains a structure, the alignment number of the internal structure is its maximum alignment number;

If the structure contains an array, the first element is aligned and the other elements are aligned.

Why is there memory alignment?

1. Platform reason ( Reasons for transplantation ) :
Not all hardware platforms can access any data at any address; Some hardware platforms can only
Get some specific types of data at some addresses, otherwise throw a hardware exception.
2. Performance reasons :
data structure ( Especially stack ) It 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.
In general: the phenomenon of improving efficiency by spending space to reduce the number of accesses (memory alignment).
Why does struct talk about memory alignment? Struct may have a large number of different types of data.
Modify the default alignment number: #pragma pack (8) / / modify the default alignment number to 8
Structure transmission parameters:
Conclusion: when the structure passes parameters, it is necessary to pass the address of the structure (pointer is recommended).

Bit segment

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. The member name of the bit field is followed by a colon and a number.
struct A {
 int _a:2;
 int _b:5;
 int _c:10;
 int _d:30;
};
A Is a bit segment type.
That paragraph A What is the size of the?   eight
(if you open up a four byte space, there are 4 * 8 = 32 bits, and then a accounts for 2 bits, b for 5 bits, and c for 10 bits. If the space is not enough to accommodate d, you need another four bytes of space, and you open up a total of 8 bytes.)
Memory allocation for bit segments:
1. The members of the bit segment can be int unsigned int signed int Or char (belonging to plastic family)
2. The space of bit segments is opened up in the form of 4 bytes (int) or 1 byte (char) as needed.
3. Bit segments involve many uncertainties, Bit segments are not cross platform. Pay attention to portable programs and avoid using bit segments.
Note: in a byte and 8bit, is there a size end?? No,
        Which bits in a byte belong to high bits? uncertain!
//An example
struct S {
 char a:3;
 char b:4;
 char c:5;
 char d:4;
};
struct S s = {0};
s.a = 10;//01010
 s.b = 12; //01100
s.c = 3; //00011
s.d = 4;//00100
//How is space opened up?

As can be seen from the test results above, truncation occurs if the size of the binary storage exceeds the size assigned to you by the bit segment.

Cross platform problem of bit segment
1. int It is uncertain whether a bit segment is treated as a signed number or an unsigned number.
2. The number of the largest bits in the bit segment cannot be determined. ( 16 Bit machine Max 16 , 32 Bit machine Max 32 , written as 27 , in 16 Bit machine
There will be problems with the filter.
3. Whether members in the bit segment are allocated from left to right or from right to left in memory has not been defined.
4. When a structure contains two bit segments, and the member of the second bit segment is too large to accommodate the remaining bits of the first bit segment, yes
It is uncertain whether to discard the remaining bits or use them.
Summary:
Compared with the structure, bit segment can achieve the same effect, but it can save space, but there are cross platform problems.

enumeration

Definition of enumeration type

emun Day//week
{
	Mon,
	Tues,
	Wed,
	Thur,
	Fri,
	Sat,
	Sun
};
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. Prevents naming contamination (encapsulation)
4. Easy to debug
5. Easy to use, you can define multiple constants at a time
Use of enumeration:
enum Color//colour
{
 RED=1,
 GREEN=2,
 BLUE=4
};
enum Color clr = GREEN;//You can only assign values to enumeration variables with enumeration constants, so that there will be no type difference.
clr = 5;               //OK?? OK!!! Enumeration is essentially an integer

Consortium

Union is also a special user-defined type. The variables defined by this type also contain a series of members These members share the same space (therefore, a consortium is also called a community). For example:
//Declaration of union type
union Un
{
 char c;
 int i;
};
//Definition of joint variables
union Un un;
//Calculate the size of multiple variables
printf("%d\n", sizeof(un));

Characteristics of the joint:

Union members share the same memory space. The size of such a union variable is at least the size of the largest member (because
The union must at least be able to preserve the largest member).
union Un
{
 int i;
 char c;
};
union Un un;
// Are the output results the same? The same!!!!
printf("%p\n",&un);
printf("%d\n", &(un.i));
printf("%d\n", &(un.c));
//What is the output below?
un.i = 0x11223344;
un.c = 0x55;
printf("%x\n", un.i);

Interview questions:

Determine the size of the current computer:

#include<stdio.h>
#include<windows.h>
union Un{
	int i;
	char c;
};

int main()
{
	union Un un;
	un.i = 0x33221100;
	if (un.c ){
		printf("Big end\n");
	}
	else
		printf("Small end\n");
	system("pause");
	return 0;
}

Calculation of consortium size: (the third point of memory alignment shall be considered)

The size of the consortium 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.

union Un1
{
 char c[5];
 int i;
};
union Un2
{
 short c[7];
 int i;
};
//What is the output below?
printf("%d\n", sizeof(union Un1));//8
printf("%d\n", sizeof(union Un2));//16

Posted by LostKID on Sat, 30 Oct 2021 16:52:46 -0700