Structure, énumération, points de connaissance communs

Structure: une collection d'éléments de types identiques ou différents.

La structure est également un type.
La structure ne peut être définie que lorsqu'elle est initialisée, pas sous forme d'affectation. Si vous souhaitez opérer, vous pouvez ·utiliser des opérateurs.
Il en va de même pour les tableaux, si vous souhaitez attribuer des valeurs, vous pouvez utiliser des boucles.

struct stu {
	char name[20];
	char sex[5];
	int age;
	char number[10];
};

Il n'est pas permis d'être vide dans la structure (exigence standard C). Les mots vides n'ont aucune signification pratique.

Les membres de la structure peuvent être des scalaires, des tableaux, des pointeurs et d'autres structures.

1. Accès des membres dans la structure:

  1. Les variables de structure accèdent aux membres et les membres des variables de structure sont accessibles via des ·opérateurs. Tel que:
struct stu {
	char name[20];
	char sex[5];
	int age;
	char number[10];
};

int main()
{
	struct stu s;
	s.age = 20;
	return 0;
}
  1. Le pointeur de structure accède au membre qui pointe vers la variable, le pointeur vers la structure.
struct stu {
	char name[20];
	char sex[5];
	int age;
	char number[10];
};

int main()
{
	struct stu s = {"小花","女",18,"192001"};
	struct stu *p = &s;
	printf("姓名:%s\n性别:%s\n年龄:%d\n学号:%s\n", p->name, p->sex, p->age, p->number);
	return 0;
}

Utilisez les ->opérateurs pour accéder.
 
 
 
2. Transfert des paramètres de structure

Lorsque les paramètres de la structure sont passés, les paramètres doivent être poussés sur la pile (instanciation formelle des paramètres), la structure n'a pas de "dégénérescence, réduction de dimensionnalité" et d'autres problèmes, et le problème de copie papier correspondant se produira. En conséquence, l'efficacité est très faible (la surcharge du système est importante et les performances sont réduites). Il est généralement recommandé d'utiliser des pointeurs de structure.

Même s'il y a des tableaux dans la structure, la réduction de dimensionnalité ne se produira pas, et tous sont des copies papier.

 
Le fait que le type de structure soit le même dépend s'il s'agit de la même variable de structure. Même si les variables membres des deux structures sont exactement les mêmes, ce sont deux structures.
Par exemple:

struct {
	char name[20];
	char sex[5];
	int age;
	char number[10];
}x;
struct {
	char name[20];
	char sex[5];
	int age;
	char number[10];
}*p;

int main()
{
	p = &x;
	return 0;
}

Le code ci-dessus peut s'exécuter une fois compilé, mais il y aura des avertissements.
 
 
 
3. Auto-référence de la structure: la structure contient un membre dont le type est la structure elle-même.

struct Node
{
	int data;
	//struct Node next;//这是一种错误的自引用
	struct Node *next;
};

Regardez un autre code:

typedef struct Node  //①
{
	int data;
	struct Node *next;//②
}node;  //③

Cela struct Noderedéfinit. Parmi eux, les significations Node de ① et ② sont les mêmes, et ③ est différent des deux autres.

Par exemple, une telle redéfinition est erronée.

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

Le programme signalera une erreur:
Insérez la description de l'image ici
comme Node n'a pas terminé la redéfinition, il ne peut pas être utilisé en premier dans la structure.

 
 
 
4. Structure de l'alignement de la mémoire

Il y a un alignement de la mémoire à l'intérieur de la structure et l'alignement de la mémoire affectera la taille globale de la structure.
L'unité de base d'accès de l'ordinateur à la mémoire est l'octet, de sorte que l' ordinateur peut lire n'importe quel octet en mémoire à volonté . Cependant, en raison de la conception matérielle de l'ordinateur, lorsque l'ordinateur lit des données, il doit partir de la position de départ des exigences spécifiques.

 
 
①Pourquoi l'alignement de la mémoire?
En raison de la conception matérielle, l'efficacité devient faible. Si vous accédez à une mémoire qui n'est pas alignée sur la mémoire, le processeur effectuera plusieurs accès à la mémoire.
② Qu'est-ce que l'alignement de la mémoire?
Sacrifier l'espace mémoire pour répondre aux limitations du matériel d'accès à la mémoire du processeur et améliorer l'efficacité est appelé alignement de la mémoire.
L'essence de l'alignement de la mémoire: l'espace pour le temps.
③Comment aligner la mémoire:
les règles d'alignement de la mémoire:

1. Le décalage du premier membre par rapport à la variable de structure est 0.
2. Les autres variables membres doivent être alignées sur une adresse qui est un multiple entier d'un certain nombre (numéro d'alignement).
3. La taille totale de la structure est un multiple entier de l'alignement maximum (chaque variable membre a un alignement).
4. Dans le cas de structures imbriquées, la structure imbriquée est alignée sur un multiple entier de l'alignement maximal d'octets, et la taille globale de la structure est l'entier de tous les alignements maximum (y compris l'alignement des structures imbriquées) Fois.
Par exemple:

struct stu{  //42 +2   4 
	char name[20];//20
	char sex[5];//5
	int age;//  3  +  4
	char number[10];//10
};

int main()
{
	printf("%d", sizeof(struct stu));
	return 0;
}

une analyse:

char name[20];  大小为20 不需要对齐
char sex[5];    每一个元素大小为1字节,对齐数为1,可以整除  故大小为5
int age;  age为int型,对齐数为4,前面的字节数为25,不能整除,故有偏移量,偏移量为3
char number[10];每一个元素大小为1字节,对齐数为1,可以整除  故大小为10
上述总大小为:42。最大对齐数为:4.
不能整除4,故需进行扩大。为44

résultat:
Insérez la description de l'image ici

struct list  //32  最大对齐数:8  32
{
	char num[5];//5
	int add;// 3 +  4
	char *p;//4
	double prt;//8
	char opp;//1
	int div;// 3 + 4
};

int main()
{
	printf("%d\n", sizeof(struct list));
	return 0;
}

Insérez la description de l'image ici
Le cas de la structure imbriquée:

struct stu{  //50  最大对齐数:8   =  56
	char name[20];//20
	char sex[5];//5
	int age;//3 +  4
	double address;//8
	char number[10];//10
};

struct list  //81   最大对齐数:8   =  88  //这里的最大对齐数为什么是8?
{                                      //因为嵌套的结构体,最大对齐数为8,故,外部结构体最大对齐数也为8
	char num[5];//5
	int add;//  3  +  4
	char p;//1
	struct stu s;//3  +  56
	char opp;//1
	int div;// 3  +  4
	char mul;//1
};
int main()
{
	printf("%d\n", sizeof(struct stu));
	printf("%d\n", sizeof(struct list));
	return 0;
}

résultat:
Insérez la description de l'image ici

Bien entendu, le numéro d'alignement peut également être modifié.

#pragma pack()

Le numéro d'alignement par défaut peut être modifié.
Remarque: la valeur entre () doit être 1, 2, 4, 8, 16.
Comme le code ci-dessus: nous modifions le numéro d'alignement à 2:

#pragma pack(2)
struct list  
{
	char num[5];
	int add;
	char *p;
	double prt;
	char opp;
	int div;
};
int main()
{
	printf("%d\n", sizeof(struct list));
	return 0;
}

Le nombre d'octets a changé: 28.
Nous modifions le numéro d'alignement à 1:

#pragma pack(1)

Le nombre d'octets a changé: 26.
 
 
 
5. Segment de bit: la déclaration et la structure du segment de bit sont similaires, mais il existe des différences.

1. Les membres du champ de bits doivent être int, unsigned int et signed int
2. Le nom de membre du champ de bits est suivi de deux points et d'un nombre

struct A
{
	unsigned char a : 2;
	unsigned char b : 3;
	unsigned char c: 6;
	unsigned char d;
	unsigned char e : 4;
};
int main()
{
	printf("%d\n", sizeof(struct A));
	return 0;
}

Insérez la description de l'image ici
La taille en octets de ce code est donc de 4 octets.
Essayons cette mission.

int main()
{
	struct A s;
	s.a = 4;
	s.b = 5;
	s.c = 6;
	s.d = 7;
	s.e = 8;
	return 0;
}

Analyse:
Insérez la description de l'image ici
lorsqu'il s'agit d'un nombre signé, nous devons faire attention à ce qu'est le bit de signe du bit le plus élevé.

struct A
{
	char a : 2;
	char b : 3;
	char c: 6;
	char d;
	char e : 4;
};
int main()
{
	struct A s;
	s.a = 4;//100 发生截断00
	s.b = 5;//101 最高位为1,最后会原反补转换  结果为-3
	s.c = 6;//1100 
	s.d = 7;//1101
	s.e = 8;//1000  原反补转换  结果为-8
	printf("%d\n%d\n%d\n%d\n%d\n", s.a, s.b, s.c, s.d, s.e);
	return 0;
}

Insérez la description de l'image ici
Les segments peuvent obtenir un bon effet d'économie d'espace, mais il y a des problèmes avec la multiplate-forme.
L'ensemble du champ de bits peut prendre l'adresse, mais il ne peut pas être pris seul.

 
 
 
 
Énumération : la nature du type d'énumération est int, et la condition par défaut (peut être modifiée, à la fois positive et négative) commence à 0 et augmente séquentiellement.

L'énumération est un type et la vérification de type est effectuée lors de la compilation. Les macros sont basées sur le principe du remplacement et au cours de ce processus, aucune vérification n'est effectuée.

enum Day
{
	MON,
	TUES,
	WED,
	THUR,
	FRI,
	SAT,
	SUN
};//一般都习惯于大写。(默认为常量)

Avantages du dénombrement:

  1. Augmenter la lisibilité et la maintenabilité du code
  2. Par rapport aux identificateurs définis par macro, les énumérations ont une vérification de type et sont plus rigoureuses.

 
 
 
 
Union : Union est également un type personnalisé spécial, qui contient également une série de membres, mais ces membres partagent un espace.

La taille de l'union n'est pas la somme de tous les types.
D'une manière générale, la taille de l'union est déterminée par la taille du plus grand élément de l'union. Après la décision, tous les éléments partagent l'espace.
Lors de l'utilisation de l'union, un seul élément est accessible à la fois.
L'union devrait également prendre en compte le problème d'alignement de la mémoire. La taille finale de l'union devrait être capable de diviser le nombre maximum d'alignements dans l'union.

union un
{
	int i;
	char c[6];
};//该联合体字节大小为8

Les membres de l'union partagent un espace mémoire commun. La modification de la valeur d'un membre affectera la valeur suivante.
Il existe un exemple plus pratique: pour déterminer la taille de l'ordinateur actuel?

union un
{
	int i;
	char c;
};

union un temp;
temp.i = 1;
printf("%d\n", temp.c);

Sortie 0, stockage big-endian, sortie 1, stockage little-endian.

Je suppose que tu aimes

Origine blog.csdn.net/w903414/article/details/106922417
conseillé
Classement