estou com uma duvida em relação ao uuso de struct, em que momento no meio do código devo usar o "." ou "->" ou ainda "(*p).var"? Não entendi muito bem como isso funciona.
estou com uma duvida em relação ao uuso de struct, em que momento no meio do código devo usar o "." ou "->" ou ainda "(*p).var"? Não entendi muito bem como isso funciona.
Oi Amanda Tudo bom?
Não sei se entendi direito a sua duvida. Qual a a sua duvida em relação ao uso do struct?
Para responder essa pergunta tem-se de ter um bom entendimento sobre o sistema de tipos do C. Uma variável char*
, por exemplo, possui um tipo diferente de uma char
. Essa diferença pode ser observada em vários níveis, mas citarei 3 exemplos:
O espaço em memória ocupado por um char
é, tipicamente, de um byte, ao passo que um char*
, como todo ponteiro, ocupa 1 palavra --- veja o valor exato usando o operador sizeof(void*)
(em sistemas de 64 bits, o valor é 8 bytes);
Dada uma variável do tipo int
, o operador ++
incrementa o valor contido na variável, alterando seu conteúdo para o valor original + 1. Em uma variável do tipo int*
o operador incrementa o valor original em sizeof(int)
, afinal, estamos falando de endereçamento de memória. Para mais informações sobre isso, procure sobre aritmética de ponteiros;
O tipo void
não pode ser usado para variáveis, e, em funções, declara a ausência de valor retornado. Por outro lado, void*
é um tipo de ponteiro genérico, que pode ser usado com variáveis de qualquer tipo, ainda que torne o conteúdo apontado opaco.
Portanto, agora que definimos a distinção entre tipos, vamos às especificidades.
O operador ponto ".
" é usado para acessar campos de uma variável do tipo struct
ou union
.
O operador prefixado "*
" realiza uma dereferência, ou seja, retorna o valor apontado pelo ponteiro alvo. Na prática, é como se estivéssemos fazendo uma coerção. Veja um exemplo:
int val = 1;
int *ptr = &val;
// As 2 linhas de código abaixo, nesse contexto, seriam uma potencial
// fonte de bugs difícil de localizar. Perceba que a primeira linha
// incrementa o endereço apontado por ptr, o qual pode nunca ter
// sido inicializado. A segunda incrementa o valor contido nesse
// endereço. Cuidado com o uso de aritmética de ponteiros!
ptr++; // expressão do tipo int*
(*ptr)++; // expressão do tipo int. Atenção à precedência dos operadores!
O operador seta "->
" é usado para acessar campos de estruturas e uniões referenciados por um ponteiro. Ou seja:
struct exemplo {
int val;
} meu_exemplo = {2};
printf("%d\n", meu_exemplo.val);
struct exemplo *ptr = &meu_exemplo;
printf("%d\n", ptr-> val);
Resumindo:
Use o operador ".
" sempre que estiver trabalhando com uma variável de um tipo struct
ou union
. Use o operador "->
" sempre que estiver trabalhando com um ponteiro. A notação (*ptr).val
é equivalente a ptr-> val
. Use aquela que você considerar mais legível, o importante não é tanto qual delas usar, mas ser consistente no uso. Particularmente, prefiro usar o operador "->
", pois torna explícito, em qualquer contexto, que se está operando um ponteiro.