Estrutura de tipo personalizada detalhada
(Uma estrutura é uma coleção de valores, esses valores são chamados de variáveis de membro. Cada membro da estrutura pode ser uma variável de tipos diferentes.)
Declaração do tipo de estrutura
Por exemplo, descreva um aluno:
struct Stu
{
char name[20];//名字
int age;//年龄
char sex[5];//性别
char id[20];//学号
};//分号不能丢
Declaração especial: ao declarar a estrutura, você não pode declarar totalmente (omitir a tag da estrutura)
//匿名结构体类型
struct
{
int a;
char b;
float c; }x;
struct
{
int a;
char b;
float c; }a[20], *p;
Estrutura de auto-referência (auto-referência correta é melhor adicionar um ponteiro)
struct Node
{
int data;
struct Node* next;
};
Definição e inicialização de variáveis de estrutura
struct Point
{
int x;
int y; }p1; //声明类型的同时定义变量p1
struct Point p2; //定义结构体变量p2
//初始化:定义变量的同时赋初值。
struct Point p3 = {
x, y};
struct Stu //类型声明
{
char name[15];//名字
int age; //年龄
};
struct Stu s = {
"zhangsan", 20};//初始化
struct Node
{
int data;
struct Point p;
struct Node* next;
}n1 = {
10, {
4,5}, NULL}; //结构体嵌套初始化
struct Node n2 = {
20, {
5, 6}, NULL};//结构体嵌套初始化
Alinhamento de memória de estrutura
Calcule principalmente o tamanho da estrutura ( site de teste popular ):
Primeiro, você deve dominar as regras de alinhamento da estrutura:
- O primeiro membro está em um endereço com deslocamento de 0 da variável de estrutura.
- Outras variáveis de membro devem ser alinhadas a um endereço que é um múltiplo inteiro de um certo número (número de alinhamento).
Número de alinhamento = o menor valor do número de alinhamento padrão do compilador e o tamanho do membro.
O valor padrão no VS é 8 - O tamanho total da estrutura é um múltiplo inteiro do alinhamento máximo (cada variável de membro tem um alinhamento).
- Se a estrutura for aninhada, a estrutura aninhada é alinhada a um múltiplo inteiro de seu alinhamento máximo e o tamanho geral da estrutura é um múltiplo inteiro de todos os alinhamentos máximos (incluindo o alinhamento de estruturas aninhadas).
//练习1
struct S1
{
字节 默认值 较小值
char c1; 1 8 1
int i; 4 8 4
char c2; 1 8 1
};
int main()
{
printf("%d\n", sizeof(struct S1));
}
Resultados da execução
Nota:
Por que há alinhamento de memória?
A maioria dos materiais de referência diz o seguinte:
- Motivo da plataforma (motivo do transplante): Nem todas as plataformas de hardware podem acessar quaisquer dados em qualquer endereço; algumas plataformas de hardware só podem
buscar certos tipos de dados em determinados endereços, caso contrário, uma exceção de hardware será lançada. - Razões de desempenho: Estruturas de dados (especialmente pilhas) devem ser alinhadas em limites naturais tanto quanto possível. A razão é que, para acessar a
memória não alinhada , o processador precisa fazer dois acessos à memória, enquanto o acesso alinhado à memória requer apenas um acesso.
Em geral:
o alinhamento da memória da estrutura é uma prática de troca de espaço por tempo. Tecnologia de bits
Ao projetar a estrutura, devemos não só satisfazer o alinhamento, mas também economizar espaço.Como fazer:
Deixar que os membros que ocupam um pequeno espaço se reúnam o máximo possível.
Os membros do tipo S1 e S2 são exatamente os mesmos, mas o tamanho do espaço ocupado por S1 e S2 é um pouco diferente.
Transferência de parâmetros de estrutura
por exemplo:
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;
}
A função print2 nas funções print1 e print2 é boa: quando a
função passa parâmetros, os parâmetros precisam ser colocados na pilha, o que causará sobrecarga no sistema de tempo e espaço.
Se a estrutura for muito grande ao passar um objeto de estrutura, a sobrecarga do sistema de empilhamento de parâmetro é relativamente grande, portanto, causará degradação de desempenho.
Conclusão: Ao passar o parâmetro da estrutura, deve-se passar o endereço da estrutura.
Estrutura para realizar o segmento da broca (preenchimento do segmento da broca e portabilidade)
O que é um
segmento de bit A declaração e a estrutura de um segmento de bit são semelhantes, com duas diferenças:
1. Os membros de um segmento de bit devem ser int, unsigned int ou signed int.
2. Há dois pontos e um número após o nome do membro do segmento de bit.
A capacidade da estrutura de implementar segmentos de bits é a seguinte:
Exemplo:
#include<stdio.h>
#include<string.h>
struct A
{
int _a : 2;
int _b : 5;
int _c : 10;
int _d : 30;
};
int main()
{
printf("%d\n", sizeof(struct A));
}
A é um tipo de segmento de bit. (1 byte = 8 bits)
Qual é o tamanho desse segmento A? 8 Alocação de memória do segmento de bits de
resultado em execução
- Os membros do segmento de bit podem ser int unsigned int assinado int ou char (pertencente à família inteira) tipo
- O espaço do segmento de bit é aberto em 4 bytes (int) ou 1 byte (char) conforme necessário.
- Os segmentos de bits envolvem muitos fatores incertos. Os segmentos de bits não são multiplataforma. Os programas que se concentram na portabilidade devem evitar o uso de segmentos de bits.
Problemas de plataforma cruzada - É incerto se o campo bit interno é tratado como um número com sinal ou um número sem sinal.
- O número de bits maiores no segmento de bit não pode ser determinado. (A máquina de 16 bits tem um máximo de 16 e a máquina de 32 bits tem um máximo de 32. Escreva como 27, o
que pode causar problemas em uma máquina de 16 bits . - Os membros no segmento de bit são alocados da esquerda para a direita na memória ou os critérios de alocação da direita para a esquerda não foram definidos.
- Quando uma estrutura contém dois segmentos de bit, e o segundo segmento de bit tem um membro relativamente grande e não pode caber nos bits restantes do primeiro segmento de bit
, é incerto se deve descartar os bits restantes ou usá-los.
Comparado com a estrutura, o segmento de bits pode obter o mesmo efeito, mas pode economizar muito bem espaço, mas há um problema de plataforma cruzada .