C中的多重引用和解引用

时间:2015-05-24 12:39:42

标签: c pointers reference dereference

有人可以向我解释多重引用和解除引用背后的概念吗?为什么以下程序将输出设为'h'?

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

getchar();
return 0;
} 

而不是这个,而是产生'd'?

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

getchar();
return 0;
}

我读到连续使用'*'和'&'相互抵消,但这个解释没有提供上述代码中产生的两个不同输出背后的原因?

3 个答案:

答案 0 :(得分:2)

第一个程序产生h,因为&* s"取消"彼此:"解除引用X"的地址给回X:

  • ptr - 指向"hello" literal
  • 的首字母的指针
  • *ptr - 取消引用指向初始字符的指针,即初始字符
  • &*ptr指向初始字符的指针的解引用地址,即指向初始字符的指针,即ptr本身

等等。如您所见,一对*&将您带回到您已经开始的位置,因此您可以从取消引用/获取地址表达式中删除所有这些对。因此,您的第一个程序printf等同于

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

第二个程序有未定义的行为,因为指针正在传递给printf,格式说明符为%c。如果您将同一个表达式传递给%s,则会打印出hello这个词:

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

答案 1 :(得分:1)

让我们来看看该计划的重要部分:

char *ptr = "hello";

指向char指向字符串文字"hello"的指针。现在,对于令人困惑的部分:

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

此处,%c需要char。让我们看一下*&*&*ptr的类型。 ptrchar*。应用解除引用运算符(*)会得到char。将地址运算符应用于此char会返回char*。这会再次重复,最后,*最后给我们一个char,即字符串文字"hello"的第一个字符,它会被打印出来。

<小时/> 在第二个程序中,在*&*&ptr中,您首先应用&运算符,该运算符为char**。在此上应用*会返回char*。这再次重复,最后,我们得到一个char*。但是%c需要char,而不是char*。因此,第二个程序根据C11标准(强调我的)展示Undefined Behavior

  

7.21.6.1 fprintf函数

     

[...]

     
      
  1. 如果转换规范无效,则行为未定义。 282 如果任何参数不是相应转换规范的正确类型,则行为未定义。 < / LI>   

所以,基本上,当你执行第二个程序时,任何事情都会发生。您的程序可能会崩溃,发出分段错误,输出奇怪的内容或执行其他操作。

顺便说一下,你说的是对的:

  

我读到连续使用&#39; *&#39;和&#39;&amp;&#39;取消对方

答案 2 :(得分:0)

让我们分解*&*&*ptr实际上是什么,但首先,请记住,当将*应用于指针时,它会为您提供指针所指向的内容。另一方面,当将&应用于变量时,它会为您提供该变量的内存地址。

现在,在稳定的基础上,让我们看看你在这里有什么: ptr是指向char的指针,因此在执行*ptr时,它会为您提供ptr指向的数据,在这种情况下,ptr指向字符串"hello",但是char只能容纳一个字符,而不是整个字符串,对吧?所以,它指向这样一个字符串的开头,这是其中的第一个字符,即h

继续...... *&*&*ptr=*&*&(*ptr) = *&*&('h')= *&*(&'h') = *&*(ptr)=*&(*ptr) = *&('h')= *ptr = 'h'

如果你在下一个函数上应用相同的模式,我很确定你能搞清楚。

摘要:从右到左读取指针!