Custom data type

Keywords: C data structure

Structure (struct)

Definition of structure variables

#include<stdio.h>
#include<string.h>
#include<ctype.h>

struct MyStruct
{
	char name[20];
	int age;
}s4,s5,s6;//Create a global list of structure variables
//Create structure global variable
struct MyStruct s3;

//Anonymous structure
struct {
	int st;

}st;//Anonymous struct types must directly create more than one global struct variable list

//Anonymous structure pointer
struct {
	int st;
}* p;  //Note here that P = & ST will not alarm, because the computer thinks they are not of the same type
int main() {

	//Create structure local variables
	struct MyStruct s1;
	struct MyStruct s2;

	return 0;
}
#include<stdio.h>
#include<string.h>
#include<ctype.h>
typedef struct st {
	int ss;

}st;//typedef names the structure st 
int main() {
	//Define a structure
	struct st s1;
	st s2;
	return 0;
}

Structure self reference

#include<stdio.h>
#include<string.h>
#include<ctype.h>
//Similar linked list
struct MyStruct
{
	int a;
	struct MyStruct* next;
};
int main() {
	return 0;
}

Initialization and reading of structure variables

#include<stdio.h>
#include<string.h>
#include<ctype.h>
typedef struct st {
	int num;
	char arr[4];


}st;//typedef names the structure st 
int main() {
	//Define a structure
	struct st s1 = { 2,"we"};
	printf("%d %s \n",s1.num,s1.arr);
	st s2 = { 3,'e' };
	printf("%d %c \n", s2.num, s2.arr[0]);
	printf("%d %s \n", s2.num, s2.arr);
	return 0;
}

Structure memory alignment

When designing the structure, we try to gather the members with small space together as much as possible (less space is wasted in alignment)

Reasons for memory alignment

  • Platform reason: not all hardware platforms can access data at any address (for example, int type can only start reading on memory multiple of 4)

  • Performance problem the accessed data should be aligned on the natural boundary as much as possible. The reason is that in order to access the misaligned memory, the processor needs to access it twice, while the aligned memory only needs to be accessed once

    (for example, if a 32-bit machine transfers 4 bytes at a time, it needs to be read twice if it starts saving in the middle)

Calculation rules

  • The first member is at the address where the structure offset is 0

  • Other member variables should be aligned to the integer multiple address of a number (alignment number) (alignment number = the smaller value of the compiler's default alignment number and the size of the member vs the alignment number is 8. If there is no default alignment number, the size of the member is the alignment number. Modify the default alignment number to 4 #pragma pack(4) cancel #pragma pack())

  • The total size of the structure is an integer multiple of the maximum alignment number (each member variable has an alignment number)

  • A structure is nested in the structure. The nested structure is aligned to an integer multiple of its maximum alignment number. The total size of the structure is an integer multiple of the maximum alignment number (each member variable has an alignment number)

 < Pictures from the web >

 < Pictures from the web >   

Memory offset offsetof()

The offset of the structure member relative to the starting position of the structure

#include<stddef.h>

struct MyStruct
{
	char cc;
	int num;

};
int main() {
	printf("%d",offsetof(struct MyStruct, num));
	return 0;
}

Structural transmission parameters

#include<stdio.h>
#include<string.h>
#include<ctype.h>
//Write a method to initialize the structure variable
//Write a method to print structure variables
struct s
{
	int a;
	char c;
	double d;

};

void Init(struct s* ps) {
	ps->a = 100;
	ps->c = 'c';
	ps->d = 0.3;
}
//When the structure is too large, we do not recommend that the variable space of the transmission structure is too large to press the performance of the system
void print1(struct s ps) {
	printf("%d %c %lf \n", ps.a, ps.c, ps.d);
}

void print2(const struct s* ps) {
	printf("%d %c %lf \n", ps->a, ps->c, ps->d);
}
int main() {
	struct s s1 = {0};
	printf("%d %c %lf \n", s1.a, s1.c, s1.d);
	Init(&s1);
	print1(s1);
	print2(&s1);
	
	return 0;
}

Bit segment segment

The declaration of a bit segment is similar to that of a struct, but there are two differences

  • The member of the bit field must generally be signed int unsigned int

  • The member variable of the bit field will be followed by a colon and a number

  • The bit segment cannot cross platform (whether the shaping is signed or unsigned cannot be known, and the bit segment size of different bit machines is uncertain, etc.)

  • The bit segment space is opened up in the form of 4 bytes (int) or one byte (char)

  • The number after the bit field cannot be greater than 32

Bit segment actually knows the actual value range of each member variable of the structure, so as to allocate space with binary bit as the minimum unit

#include<stdio.h>
#include<string.h>
#include<ctype.h>

struct s
{
	int _a : 2;
	int _b : 5;
	int _c : 10;
	int _d : 30;

};
int main() {
	struct s s1;
	printf("%d",sizeof(s1));  // 2+5+10+30=47bit = 47/8=6 bytes (carry is required here) because it is of int type, it is developed according to 4 bytes. During development, if a space (4 bytes) cannot meet the needs of members (the size is not large enough), it will abandon this unused space (binary bits) to the next space (4 bytes), so 8 bytes are developed
	return 0;
}

 < Pictures from the web >

enumeration

Advantages of enumeration

  • Readability and maintainability

  • Compared with #define, type detection is more rigorous

  • Prevent naming pollution

  • Easy to debug

  • Easy to use

#include<stdio.h>
#include<string.h>
#include<ctype.h>

enum Sex
{
	MALE,  //0
	FEMALE,//1
	SECRET, //2
	Q = 20,//Assign initial value 20
	W //21
};
int main() {
	enum Sex s1 = MALE;
	printf("%d",sizeof(s1)); // 4
	return 0;
}

Common body (Consortium) union

Members of a community share a space. Members cannot be used at the same time

The common body size is at least the size of the maximum 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

For example, int i; Size 4 alignment number 4 standard alignment number 8 alignment number 4

char[5]; Size 5 alignment number 1 standard alignment number 8 alignment number 1

The actual consortium size is the minimum multiple of 4 8

#include<stdio.h>
#include<string.h>
#include<ctype.h>

union un
{
	char a;
	int i;
};
int main() {
	union un u1;
	printf("%d",sizeof(u1)); // 4
	return 0;
}
//Judge whether it is large-end storage or small-end storage
#include<stdio.h>
#include<string.h>
#include<ctype.h>

union MyUnion
{
	int i;
	char a;
};
int main() {
	union MyUnion u1;
	u1.i = 1;
	if (u1.a == '0') {
		printf("Big end");
	}
	else {
		printf("Small end");
	}

	return 0;
}

Posted by public-image on Sat, 11 Sep 2021 17:40:48 -0700