Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

em relação a referenciação de ponteiros em structs

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.

2 respostas

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?

solução!

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:

  1. 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);

  2. 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;

  3. 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.