Accessing variables from a struct

Asked

Viewed 83 times

0

I am studying C and I am doubtful in the difference of the following lines:

(*depois).agora = 20

and

*depois.agora = 20;

From what I understand the point . has priority and the compiler would try to solve depois.agora and after that would settle *(depois.agora)

So, depois is the memory address. if I try to access *(depois.agora), I wouldn’t be picking up the value that’s contained in the address depois.agora?

What would be the difference between the 2 lines?

#include <stdio.h>

struct horario
{
    int hora;
    int minuto;
    int segundo;
};

int main(void)
{
    struct horario agora;
    struct horario *depois;

    depois = &agora; // depois aponta para agora, ou seja, armazena o endereco de memoria de agora

    (*depois).agora = 20; // "atalho": depois->agora = 20

    *depois.agora = 20; // errado, por quê?

    // * = operador de derreferência
    return 0;
}

2 answers

2

Essentially understood everything.

The first is taking the amount that is in the address depois and then taking the field hora (in the question the field name is wrong). The parentheses are just there to indicate that first comes the melt that will produce an object of the type struct horario which in turn has a field hora.

The second, by operator precedence, is picking up the pointer depois and trying to access the field hora in it, it turns out that a pointer has no fields, it is an address and nothing else, so it already gives error. He won’t even try to use the melt operator on something that doesn’t make sense. It’s like:

*(depois.agora) = 20;

I put in the Github for future reference.

You can only access an object in a way compatible with its content.

1


I start by saying that you are accessing the incorrect value in the:

(*depois).agora = 20; 
*depois.agora = 20;

For the structure horario doesn’t have the field agora, so would have to switch to one of the fields of the same, as for example, hora:

(*depois).hora = 20; 
*depois.hora = 20;

However, the problem has to do with operator precedence. The operator . has priority over the operator *. To make it more evident we could rewrite the instructions according to the operators' precedence:

(*depois).hora = 20; 
*(depois.hora) = 20;

To answer the question, the depois is a pointer that points to a structure. So first you have to go to the memory location where the structure is doing *depois, and only when he accessed the site in memory walk the bytes needed to reach the field hora with .hora, which gives you the first case you specified:

(*depois).hora = 20;

If you do not enclose the brackets, the operators' precedence is first done depois.hora that will try to access the pointer as if it were a structure, which in itself fails because it is a pointer and not a structure. The compiler can soon notice by the types that it is wrong and immediately gives a build error:

error: request for Member 'hora' in Something not a Structure or Union

Reading carefully we see that the compiler indicates that we are accessing a field hora of something that is not a structure or union (it is actually a pointer). Note also that only depois.hora is sufficient to generate the error.

Table of precedence of operators

  • then[0] will walk to the memory location stored by the pointer, for what I saw produces the same effect as using *after?

  • @Bart The indexing operator ([]) references the pointer, so it allows accessing the memory address pointed, but is conceptually incorrect for a pointer that does not point to an array.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.