Funções, struct e ponteiros
Ponteiros para struct são um modo prático de acessar membros de uma struct. O conceito de ponteiros para struct é o mesmo que ponteiro para uma variável int ou float por exemplo. Primeiro declaramos uma variável e um ponteiro para ela, depois fazemos o ponteiro apontar para o endereço de memória daquela variável. A vantagem de um ponteiro para uma struct é que uma função pode receber apenas um ponteiro para um membro da struct, sem precisar receber toda struct de uma vez.
Erros de lógica:
- Se o ponteiro para a struct não estiver apontado para a mesma, a tentativa de acessar um membro da struct causará um travamento ou outro erro;
- O tipo declarado dentro da struct deve corresponder ao tipo do ponteiro em si e vice-versa para evitar problemas.
- A function that swaps all values of all members of two structs of the same type:
typedef struct Produto Pro; struct Produto { char Tipo[1]; int Ano; }; /* recebe dois endereços de duas structs, A e B, e troca os valores de todos os membros de cada uma */ void Troca (Pro *A, Pro *B) { Pro Temp, *C; C = &Temp; *C = *A; *A = *B; *B = *C; } /* Chamando a função */ Troca(&X, &Y);
É a mesma lógica da troca de valores de duas variáveis, mas agora temos structs e ponteiros para uma struct. Note que ambas as structs devem ser do mesmo tipo, senão o programa não compila.
Nota: no exemplo acima, X e Y são do mesmo tipo "Pro". Se um membro da struct é do tipo float e o ponteiro é do tipo int. Esse tipo de mistura causa problemas.
- Uma função que troca o valor de dois membros de duas structs:
typedef struct Product Pro; struct Produto { char Tipo[1]; int Ano; }; /* Recebe dois endereços de duas structs, A e B e troca os valores do membro "Ano" de cada uma */ void Troca (Pro *A, Pro *B) { Pro Temp, *C; C = &Temp; C->Ano = A->Ano; A->Ano = B->Ano; B->Ano = C->Ano; } /* Chamando a função */ Swap(&X, &Y);
O operator flecha: tanto C->Ano quanto (*C).Ano significam a mesma coisa. No segundo caso os parêntesis são obrigatórios por causa da precedência dos operadores. Sem os parêntesis o compilador irá ler *(C.Ano) e gerará um erro porque não tem um ponteiro com aquele nome. O operador flecha é um símbolo mnemônico para lembrar que C é um ponteiro e que aponta para a struct do tipo "Pro", em direção ao membro "Ano".
Nota: temos que ter cuidado para não confundir o ponteiro para uma struct com a própria struct. Portanto, se escrevermos C.Ano ou B.Tipo[0], estamos dizendo para o compilador que "C" e "B" são structs quando não o são.