This is the 28th day of my participation in the Gwen Challenge in November. Check out the details: The last Gwen Challenge in 2021.”

Custom type

The structure of the body

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

Declare a structure type

// Declare a student type to create a student variable (object) from the student type
// Describe the student must have attributes. Name, number, gender, age
struct Stu
{
    char name[20];/ / name
    char tele[12];/ / phone
    char sex[10];/ / gender
    int age;/ / age
};

struct Stu s3;// Create a global struct variable

int main(a)
{
    struct Stu s1;
    struct Stu s2;// Create a structure variable
	return 0;
}
Copy the code
image-20210913094556253


Special statement

When declaring a structure, you can declare it incompletely.

No structure tag

Anonymous structure type

Just to be clearThe anonymous structure is a typeThey don’t take up space, just like ints, they don’t create space until they create a variable, so there’s no such thing as destroying or destroying a type if it doesn’t take up space, there’s no such thing as destroying or destroying a type if it has space, so types are like drawings, variables are the real house to build

struct 
{
    char name[20];/ / name
    char tele[12];/ / phone
    char sex[10];/ / gender
    int age;/ / age
}stu;// Create a variable with a struct name. If you do not have a struct name, create a variable with a struct name
Copy the code

Anonymous structure pointer type

struct 
{
    char name[20];/ / name
    char tele[12];/ / phone
    char sex[10];/ / gender
    int age;/ / age
}* pstu;// Then the pstU becomes the anonymous structure pointer
Copy the code
image-20210917060233748


The structure is self-referencing

Is it ok to include a member in a structure whose type is the structure itself?

image-20210917061523191


So the Node comes out

One is the data and one is the address

struct Node
{
	int data;          / / data domain
	struct Node* next; / / pointer field
};
Copy the code

That’s when a structure references a variable of its own type and finds another object of the same type

Pay attention to

image-20210917063320647


A self-reference to a structure does not omit its own structure tag. Here is the solution

typedef struct Node
{
	int data;          / / data domain
	struct Node* next; / / pointer field
}Node;
Copy the code

Structure variable definition and initialization

struct Stu
{
    char name[20];/ / name
    char tele[12];/ / phone
    char sex[10];/ / gender
    int age;/ / age
};

struct Stu s3;// Create a global struct variable

int main(a)
{
    struct Stu s1 = {"zhuzhongyuan"."13151732661"."nan".22};// create struct s1 and initialize it
    printf("%s %s %s %d",s1.name,s1.tele,s1.sex,s1.age);
	return 0;
}
Copy the code
image-20210917084658329


Internal alignment of the structure

Now let’s dive into the problem of calculating the size of a structure.

This is also a particularly popular topic: internal alignment of structures

#include<stdio.h>
// Memory alignment
// There is alignment in the structure
struct S2
{
	int a;
	char b;
	char c;
};                        
struct S1
{
	char b;
	int a;
	char c;
};
int main(a)
{
	printf("%d\n".sizeof(struct S1));
	printf("%d\n".sizeof(struct S2));
	return 0;
}
Copy the code
image-20210917090210504


There are rules of alignment in the structure

  1. The first member of the structure is always placed at the offset 0 of the structure’s starting position
  2. Structure members start with the second member and are always placed at an integer multiple of the aligned number
  3. What are the alignment numbersIs the compiler’s default alignment number and smaller values of the variable’s own sizePay attention to theLinux has no default alignment number The default alignment number for VS is 8
  4. The total size of the structure must be an integer multiple of the largest alignment number for each member
  5. In the case of nested structures, the nested structure is aligned to an integer multiple of its own largest aligned number, and the overall size of the structure is an integer multiple of all the largest aligned numbers (including nested structures)
image-20210917093552942


image-20210917094041911


A few practice

image-20210917094956838


image-20210917101912669


Why is there memory alignment

1. Platform reasons (porting reasons)

Not all hardware platforms can access any data at any address, and some platforms can only access certain types of data at certain addresses or throw hardware exceptions

2. Performance reasons

Data structures (especially stacks) should be aligned on natural boundaries as much as possible because the processor needs to make two memory accesses to unaligned memory, whereas aligned accesses only need one

On the whole

The alignment of the structure is to take space in exchange for time, which is a waste of memory and a convenience

To solve

So when we design the structure, we need to satisfy the alignment, but also need to save space, how to do this: let the small space members as much as possible together.

image-20210917233228992


Change the default alignment number

The default alignment number for VS is 8

We can modify the default alignment number with #pragma pack()

image-20210917234827620


The default alignment is 2 to the power of something

Implementation of the offsetof macro

Computes the offset of a variable in a structure with respect to the head address

Offsetof original format
image-20210918054155802


image-20210918054846243


Structure parameter transfer

Value passed

image-20210918061503779


Address transfer

image-20210918063001860


How to choose

1. When passing parameters to a function, parameters need to be pushed, resulting in system overhead in time and space.

2. When passing a structure object, the structure is too large, and the system overhead of parameter pushing is relatively high, so it will lead to the performance decline.

Conclusion: When a structure passes a parameter, it passes the address of the structure.

A period of

What is a bit segment

A bit segment declaration is similar to a structure, with two differences

1. The member of the bit segment must be an int,unsiged int or signed int

2. Members of a bit segment are followed by a colon and a number

image-20210918065432943


image-20210918070011886


Bit segment memory allocation

  1. The members of a bit segment can be of type int, unsigned int, signed int, or char(which belongs to the integer family)
  2. The space of the bit segment is opened up as needed by 4 bytes (int) or 1 byte (char)
  3. Bits involve a lot of uncertainty and are not cross-platform, so applications that focus on portability should avoid using bits
image-20210918090139913


Cross-platform problems with bits

  1. It is uncertain whether an int bit segment is treated as a signed or unsigned number.
  2. The number of maximum bits in a bit segment is uncertain. (16 bit machine Max 16, 32 bit machine Max 32, write 27, 16 bit machine problem.
  3. Whether members of a bit segment are allocated in memory from left to right or from right to left is undefined.
  4. When a structure contains two bits and the second bit is too large to accommodate the remaining bits of the first bit, it is also uncertain whether to discard the remaining bits or use them.

Conclusion:

Compared to structure, bit segment can achieve the same effect and can save a lot of space, but there are cross-platform problems.

The application of bits

image-20210918091635663


The enumeration

Enumeration constants are incremented by default if we do not initialize them

We have four kinds of constants

1. Literal constants

2. A constant variable modified by const

3. Identifier constant defined by #

4. Enumerate constants

Here we’ll talk about enumerating constants

image-20210918094024475


Enumeration constants cannot be changed, only initialized

image-20210918094628627


So how does enumeration work

image-20210918095317933


Advantages of enumerations

Why use enumerations when we can use #define to define constants? Advantages of enumeration:

  1. Increases code readability and maintainability
  2. Enumerations are more rigorous in type checking than the identifiers defined by #define.
  3. Prevents naming contamination (encapsulation)
  4. Easy to debug


  5. Easy to use, you can define multiple constants at once

Simple calculator

#include<stdio.h>
enum Option
{
	exit,
	add,
	sub,
	mul,
	div
};
void menu(a)
{
	printf("*********************\n");
	printf("****1.add 2.sub****\n");
	printf("****3.mul 4.div****\n");
	printf("**** 0.exit ****\n");
	printf("*********************\n");
}

int main(a)
{
	int input = 0;
	int a = 0;
	int b = 0;
	int c = 0;
	do
	{
		menu();
		printf("Please select :>");
		scanf("%d",&input);
		printf("Please enter two operands :>");
		scanf("%d%d", &a, &b);
		switch (input)			
		{
		case add:
			c = a + b;
			printf("%d\n", c);
			break;
		case sub:
			c = a - b;
			printf("%d\n", c);
			break;
		case mul:
			c = a * b;
			printf("%d\n", c);
			break;
		case div:
			if (b == 0)
			{
				printf("The numerator cannot be 0\n.");
				break;
			}
			else
			{
				c = a / b;
				printf("%d\n", c);
				break;
			}			
		default:
			break; }}while (input);
	return 0;
}
Copy the code
image-20210918104241635


Union (common body)

Definition of the union type

A union is also a special custom type that defines a variable that also contains a list of members that share the same space (so unions are called Commons).

Union type declaration

image-20210918105430018


image-20210918105748187


image-20210918110608353


Characteristics of association

The members of the union share the same memory space, so the size of a union variable is at least the size of the largest member (because the union must be able to hold the largest member).

Determine the size side storage of the current machine

We learned one way before

#include<stdio.h>
int main(a)
{
	int a = 1; //0x 00 00 00 01
	/ / low -- -- -- -- -- -- -- -- -- -- -- -- -- > high
	//01 00 00 00 Small - end storage
	//00 00 00 01 Big-endian storage
	// get the first byte of a
	char* pc = (char*)&a;
	if (*pc == 1)
	{
		printf("Small end storage");
	}
	else
	{
		printf("Big endian");
	}
	return 0;
}
Copy the code
image-20210918111603326


Now learning Commons is taking advantage of his special situation

#include<stdio.h>
union Un
{
	char c;
	int i;
};
int main(a)
{
	union Un u = { 0 };
	u.i = 1;
	if (u.c == 1)
	{
		printf("Small end storage");
	}
	else
	{
		printf("Big endian");
	}
	return 0;
}
Copy the code
image-20210918112419963


Calculation of union size

The size of the union is at least the size of the largest member. When the maximum member size is not an integer multiple of the maximum aligned number, align to an integer multiple of the maximum aligned number.

image-20210918122833572