当前位置:网站首页>Detailed explanation of type, user-defined type, preliminary understanding of structure

Detailed explanation of type, user-defined type, preliminary understanding of structure

2022-07-19 08:10:00 Qingfeng jade bone ( ω・)「 well

Catalog

Structure

Statement of structure

Special statement

Self reference of structure

Definition, initialization and use of structure variables

Structure memory alignment

computing method

analysis

Verification method

result

Why is there memory alignment  

Graphic analysis

Change the default alignment number

Before the change  

After modification

Structural parameters

Bit segment

What is a bit segment  

Bit segment memory allocation  

Bit segment analysis  

The cross platform problem of bit segment

Afterword


Structure

stay C Language in , Structure (struct) It means a data structure , yes C In language Composite data class

(aggregate data type) One kind of .. A structure can be declared as Variable 、 The pointer or Array etc. , To achieve a more complex data structure .. A structure is also a collection of elements , These elements are called members of the structure (member), And these members can be of different types , Members usually visit by name

Statement of structure

// Statement of structure 
struct Stu{
	// Relevant attributes of students 
	char name[20];
	int age;
	char sex;
}s1,s2;		// Created here s1、s2 Global variable 

int main() {

	struct Stu s3;	//s3 It's a local variable 

	return 0;
}

We can create the type first and create two global variables by the way s1、s2, You can also create local variables inside the function after the structure is created s3

Special statement

When you declare the structure , It can be stated incompletely

Anonymous struct type

struct                // No name
{
        int a;
        char b;
        float c;
}x;                        // This is defining a Anonymous struct type

This naming method can only be used once , Because there's no name , So it won't be used in the future , This method can only be used when this type is used only once

struct
{
    int a;
    char b;
    float c;
}x;


struct
{
    int a;
    char b;
    float c;
}a[20], * p;                // You can create a pointer to a structure , The type of pointer is the content defined above

int main() {        // When anonymous structures are used in this way, the compiler will warn

    p = &x;          // The compiler will treat the above two declarations as two completely different types , Even if their content is      

    return 0;                                                                           // Same . So this behavior is illegal
}

Self reference of structure

​// Self reference of structure 

struct Node
{
	int data;    // Data fields 

	struct Node* next;    // Pointer to the domain        // Find nodes of the same type through pointers 
};

Use nodes to connect them in series , Self reference of structure , You need to include a structure pointer of the same type

We can use typedef To rename the structure type , Since the simple code

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

In this way, when using this type in the future, you can directly Node s1 To create a structural variable ;

This method and struct Node s1 It is equivalent.

Definition, initialization and use of structure variables

// Structure variable definition and initialization 

#include<stdio.h>
struct Point
{
	int x;
	int y;
	char name[20];
}p1 = { 2,3,"zhangshan" };
// We can initialize directly after creating the structure type 

int main() {

	struct Point p2 = { 4,5,"lisi" };

	printf("%d %d %s\n", p1.x, p1.y, p1.name);
	printf("%d %d %s\n", p2.x, p2.y, p2.name);

	return 0;
}
// You can also create and initialize later 

Structure memory alignment

This is an examination site  

// Structure memory alignment 

#include<stdio.h>
// practice 1
struct S1

{
	char c1;
	int i;
	char c2;
};
// practice 2
struct S2
{
	char c1;
	char c2;
	int i;
};

int main() {

	printf("%d\n", sizeof(struct S1));
	printf("%d\n", sizeof(struct S2));

	return 0;
}

Let's first look at the result of this string of code

We will find that these two seem to be the same , There are two different results

computing method

First, you have to master the alignment rules of the structure :
1. The first member is offset from the structure variable by 0 The address of .
2. Other member variables are aligned to a number ( Align numbers ) An integral multiple of the address of .
     Align numbers = Compiler default alignment number And The size of the member Smaller value .
    VS The default value in is 8
3. The total size of the structure is the maximum number of alignments ( Each member variable has an alignment number ) Integer multiple .
4. If the structure is nested , The nested structure is aligned to an integral multiple of its maximum alignment , Structure of the       The overall size is the maximum number of alignments ( The number of alignments with nested structures ) Integer multiple .

analysis

Verification method

Here we can verify by offset , We make use of <stddef.h> Library functions in offsetof macro  

#include<stdio.h>
#include<stddef.h>
// practice 1
struct S1

{
	char c1;
	int i;
	char c2;
};

// practice 2
struct S2
{
	char c1;
	char c2;
	int i;
};

int main() {

	printf("%d\n", sizeof(struct S1));	//12
	printf("%d\n\n", sizeof(struct S2));	//8
	printf("%d\n", offsetof(struct S1,c1));
	printf("%d\n", offsetof(struct S1,i));
	printf("%d\n", offsetof(struct S1,c2));

	return 0;
}

result

Two exercises

// practice 3                                                                                                ---16
struct S3
{
    double d;
    char c;
    int i;
};
// practice 4- Structure nesting problem                                                                       ---32
struct S4
{
    char c1;
    struct S3 s3;
    double d;                        // When calculating the nested structure, you should carefully look at the fourth calculation method
}; 

Why is there memory alignment  

1. Platform reasons ( Reasons for transplantation )
    Not all hardware platforms can access any data on any address ; Some hardware platforms can only access certain types of data at certain addresses , Otherwise, a hardware exception will be thrown .
2. Performance reasons
    data structure ( Especially stacks ) It should be aligned as far as possible on the natural boundary .
    The reason lies in , To access unaligned memory , The processor needs to make two memory accesses ; The aligned memory access only needs one access .

On the whole : 

The memory alignment of the structure is Space In exchange for Time How to do it

Graphic analysis

When designing structures , We have to satisfy the alignment , And save space , Writing like this can be done

Let the members who occupy less space gather together as much as possible

// for example :
struct S1
{
 char c1;
 int i;
 char c2;
};

struct S2
{
 char c1;
 char c2;
 int i;
};

Change the default alignment number

Before the change  

// Change the default alignment number 

#include<stdio.h>
struct S
{
	int i;
	double d;
};

int main() {

	printf("%d\n", sizeof(struct S));        
	return 0;
}

result

After modification

// Change the default alignment number 

#include<stdio.h>
#pragma pack(4)
struct S
{
	int i;
	double d;
};
#pragma pack()

int main() {

	printf("%d\n", sizeof(struct S));
	return 0;
}

 

If you don't want to align numbers like this 4 Change to 1 That's it , However, the default alignment number is generally 2^x Easy for the compiler to read data

Structural parameters

// Structural parameters 
#include<stdio.h>
struct S
{
	int data[1000];
	int num;
};

void print1(struct S s)
{
	for (int i = 0; i < 3; i++)
	{
		printf("%d ", s.data[i]);
	}
	printf("%d\n", s.num);
}

void print2(const struct S* ps)    // prevent ps hold s changes 
{
	for (int i = 0; i < 3; i++)
	{
		printf("%d ", ps->data[i]);
	}
	printf("%d\n", ps->num);
}

int main() {
	struct S s = { {1,2,3},100 };
	print1(s);    // Pass value 
	print2(&s);   // Byref 

	return 0;
}

There are two methods of value transmission and address transmission , We usually use address transmission method  

reason :

         When a function passes parameters , The parameter is stack pressing , There will be time and space overhead .
If you pass a structure object , The structure is too large , The system overhead of parameter stack pressing is relatively large , So it can lead to performance degradation .

Bit segment

What is a bit segment  

The declaration and structure of a bit segment are similar , There are two differences :
1. The member of the segment must be intunsigned int or signed int .
2. The member name of the segment is followed by a colon and a number .

// Bit segment 

#include<stdio.h>   
struct A {
	int _a : 2;			// Let it only occupy 2 individual bit, The same goes for the following       // Sometimes we need a number to indicate true or false ,0 or 1
	int _b : 5;
	int _c : 10;        // The following number is the number of bytes reopened for it     // Then we only need one byte 
	int _d : 30;
};

//47bit
//6byte -- 48bit
//8byte -- 64bit

int main() {

	printf("%d\n", sizeof(struct A));	// The result is  8

	return 0;
}

  This method can save space to a certain extent

Bit segment memory allocation  

1. The members of a segment can be int unsigned int signed int Or is it char ( It belongs to the plastic family ) type
2. The space of the bit segment is based on 4 Bytes ( int ) perhaps 1 Bytes ( char ) The way to open up .
3. Bit segments involve many uncertainties , Bit segments are not cross platform , Pay attention to portable program should avoid using bit segment . 

Bit segment analysis  

// An example 

struct S {
	char a : 3;
	char b : 4;
	char c : 5;
	char d : 4;
};

int main() {

	struct S s = { 0 };
	s.a = 10; 
	s.b = 12; 
	s.c = 3; 
	s.d = 4;

	return 0;
}

The cross platform problem of bit segment

1. int It's 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 The machine is the largest 16,32 The machine is the largest 32, It's written in 27, stay 16 position        The machine will go wrong .
3. The members in the bit segment are allocated from left to right in memory , Or right to left allocation criteria have not yet been defined .vs Middle is from right to left
4. When a structure contains two bit segments , The second segment is relatively large , Cannot hold the remaining bits of the first bit segment ,      Whether to discard the remaining bits or to use , This is uncertain .
summary :
         Compared to the structure , Bit segments can achieve the same effect , But it can save a lot of space , But there are cross platform problems

Afterword

, I've been lazy recently

原网站

版权声明
本文为[Qingfeng jade bone ( ω・)「 well]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/200/202207170623002867.html