【问题标题】:When to use dereference operator for pointers C++ [duplicate]何时对指针使用解引用运算符 C++ [重复]
【发布时间】:2017-02-08 13:10:01
【问题描述】:

我目前正在学习 C++。不在学校。使用书籍、教程和练习。

让我感到困惑且无法找到答案的一件事是何时使用解引用运算符 (*) 作为指针。例如,来自我目前正在阅读的 C++ 入门:

char *cp = get_string();
if (cp) /* ... */    // true if the pointer cp is not zero 

while (*cp) /*    ... */    // true if *cp is not the null character

我不明白为什么在 if 语句中它只是 cp 没有取消引用运算符,然后在 while 语句中它使用取消引用运算符。还有其他示例,例如 for 循环中的混合使用,但这是本书中让我感到困惑的最新示例。提前感谢您的帮助。

总结:你什么时候只使用指针的变量名而不使用解引用,什么时候使用它来解引用。以及如何区分。

【问题讨论】:

  • 答案就在你的代码cmets ..
  • @HAG,我不在学校,我正在努力学习,所以我不完全理解它的含义,但感谢你对初学者投反对票,因为我不明白。我认为在这里发帖的目的是如果我需要帮助。您可能很容易理解这些 cmets 的含义,但我敢肯定,当您刚开始时,某些方面的情况也令人困惑。
  • 我没有投反对票!但是,我确实认为您可以通过简单的在线搜索找到答案.. 有大量的教程可以帮助您解决您的要求。这可能就是你的问题被否决的原因......
  • @HAG,那么我很抱歉。我做了谷歌搜索。尝试了一段时间,但找不到我的具体要求。这只是关于为什么使用指针和指针而不是引用的问题。我不知道为什么我因为提出问题而被否决。

标签: c++ pointers if-statement while-loop


【解决方案1】:

指针是一个变量,它的值是另一个变量或对象的地址。我们说指针“指向”另一个对象。

在编写表达式时,cp 表示指针变量。 *cp 表示指针变量所在地址的变量或对象。

试着在你的脑海中清楚“指针”和“被指向的东西”之间的区别。这是两个不同的东西,每个都有自己的生命周期和存储要求。

因此,为了解决您问题中的代码,if (cp) 正在测试指针。它是if ( cp != nullptr ) 的缩写,即指针是否已设置为指向某处? (也就是说,指针当前是否持有另一个对象的地址?)

if (*cp) 表示 if (*cp != 0) ,它询问地址存储在指针中的对象的值(即被指向的对象的值)。

【讨论】:

  • 所以没有取消引用是查看它是否实际指向一个对象,而取消引用是比较该对象的实际值?
  • @Matt 没错。
  • @Matt 好吧,这取决于您之后对表达式的处理方式。要理解的是cp 指的是指针,*cp 指的是指向的对象。 (这两件事都是“实际价值”)。然后,您可以继续将它们与某物进行比较,或分配给它们,或进行加法或其他任何操作
  • @Matt 你会把* 放在哪一行?
  • @Matt 我猜你的意思是auto *pbeg = ia.begin();?如果是这样,则该行中没有取消引用运算符。运算符只出现在表达式中,但*pbeg 是一个声明符。符号在声明器中的含义与在表达式中的含义不同。尝试查阅您的学习材料中有关声明的部分。还要查看 auto deduction 的工作原理,因为它与声明中的其他类型不同。
【解决方案2】:

这张图片解释了这个概念。

指针变量总是存储另一个变量的地址。如果是数组,它存储数组中第一个元素的地址。

解引用运算符引用特定指针变量存储的地址中的值。 在上面的例子中,指针变量 ptr 中存储的地址是 1001。*(ptr) 应该给出存储在地址位置 1001 中的值,即变量 var 的内容,即 50。

总而言之,当你想检查指针变量是否指向某个地址位置时,你使用不带解引用运算符的变量,当你想处理存储在指针变量中的地址位置中的值时,使用它与解引用运算符

在您的示例中,首先它检查指针是否通过语句指向字符串

if(cp)

然后通过语句检查指针变量的内容是否为非空(可能是检查字符串的结尾)

while(*cp)

【讨论】:

  • 感谢您的帮助。
【解决方案3】:

区别很简单,但需要练习才能习惯。本质上,当您想要处理指针实际指向的内容(即实际位于指针末尾的内容)时,使用解引用运算符。

例如,如果我有一个char *cp = get_string();,那么 cp 是一个指向字符数组中第一个字符的指针。

检查if(cp) 之类的内容是检查指针 是否为0(即指针是否指向NULL)。这在这种情况下可能很有用,因为get_string() 如果成功则返回一个指向字符串的指针,如果出现问题则返回一个NULL

相比之下,像while(*cp) 这样的操作是在说cp 当前指向的字符不是0(空字符\0),然后继续循环。在这种情况下,您的 while 循环可能类似于:

while(*cp) {
    // process letter currently pointed to by cp
    cp++; // advance cp to point to the next character.
}

这是遍历字符数组的常用习惯。

【讨论】:

  • 为什么把指针放在括号里,把后缀递增放在外面?
【解决方案4】:

我不认为像这样编写这两个测试是好的做法。为了清楚起见(这正是您要问的问题),它们应该是:

if(cp == nullptr) // or `cp == NULL`
    ...
if(*cp == '\0')
    ...

【讨论】:

  • 我只是在学习不要尝试制作程序。我正在努力了解基本面。
  • 惯例是避免if(cp == NULL) 的冗余。这就像写if(condition == True);它被认为是过度的。
  • @Matt 我的意思是,第一种情况检查指针是否为空,第二种情况检查指向字符是否为空.如果您使用空指针执行*cp,则会导致分段错误,因为它不是有效的内存地址。
  • @gowarth 我认为这取决于上下文和个人风格。对于初学者或测试的内容可能不明显的代码片段,IMO 仍然是一种很好的做法。
  • @gowrath 确实,这是多余的。但他写为了清楚。把事情说清楚可以澄清它们。
猜你喜欢
  • 2011-05-14
  • 1970-01-01
  • 1970-01-01
  • 2010-12-27
  • 1970-01-01
  • 2020-10-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多