8

I'm newbie on C. I need to understand what each of the values ​​printed on the screen means by the following code:

#include<stdio.h>

int main() 
{
     int x = 10;
     int *ptr = &x;
     printf("%d %d %d\n", *ptr,**&ptr, 2**ptr);
     return 0;
}

Output(GCC):

10 10 20

Here, I have declared variable x and ptr point to x variable. So, *ptr printed value of x. But I could not understand the values ​​of **&ptr and 2**ptr.

Thanks in advance.

msc
  • 33,420
  • 29
  • 119
  • 214
skc
  • 139
  • 1
  • 5
  • 1
    the first 10 is the content of ptr (and ptr is the adr of x) so it's the content of x ... the second one you & = you get adr of ptr, * = you get its content, * = you get again the content of ptr which is also x. The last one you multiply the *ptr by 2 and *ptr is again the content of x – Temani Afif Oct 28 '17 at 08:09
  • 2
    If you understand what `*ptr` is, you’ll probably understand what `2 * *ptr` is when formatted sensibly. (It’s two times `*ptr`.) – Ry- Oct 28 '17 at 08:09
  • 1
    You may found these readings useful [What does “dereferencing” a pointer mean?](https://stackoverflow.com/questions/4955198/what-does-dereferencing-a-pointer-mean) and [meaning of “referencing” and “dereferencing”](https://stackoverflow.com/questions/14224831/meaning-of-referencing-and-dereferencing) – Yusef Maali Oct 28 '17 at 08:50

4 Answers4

30

Here, * and & operators cancel effect of each other when used one after another. 

**&ptr is the same as *ptr and here, ptr hold the address of x variable. So, print the value of x here.

2**ptr is interpreted as 2 * (*ptr). So, 2 * (10) is equal to 20.

msc
  • 33,420
  • 29
  • 119
  • 214
9
**&ptr

& and * are unary operators which have an opposite meaning 1 from the other.

&(lvalue) means to return the address of the corresponding lvalue while *(lvalue) means to return the value from the address pointed by lvalue, considering the type of lvalue, in order to know how to dereference it.

Visually the meaning of these operators looks like this (my talent in artist-mode of emacs is not too big):

        +----------------+            
        |  ptr = *&ptr   |            
        +--------------+-+            
       /                \
      /                  \
     &ptr                 \
                           +----------------+
                           |    *ptr        |
                           +----------------+
                          /
                         /
                        ptr

Note that I marked inside the box the right value, while outside the box the addresses of memory of the left values of the corresponding memory locations.

Now when you write *&(lvalue), it means to get the value from the address of lvalue, which is written shortly lvalue.

So **&ptr means *ptr -- namely the value from the adress pointer by ptr, dereferenced as integer, in your case 10.


2**ptr

The lexer will split the code in tokens and the parser will build a tree like that:

(2) * (*ptr)

In this case the result will be 2 times the value from the adress of ptr, in your case 20.

alinsoar
  • 15,386
  • 4
  • 57
  • 74
  • 5
    Nice answer, but to be honest I find your graph pretty confusing. For one, `ptr` is reported twice, once inside a box and once outside. And there's no `x=10` anywhere. – Fabio says Reinstate Monica Oct 28 '17 at 12:41
  • @FabioTurati Inside the box it is the right value, outside the box the left value. There is no x=10 as the answer is abstract, not concrete. – alinsoar Oct 28 '17 at 12:42
2

int *ptr points to int x.

printf("%d\n", *ptr); means - take value where prt points. So *ptr is x value.

printf("%d\n", **&ptr); - &ptr is the address of pointer and *&ptr is value in ptr. And value of &ptr is address of x. So **&ptr is value of x

printf("%d\n", 2**ptr); - 2 multiply by value in ptr. It means 2*x

Gor Asatryan
  • 904
  • 7
  • 24
0

ptr is a pointer variable. This pointer variable will point to the memory location where the value of x is stored. *ptr will access the value pointed by the pointer variable.

Now & is an address operator in C. &ptr returns the address of ptr. So *&ptr returns the value from the address of ptr. So * and & will nullify each other. That is ptr and *&ptr are one and the same.

ptr = *&ptr => *ptr = **&ptr Hence the value is 10.

2**ptr is nothing but 2 * (*ptr). Hence the value is 20.

Saathvik
  • 267
  • 4
  • 9
  • "*`*ptr` is a pointer variable.*" No really. `ptr` is the pointer varaible. And as you correctly mention: `*ptr` is the dereference pointer `ptr`. So in fact `*ptr` evaluates to an `int`. – alk Oct 28 '17 at 09:07