Pointer to struct

6

I was studying pointers to struct , and I saw that there are two ways to use it. can be:

(*ponteiro).variavel

Or:

ponteiro->variavel

According to what I read, when we put *ponteiro.variavel , because of the order of precedence, it ends up like this:

*(ponteiro.variavel)

So, okay. While I was practicing (I was using -> ), I came across the following situation:

I have struct within the other:

typedef struct {
    char nome[100];
    float salario;
} Funcionario;

typedef struct {
    char nome[100];
    unsigned qtdFuncionario;
    Funcionario *vetor;
} Firma;

At the time of accessing the nome or the salario of the employee, I had to do the following:

vetor[firma->qtdFuncionario].nome

If I put:

vetor[firma->qtdFuncionario]->nome

The compiler does not accept! But why does this work? And the order of precedence?

Thanks for the help;)

    
asked by anonymous 19.10.2018 / 18:41

2 answers

0

The type of vetor is Funcionario* and not Funcionario** . So to get a Funcionario (not a Funcionario* ), you use vetor[blablabla] . Because the result of this is Funcionario (not Funcionario* ), to access the nome field, you use .

Being vetor a pointer, when you use [] on a pointer, it will result in the type of the pointer component (that is, Funcionario ). Since Funcionario is not a pointer, members should be accessed with . and not -> . If you get a Funcionario* , then you would use -> , which is only valid for pointers.

As to precedence:

  • What's inside [] is resolved first, that is, firma->qtdFuncionario , which will result in some number.

  • Then, [] is applied to the pointer, which then gets an element whose address will be properly calculated by the code that the compiler enters. Note that what is obtained is an element, not a pointer. This resolves the expression on the left side of . or -> .

  • Having the content on the left side of . or -> has been completely solved, then the one on the right side can be solved. If the one on the left is a pointer, use -> . Otherwise, . is used.

Since you did not use the reference operator (the * unary) in the expression, its precedence turns out to be irrelevant. Your mistake is to believe that subexpression with [] should result in a pointer, which is not true.

    
19.10.2018 / 21:05
0

The member vetor is part of the structure Firma !

The compiler will return an error saying that vetor was not declared if you try something like:

vetor[firma->qtdFuncionario]->nome   /* ERRO! */

You need to tell the compiler that vetor is within firma :

firma->vetor[firma->qtdFuncionario]->nome  /* OK (?) */

CAUTION:

The compiler will perfectly compile this code, however, if your intent is to store the size of vetor to qtdFuncionario , the code still has a problem!

Something like:

firma->vetor[firma->qtdFuncionario]->nome   /* NÃO! */

Access a element after the last element of vetor , reading an unknown memory location, probably leading to an undefined behavior code.

Access the first official of vetor :

firma->vetor[ 0 ]->nome   /* OK! */

Access the last official of vetor :

firma->vetor[ firma->qtdFuncionario - 1 ]->nome  /* OK! */

Example:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    char nome[100];
    float salario;
} Funcionario;


typedef struct {
    char nome[100];
    unsigned int qtdFuncionario;
    Funcionario *vetor;
} Firma;

int main( void )
{
    unsigned int i;
    Firma f;

    /* Nome da Firma */
    strcpy( f.nome, "FooBar" );

    /* Quantidade de funcionarios */
    f.qtdFuncionario = 3;

    /* Aloca memoria para 3 funcionarios */
    f.vetor = (Funcionario*) malloc( sizeof(Funcionario) * 3 );

    /* Funcionario #1 */
    strcpy( f.vetor[0].nome, "Fulano" ); 
    f.vetor[0].salario = 1000.00;

    /* Funcionario #2 */
    strcpy( f.vetor[1].nome, "Ciclano" ); 
    f.vetor[1].salario = 1200.00;

    /* Funcionario #3 */
    strcpy( f.vetor[2].nome, "Beltrano" ); 
    f.vetor[2].salario = 1500.00;

    /* Exibe lista de Funcionarios da Firma */
    for( i = 0; i < f.qtdFuncionario; i++ )
    {
        printf("Funcionario #%d:\n", i+1 );
        printf("\tNome: %s\n", f.vetor[i].nome );
        printf("\tSalario: %.2f\n", f.vetor[i].salario );
    }

    /* Libera memoria */
    free(f.vetor);

    return 0;
}

Output:

Funcionario #1:
    Nome: Fulano
    Salario: 1000.00
Funcionario #2:
    Nome: Ciclano
    Salario: 1200.00
Funcionario #3:
    Nome: Beltrano
    Salario: 1500.00
    
20.10.2018 / 14:21