Structs
AS Structs são a solução do C para organizar dados complexos, resolvendo dois grandes problemas que você encontraria ao usar apenas tipos simples
- Código Limpo: Imagine passar seis argumentos (
x1, y1, z1, x2, y2, z2) para uma função de distância. Fica confuso! Com uma struct, você agrupoa esses dados em um único "pacote". - Retorno Múltiplo: No C, uma função só pode retornar um único valor. Se você precisar que uma função retorn coordernadas X, Y e Z ao mesmo tempo, você as coloca dentor de uma struct e retorna a struct inteira.
- Sintaxe Básica: Você define um novo tipo personaliado que pode conter diferentes tipos de dados:
struct Human {
int age;
char *name;
int is_alive;
}As structs são o primeiro passo para criar estruturas de dados poderosas!
Inicializar e acessar Structs em C
- Formas de Inicialização:
struct City{
char *name;
int lat;
int lon;
}- Zero Initializer{0}: Define todos os campos da struct como zero.
int main() {
struct City c = {0};
}2. Positional Initializer: Os valores são passados na ordem exata em que foram declarados na definição da struct.
int main() {
struct City c = {"San Francisco, 37, -122};
}3. Designated Initializer (Recomendado): Você associa o valor diretamente ao nome do campo usando um ponto (ex. .name = SF). É a forma mais legível e segura, pois não quebra se a ordem dos campos mudar.
int main() {
struct City c = {
.name = "San Francisco",
.lat = 37,
.lon = -122
};
}- Acesso a Campos: Para ler ou modificar um valor, usamos o operador
.(ex.c.lat = 41).
struct City c;
c.lat = 41; // Set the latitude
printf("Latitude: %d, c.lat); // Print the latitudeDica
Uma forma facil de inicializar o retorno a struct.
struct city new_city(char *name, int lat, int lon) {
return (struct City){.name = name, .lat = lat, .lon = lon};
}Uso de Typedef em C
- Simplifição: O
typedefserve para criar "apelidos" para os tipos de dados. Isso evita que você tenha que digitarstruct NomeDaStructtoda vez que for declara uma váriavel. - Sintaxe: Ao definir a struct com
typedef, você escolhe um nome curto ao final (ex.pastry_t). Agora, você pode usar apenaspastry_tcomo se fosse um tipo nativo (comointoufloat). - Conversão: O sufixo
_té uma prática comum na comunidade C para indicar que aquela nome se refere a um tipo. - Flexibildade: Você pode até criar structs anônimas (sem nome oficial) se usar o
typedefpara dar o apelido diretamente.
Com isso, seu códgio fica muito mais limpo e legível!
Como o C gerencia o tamanho e a memória de structs
- `sizeof` em Structs: Funciona exatamente como nos tipos básicos, permitindo descobrir o tamanho total em bytes de uma struct personalizada.
- Layout de Memória: Os campos são armazenados de forma contígua (um após o outro). Se você tem três
intde 4 bytes, a struct terá pelomenos 12 bytes.

- Padding: O C insere espaços "vazios" entre campso de tipos diferenetes para garantir o alinhamento de memória. Isso ocorre porque as CPUs processam dados de forma mais eficiente quando eles estão organizados em blocos específicos (ex. de 4 em 4 bytes).
- Variabildiade: O Layout exato e a quantidade de padding dependem do compilador e da arquitetura do sistema.

É fascinante ver como o C expõe oesses detalhes de performance que outras linguagens escondem!
Struct Padding
- Controle Total: O fato de podermos influenciar o layout da memória é uma das maiores vantagens do C para quem busca performance.
- A Ordem Importa: O tamanho total de uma struct pode mudar drasticamente dependendo de como você organiza os campos.
- Dica de perfomance: Para minimizar o "padding" (os espaços vazios que o compilador insere para alinhar dados), a regra geral é listar os campos do maior para o menor (ex: comece com
doubleoulonge termine comchar).
É impressionante como uma simples mudança na ordem das linahs de código pode tornar seu programa muito mais eficiente em termos de mémoria.
typedef struct {
char* a; // 4 bytes
double b; // 8 bytes
short c; // 2 bytes
char d; // 4 bytes
long e; // 4 bytes
void f; // 0 bytes
} poorly_aligned_t;
=======================
typedef struct {
double b;
long e;
char* a;
char d;
short c;
void f;
} better_t;