Multiple Reference and Dereference in C

早过忘川 提交于 2019-12-25 18:28:37

问题


Can somebody clealry explain me the concept behind multiple reference and dereference ? why does the following program gives output as 'h' ?

int main()
{
char *ptr = "hello";
printf("%c\n", *&*&*ptr);

getchar();
return 0;
} 

and not this , instead it produces 'd' ?

int main()
{
char *ptr = "hello";
printf("%c\n", *&*&ptr);

getchar();
return 0;
}

I read that consecutive use of '*' and '&' cancels each other but this explanation does not provide the reason behind two different outputs generated in above codes?


回答1:


The first program produces h because &s and *s "cancel" each other: "dereferencing an address of X" gives back the X:

  • ptr - a pointer to the initial character of "hello" literal
  • *ptr - dereference of a pointer to the initial character, i.e. the initial character
  • &*ptr the address of the dereference of a pointer to the initial character, i.e. a pointer to the initial character, i.e. ptr itself

And so on. As you can see, a pair *& brings you back to where you have started, so you can eliminate all such pairs from your dereference / take address expressions. Therefore, your first program's printf is equivalent to

printf("%c\n", *ptr);

The second program has undefined behavior, because a pointer is being passed to printf with the format specifier of %c. If you pass the same expression to %s, the word hello would be printed:

printf("%s\n", *&*&ptr);



回答2:


Lets go through the important parts of the program:

char *ptr = "hello";

makes a pointer to char which points to the string literal "hello". Now, for the confusing part:

printf("%c\n", *&*&*ptr);

Here, %c expects a char. Let us look into what type *&*&*ptr is. ptr is a char*. Applying the dereference operator(*) gives a char. Applying the address-of operator to this char gives back the char*. This is repeated again, and finally, the * at the end gives us a char, the first character of the string literal "hello", which gets printed.


In the second program, in *&*&ptr, you first apply the & operator, which gives a char**. Applying * on this gives back the char*. This is repeated again and finally , we get a char*. But %c expects a char, not a char*. So, the second program exhibits Undefined Behavior as per the C11 standard (emphasis mine):

7.21.6.1 The fprintf function

[...]

  1. If a conversion specification is invalid, the behavior is undefined.282If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined.

So, basically, anything can happen when you execute the second program. Your program might crash, emit a segmentation-fault, output weird things, or do something else.


BTW, you are right about saying:

I read that consecutive use of '*' and '&' cancels each other




回答3:


Let's break down what *&*&*ptr actually is, but first, remember that when applying * to a pointer, it gives you what that pointer points to. On the other hand, when applying & to a variable, it gives you the address in memory for that variable.

Now, after getting a steady ground, let's see what you have here: ptr is a pointer to a char, thus when doing *ptr it gives you the data which ptr points to, in this case, ptr points to a string "hello", however, a char can hold only one char, not a whole string, right? so, it point to the beginning of such a string, which is the first character in it, aka h.

Moving on...*&*&*ptr=*&*&(*ptr) = *&*&('h')= *&*(&'h') = *&*(ptr)=*&(*ptr) = *&('h')= *ptr = 'h'

If you apply the same pattern on the next function, I'm pretty sure you can figure it out.

SUMMARY: read pointers from the right to the left!



来源:https://stackoverflow.com/questions/30423589/multiple-reference-and-dereference-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!