Tipo personalizado (1): estructura


1. Conocimientos básicos de estructura

(1) Estructura

Una estructura es una colección de valores, y estos valores se denominan variables miembro de estructura. Cada miembro de la estructura puede ser una variable de diferente tipo.

(2) La declaración de la estructura

El código es el siguiente (ejemplo):

struct tag//结构体的名称
{
    
    
	member - list1;//内部可以定义多个不同类型的成员变量
	member - list2;
	member - list3;
	//...
};

Por ejemplo, use una estructura para describir parte de la información de un estudiante.

El código es el siguiente (ejemplo):

struct student//用来描述学生的结构体
{
    
    
	//定义成员变量
	char name[10];
	int age;
	char telephone[20];
	char address[50];
}s1;//可以在这里直接创建变量
//这个结构体类型的名称是struct student而不是student

//通过struct student创建变量s2
struct student s2 = {
    
    "zhang san", 18, "123456789", "shang hai"};
//可以通过typedef来重新定义结构体的名称以简化代码
typedef struct student student
student s3;
//以上s1, s2, s3的三种创建变量的方式都是合法的

(3) Declaración de estructura especial

El código es el siguiente (ejemplo):

//匿名结构体
struct
{
    
    
	int a;
	char b;
	float c; 
}x;
struct
{
    
    
 	int a;
 	char b;
 	float c; 
 }
 a[20], *p;

El compilador tratará estos dos tipos de estructura como tipos completamente diferentes
. La declaración de esta estructura solo puede definir directamente variables aquí, y solo puede usarse aquí

(4) Acceso a las variables miembro de la estructura

El código es el siguiente (ejemplo):

typedef struct birthday
{
    
    
	int year;
	int month;
	int day;
}birthday;

typedef struct student
{
    
    
	char name[10];
	int age;
	char telephone[20];
	char address[50];
	birthday b;
}student;
int main()
{
    
    
	student s1 = {
    
     "zhang san", 18, "123456789", "shang hai",
					 {
    
     2000, 1, 1 } };
	//结构体变量访问成员变量用.操作符			 
	printf("name:%s age:%d telephone:%s address:%s\nbirthday:%d.%d.%d\n",
		s1.name, s1.age, s1.telephone, s1.address, s1.b.year, s1.b.month, s1.b.day);
	//结构体指针访问成员变量用->操作符
	student* ps = &s1;
	printf("name:%s age:%d telephone:%s address:%s\nbirthday:%d.%d.%d\n",
		ps->name, ps->age, ps->telephone, ps->address, ps->b.year, ps->b.month, ps->b.day);
	return 0;
}

2. Autorreferencia de la estructura

No se permite incluir un miembro cuyo tipo sea la propia estructura.

Como el siguiente código es ilegal

struct student
{
    
    
	char name[10];
	int age;
	char telephone[20];
	char address[50];
	struct student next;//不合法
};

El método de autorreferencia correcto es el siguiente:

El código es el siguiente (ejemplo):

//可以在创建结构体时直接typedef
typedef struct student
{
    
    
	char name[10];
	int age;
	char telephone[20];
	char address[50];
	struct student* next;//通过指针找到下一个结构体变量
	//注意虽然外面已经typedef,但是这里不能写成student
}student;

Se permite incluir otro tipo de estructura dentro de la estructura

El código es el siguiente (ejemplo):

typedef struct birthday
{
    
    
	int year;
	int month;
	int day;
}birthday;

typedef struct student
{
    
    
	char name[10];
	int age;
	char telephone[20];
	char address[50];
	birthday b;
}student;

student s1 = {
    
     "zhang san", 18, "123456789", 
					"shang hai", {
    
     2000, 1, 1 } };
								//注意初始化b时要再加一个大括号

2. Calcule el tamaño de la estructura.

Como tipo personalizado, la estructura no tiene el mismo tamaño fijo que los tipos integrados como int y double. A continuación se describe cómo calcular el tamaño de un tipo de estructura.

En primer lugar, debe dominar las reglas de alineación de la estructura:
(1) El primer miembro está en la dirección con un desplazamiento de 0 de la variable de estructura.
(2) Otras variables de miembro deben alinearse con direcciones que sean múltiplos enteros del número de alineación.
El número de alineación = el valor más pequeño del número de alineación predeterminado del compilador y el tamaño del miembro.
(El valor predeterminado en VS es 8 y el valor predeterminado en Linux es 4)
(El compilador VS se usa en el siguiente ejemplo)
(3) El tamaño total de la estructura es el número máximo de alineación (cada variable miembro tiene una alineación Número).
(4) Si la estructura está anidada, la estructura anidada se alinea con un múltiplo entero de su alineación máxima, y ​​el tamaño total de la estructura es la alineación máxima (incluida la alineación de la estructura anidada) Múltiplos enteros.

Aquí hay algunos ejemplos de cómo calcular el tamaño de la estructura.

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


Calcular el tamaño de la estructura s1


struct S2
{
    
    
	double d;
	char c;
	int i;
};

Inserte la descripción de la imagen aquí
Calcular el tamaño de la estructura s2

Debido a la alineación de memoria de la estructura, es posible ahorrar espacio tanto como sea posible al diseñar la estructura.

//例如:
struct S1
{
    
    
	char c1;
	int i;
	char c2;
 };
struct S2
{
    
    
	char c1;
	char c2;
	int i;
};
//S1、S2的成员变量相同,但S2所占的空间小

3. Modifique el número de alineación predeterminado

La alineación predeterminada se puede modificar mediante la directiva de preprocesamiento #pragma pack ()

El código es el siguiente (ejemplo):

#include <stdio.h>

#pragma pack(8)//设置默认对齐数为8
struct S1
{
    
    
	char c1;
	int i;
	char c2;
};
#pragma pack()//取消设置的默认对齐数,还原为默认

#pragma pack(1)//设置默认对齐数为1
struct S2
{
    
    
	char c1;
	int i;
	char c2;
};
#pragma pack()//取消设置的默认对齐数,还原为默认

int main()
{
    
    
    printf("%d\n", sizeof(struct S1));//12
    printf("%d\n", sizeof(struct S2));//6
    return 0; 
}

4. Transferencia de parámetros de estructura

Cuando la función pasa parámetros, los parámetros deben insertarse en la pila, lo que provocará una sobrecarga del sistema en el tiempo y el espacio.
Si pasa un objeto de estructura, la estructura es demasiado grande y la sobrecarga del sistema de apilamiento de parámetros es relativamente grande, lo que conducirá a una disminución en el rendimiento, por lo que la dirección de la estructura generalmente se pasa al pasar parámetros.

El código es el siguiente (ejemplo):

struct S 
{
    
    
	int data[1000];
	int num;
};
struct S s = {
    
     {
    
     1, 2, 3, 4 }, 1000 };

//结构体传参
void print1(struct S s) 
{
    
    
	printf("%d\n", s.num);
}

//结构体地址传参
void print2(struct S* ps) 
{
    
    
	printf("%d\n", ps->num);
}

int main()
{
    
    
	print1(s);//传结构体
	print2(&s);//传地址
	return 0;
}

Gracias por leer, critique y corrija cualquier error.

Supongo que te gusta

Origin blog.csdn.net/weixin_51983604/article/details/115298310
Recomendado
Clasificación