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.
Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!
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.