Personalization - custom type

Custom type

structural morphology

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

Declare a struct type

//Declaring a student type is to create a student variable (object) through the student type
//To describe a student, you have to have attributes or something. Name, phone number, gender, age
struct Stu
{
    char name[20];//name
    char tele[12];//Telephone
    char sex[10];//Gender
    int age;//Age
};

struct Stu s3;//Create global structure variable

int main()
{
    struct Stu s1;
    struct Stu s2;//Create structure variable
	return 0;
}

Special declaration

When declaring a structure, you can declare it incompletely.

No structure label

Anonymous structure type

To be clear, anonymous structures are types that do not occupy space, just like int. they will not open up space if they do not create a variable. Therefore, if the type does not occupy space, it will not be destroyed or not destroyed. Only when there is space, it will be destroyed or not destroyed. The type is like a drawing, and the variable is the real house to be built

struct 
{
    char name[20];//name
    char tele[12];//Telephone
    char sex[10];//Gender
    int age;//Age
}stu;//Directly connect the structure variable. When anonymous, create the variable later. Otherwise, you can't use this structure name later, because how to create a variable without a structure name

Anonymous structure pointer type

struct 
{
    char name[20];//name
    char tele[12];//Telephone
    char sex[10];//Gender
    int age;//Age
}* pstu;//At this point, pstu becomes an anonymous structure pointer

Structure self reference

Can a structure contain a member whose type is the structure itself?

So the node comes out

One represents data and one represents address

struct Node
{
	int data;          //Data domain
	struct Node* next; //Pointer field
};

This means that the structure finds another object of the same type by referencing a variable in its own type

be careful

Therefore, you cannot omit your own structure label for structure self reference. The following is the solution

typedef struct Node
{
	int data;          //Data domain
	struct Node* next; //Pointer field
}Node;

Definition and initialization of structure variables

struct Stu
{
    char name[20];//name
    char tele[12];//Telephone
    char sex[10];//Gender
    int age;//Age
};

struct Stu s3;//Create global structure variable

int main()
{
    struct Stu s1 = {"zhuzhongyuan","13151732661","nan",22};//(definition) create the structure variable s1 and initialize it
    printf("%s %s %s %d",s1.name,s1.tele,s1.sex,s1.age);
	return 0;
}

Structure memory alignment

Now let's delve into a problem: calculating the size of a structure.

This is also a particularly popular test point: structure memory alignment

#include<stdio.h>
//memory alignment 
//Structure memory alignment
struct S2
{
	int a;
	char b;
	char c;
};                        
struct S1
{
	char b;
	int a;
	char c;
};
int main()
{
	printf("%d\n", sizeof(struct S1));
	printf("%d\n", sizeof(struct S2));
	return 0;
}

Rules for structure memory alignment

  1. The first member of the structure is always placed at the beginning of the structure with an offset of 0
  2. The structure member starts from the second member and is always placed at an integer multiple of the alignment number
  3. What is the alignment number? It is the compiler's default alignment number and the smaller value of the variable's own size. Note that linux does not have a default alignment number
    The default alignment number under vs is 8
  4. The total size of the structure must be an integral multiple of the maximum number of alignments of each member
  5. If a structure is nested, the nested structure is aligned to an integer multiple of its maximum alignment number, and the overall size of the structure is an integer multiple of all the maximum alignment numbers (including the alignment number of nested structures)

Several exercises

Why is there memory alignment

1. Platform reason (migration reason)

Not all hardware platforms can access any data at any address. Some platforms can only access 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, because in order to access misaligned memory, the processor needs to make two memory accesses, while aligned access only needs one access

on the whole

Structure memory alignment is the practice of exchanging space for time. In image, it is a waste of memory for convenience

solve

When designing the structure, we should not only meet the alignment, but also save space. How to do this:
Let the members with small space gather together as much as possible.

Modify the default number of alignments

vs the default alignment number is 8

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

The default setting is the power of 2

Implementation of offsetof macro

Calculates the offset of a variable in the structure from the first address

offsetof original format

Structural transmission parameters

pass by value

Address transfer

How to choose

1. When transferring parameters to a function, the parameters need to be stacked, which will have system overhead in time and space.

2. 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.

Bit segment

What is a bit segment

The declaration of a bit segment is similar to that of a struct, with two differences

1. The member of the bit field must be int, unsigned int or signed int

2. The member of the bit field is followed by a colon and a number

Memory allocation for bit segments

  1. The members of the bit segment can be int, unsigned int, signed int, or char (belonging to the shaping 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 segment involves many uncertain factors. Bit segment is not cross platform. Pay attention to portable programs and avoid using bit segment

Cross platform problem of bit segment

  1. It is uncertain whether the int bit field 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 machines have a maximum of 16 and 32-bit machines have a maximum of 32, which is written as 27. Problems will occur on 16 bit machines.
  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, it is also uncertain whether to discard the remaining bits or use them.

Summary:

Compared with the structure, the bit segment can achieve the same effect and save space, but there are cross platform problems.

Application of bit segment

enumeration

If we do not initialize enumeration constants, they are incremented by one by default

There are four kinds of constants

1. Literal constant

2.const modified constant

3. # identifier constant defined by number

4. Enumeration constants

Here we will talk about enumeration constants

Enumeration constants cannot be changed. They can only be initialized

How does enumeration work

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. Prevents naming contamination (encapsulation)
  4. Easy to debugDefine is not allowed, because define is completely replaced. If you directly replace GREEN with 1 in the code, there will be no concept of GREEN in the code. It is completely replaced
  5. Easy to use, you can define multiple constants at a time

Clean Calculator Beta

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

int main()
{
	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("Molecule cannot be 0\n");
				break;
			}
			else
			{
				c = a / b;
				printf("%d\n", c);
				break;
			}			
		default:
			break;
		}
	} while (input);
	return 0;
}

Consortium

Definition of union type

Union is also a special user-defined type. The variables defined by this type also contain a series of members, which are characterized by the fact that these members share the same space (so
Consortium (also known as community).

Declaration of union type

Characteristics of joint

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 (because the union must be able to save the largest member at least)

Determine the size of the current machine

I learned a method before

#include<stdio.h>
int main()
{
	int a = 1; //0x 00 00 00 01
	//Low ----------- > High
	//01 00 00 small end storage
	//00 01 big end storage
	//Find a way to get the first byte of A
	char* pc = (char*)&a;
	if (*pc == 1)
	{
		printf("Small end storage");
	}
	else
	{
		printf("Big end storage");
	}
	return 0;
}

Now I've learned that the commune takes advantage of his special situation

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

Calculation of joint 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 alignment number, it should be aligned to an integer multiple of the maximum alignment number.

Tags: C C++

Posted by dude81 on Tue, 21 Sep 2021 13:39:05 +0530