0

Can any one explain how the printf is printing hello in the following?

#include<stdio.h>

void main()
{
 char *p;
 p="hello";
 printf("%s",*&*&p);
}

I know that *&p...means value in p, i.e the address of string "hello". What is happening in the initial *&

Beeeaaar
  • 1,010
  • 9
  • 19
Rohit
  • 635
  • 6
  • 12
  • 22
  • 4
    `*&`, first taking the address and then dereferencing is the identity, so `*&*&p` is just `p`. – Daniel Fischer Sep 06 '12 at 15:22
  • one doubt...assume p's address is 200 and "hello" starting address is 100...so *&*&p---*&*200---*&100....now what does &100 will give ....usually &p means address of the variable p....and how will it work for &100.... Thanx for the reply – Rohit Sep 06 '12 at 15:29
  • No, it doesn't work that way. You can only take the address of lvalues, so `&100` is meaningless. `&p` gives you a `char**`, pointing to `p`. Dereferencing that, `*&p` gives you the object `&p` points to, namely `p`. – Daniel Fischer Sep 06 '12 at 15:37

3 Answers3

7

As you said, *&p means p, that means the consecutive * and & cancels out. Hence *&*&p becomes p too.

And as @Kerrek said (in the comment) that *&p produces an lvalue, so you take its address again.


Note that your code is not standard conformant. main() must have int as return type. And you cannot assign "hello" to a non-const char*. It must be const char*. A standard conformant code would be this:

#include<stdio.h>

int main()
{
   const char *p = "hello"; 
   printf("%s",*&*&p);
}
Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • 2
    Perhaps worth noting that `*&p` is an lvalue, so you can take its address again... – Kerrek SB Sep 06 '12 at 15:25
  • Cheers. I was just thinking that someone might come and ask why `**&&` doesn't work :-) – Kerrek SB Sep 06 '12 at 15:30
  • "And you cannot assign "hello" to a non-const `char*`. It must be `const char*`." Perhaps it's worth pointing out that C and C++ differ here. In C, the type of `"hello"` is `char[6]`, and assigning it to a `char*` is perfectly legal (since trying to modify string literals is undefined behaviour, it's usually a good idea to only assign them to `const char*`s also in C, though). – Daniel Fischer Sep 06 '12 at 18:31
  • @DanielFischer: Is it `char[6]` or `const char[6]`? – Nawaz Sep 06 '12 at 18:37
  • In C, it's `char[6]`, in C++ it's `const char[6]`. – Daniel Fischer Sep 06 '12 at 18:43
1

&p is the address of p.

*p is the thing pointed at by the address p.

*&p is *(&p) the thing pointed at by the address &p - which is p itself (i.e., the thing pointed at by the address "address of p").

Thus it turns out that *&p is just p - the *& cancel each other out. You can repeat this: *&*&p will still be p. You can do this ad infinitum: *&*&*&*&*&*&*&*&*&p will also be p.

Claudiu
  • 224,032
  • 165
  • 485
  • 680
0

'*&' cancels each other. You are getting the address of p then dereferencing it again. So the end result will just be p.

Richard Heath
  • 349
  • 3
  • 12