Output a C code with pointers

16

I need to understand what each of the values printed on the screen means by the following code:

#include<stdio.h>

int main() {
 int i=5;
 int *p;
 p = &i;
 printf("%u %d %d %d %d \n", p, *p+2,**&p,3**p,**&p+4);
 return 0;
}

As I understand it, two variables were declared i and p , but p was declared as a pointer (I believe it is). When it says p = &i; means that now the p value is the i address. But I could not understand the values of *p+2,**&p,3**p,**&p+4. .

The output displays the following when executing the code:

6487628 7 5 15 9
    
asked by anonymous 20.10.2017 / 12:27

4 answers

17

The asterisk is the dereference operator , that is, it takes the value that is in that address. It can only be used in pointers to give correct results.

*p is to get the value of the address of p , in this case the p is the address of i you already know, then it takes the value 5 and then adds 2 giving 7 .

Next he does something unnecessary, I believe only to demonstrate the operation. It is getting the address of p ( &p ), and with it it is getting the value of this address through * ( *&p ) returning having the address contained in p , so it returns the address of i that was in p , then it again takes the value of i ( **&p ). Then there are 3 operators there: * * & p or if you prefer (*(*(&p))) .

The other read 3 * (*p) . The beginning is simple is basic arithmetic you already know, and what comes next has already learned above. It is getting the value that is at the address of p that we know is worth 5 (the value of i ) and multiplies by 3.

The latter is a mixture of the second and third.

Separating operations for better viewing:

#include <stdio.h>

int main() {
    int i = 5;
    int *p = &i;
    printf("%u\n", p);  //é o endereço de i
    printf("%d\n", *p);  //é o valor de i obtido pelo endereço que está em p
    printf("%d\n", (*p) + 2); //pega o valor de i e soma 2
    printf("%d\n", (&p));  //pega o endereço de p
    printf("%d\n", (*(&p))); //com o endereço de p pega o valor dele, que é o endereço de i
    printf("%d\n", *(*(&p))); //então pega o valor de i, isto é o mesmo que *p
    printf("%d\n", 3 * (*p)); //multiplica 3 pelo valor de i, é o mesmo que 3 * i
    printf("%d\n", *(*(&p)) + 4);  //soma 4 em i através de uma fórmula desnecessária
}

See running on ideone . And no Coding Ground . Also I placed GitHub for future reference .

And if you're wondering if * has different meaning depending on the context, yes, it has, it can be used as a multiplier when we are talking about normal values or it can have the form of accessing the value of a pointer when we are accessing a pointer. It is confusing, it should not be so, but that is how language was conceived. 3**p shows this well, the same symbol is doing two completely different operations.

    
20.10.2017 / 12:39
14
  • p appears as the value 6487628 . This is the actual value stored in p , which is the address of i .

  • *p+2 , due to operator precedence, should be interpreted as (*p)+2 . *p returns the value stored in the memory address pointed by p , which is 5 . In addition, we have the 7 result.

  • **&p is the same as *p because * and & are canceled. One is the operation of creating a pointer from one variable and the other is that of a value from a pointer. We have already seen that *p is 5 .

  • 3**p is interpreted as 3*(*p) , again, due to the precedence of the operators. This is the same as 3*5 , which is 15 .

  • **&p+4 is the same as *p+4 as seen in the other case. This is interpreted as (*p)+4 , which is 5+4 , which is equal to 9

20.10.2017 / 12:40
14

Follow your commented code:

#include <stdio.h>

int main()
{
    int i = 5;     /* Atribui 5 ao inteiro 'i' */
    int *p;        /* Declara um ponteiro 'p' para inteiro */
    p = &i;        /* Atribui ao ponteiro 'p' o endereco de 'i' */

    printf("%u\n", p );         /* Endereco armazenado no ponteiro 'p' */
    printf("%d\n", *p + 2 );    /* Soma 2 ao conteudo do inteiro apontado por 'p' */
    printf("%d\n", **&p );      /* Conteudo do inteiro apontado por 'p' (Mesmo que '*p') */
    printf("%d\n", 3 * *p );    /* Multiplica por 3 o conteudo do inteiro apontado por 'p' */
    printf("%d\n", **&p + 4 );  /* Soma 4 ao conteudo do inteiro apontado por 'p' (Mesmo que '*p + 4') */

    return 0;
}
    
20.10.2017 / 12:43
14
  

@Maniero's response has a more explanatory bias of operations, this mine has a bias of how the operations are done without further details

  • p ==> 6487628 : this is the address of i in memory
  • *p+2 ==> 7 : the sum of i with 2; as p points to i , *p takes value within i
  • **&p ==> 5 : the value indicated by the value indicated by the p address; narrowly, from right to left:
  • &p gets the address of variable p
  • *&p gets the address of p points, therefore gets p
  • **&p , we know that *&p ==> p of the previous step, so this equals *p , which is the numeric value 5 ( p points to i , i vale 5)
    • In the sense of pointers, addresses and variables, * and & are inverse operations, so they end up being null; only has one detail, the reference operator & can only be applied once consecutively, whereas the reference operator * can be cascaded consecutively
  • 3**p ==> 15 : 3 multiplied by the value indicated by p ; the first * is the multiplication operator, the second is the access to the memory region
  • **&p+4 ==> 9 : we already know that **&p is the value of i , then we add 4, obtaining 9
20.10.2017 / 12:39