【问题标题】:returning a vector pointer from a function从函数返回向量指针
【发布时间】:2018-12-13 10:48:46
【问题描述】:

您好,我正在尝试理解算法,但我只是不明白在函数中使用它们。在这种情况下,将向量传递给函数。理解的主要问题是“string* ptrToElement(vector<string>* const pVec, int i)"的返回部分。我不知道为什么在这个函数中返回时,"return (&( (*pVec)[i] ))",为什么pvec有一个*。为什么它是一个指针。这让我感到困惑理解,我不明白为什么 pvec 有

string* ptrToElement(vector<string>* const pVec, int i);
int main()
{

vector<string> vecInventory;

vecInventory.push_back("sword");
vecInventory.push_back("shield");
vecInventory.push_back("armour");

cout << "Sending the object pointed to by returned pointer: " << endl;
cout << *( ptrToElement(&vecInventory,0) ) << endl << endl;


int iTemp = 0;
cin >> iTemp;
return (0);
}



string* ptrToElement(vector<string>* const pVec, int i)
    {
    return (&( (*pVec)[i] ));
    }

【问题讨论】:

  • pVec 不必是指针。一个更合理的函数应该是这样的:string&amp; refToElement(vector&lt;string&gt;&amp; vec, int i) { return vec[i]; } 虽然目前还不清楚为什么需要一个辅助函数,而不是在必要时写vec[i]
  • 这实际上是给出的练习表的一部分。我试图理解其中的每一件事。唯一让我难过的是 pvec 是函数返回中的指针。我知道执行这个小练习的主要目的的其他方法。但是是的...

标签: c++ algorithm vector parameter-passing


【解决方案1】:

要理解这一点,您只需可视化变量和指针在内存位置方面的实际含义。

编译器和程序加载器会选择真实的内存地址,这些位置可能会在每次程序运行时发生变化,所以我们只是为了演示目的而编造一些值。

vecInventory 是一个向量对象,它占用了一些内存,因为它里面有一些数据,所以为了演示的目的,我们只说它存储在从地址 100 开始的内存中。如果你在程序中写 vecInventory它指的是矢量对象。

&amp;vecInventory 是向量对象的地址。所以&amp;vecInventory 只是数字 100,因为那是向量对象的内存位置。

所以现在当您将&amp;vecInventory 传递给ptrToElement 时,该函数将接收到它存储在pVec 中的值100。所以pVec 包含数字 100。

*pVec 表示存储在指针中存储位置的事物。 pVec 包含值 100,它是向量对象的内存位置,因此 *pVec 是向量对象。

您可以直接将vecInventory 向量对象传递给ptrToElement,而不是传递向量对象的内存位置,但是将值传递给函数意味着复制传递的值。因此,如果您传递一个数字(如内存位置),则只会复制一个数字,而如果该对象非常大,则直接传递一个对象可能会出现问题,因为复制非常大的东西可能需要一段时间。在这种情况下,这无关紧要,因为向量很小(您放入向量中的数据不会存储在向量对象中)。

(*pVec)[i] 是存储在向量条目 i 处的值。还记得我说过你放入向量中的数据没有存储在向量对象中吗?因此,当您的示例中的 i=0 时,出于演示目的,我们只说向量索引 0 处的值存储在从地址 50 开始的内存中。

&amp;(*pVec)[i] 当 i=0 时是数字 50,因为这是索引 0 处的值存储在内存中的位置。这意味着从ptrToElement(&amp;vecInventory,0) 返回的值是数字 50。

*( ptrToElement(&amp;vecInventory,0) ) 表示存储在指针中存储位置的事物。 ptrToElement(&amp;vecInventory,0) 返回值 50,它是存储在索引 0 处的值的内存位置,因此 *( ptrToElement(&amp;vecInventory,0) ) 是存储在向量对象的索引 0 处的值。

所以在我们的示例演示中:

  • vecInventory 是向量对象(存储在内存位置 100)
  • &amp;vecInventory是内存位置100
  • pVec是内存位置100
  • *pVec 是向量对象(存储在内存位置 100)
  • (*pVec)[i] 当 i=0 时是向量索引 0 处的值(存储在内存位置 50)
  • &amp;(*pVec)[i] 是内存位置 50
  • ptrToElement(&amp;vecInventory,0)是内存位置50
  • *( ptrToElement(&amp;vecInventory,0) ) 是向量索引 0 处的值(存储在内存位置 50)

【讨论】:

  • 如果我错了杰瑞,请纠正我。我知道对于返回的任何对象,返回类型都是 & 和 * 的罕见组合。我能想到的唯一与向量类似的其他类型是数组,所以如果它是一个传入的数组,显然函数被修改为将数组作为参数传入,返回是否类似于向量。 IE;说 char arr[10]="whatever";现在返回这个数组会是什么样子??
  • @EnochThomas 没有向量是对象。它与数组完全不同。您不需要传递指向数组的指针,因为数组会自动衰减为指向数据的指针,因此如果您有 string array[3];,您将在没有 &amp; 的情况下调用 ptrToElement(array,0)。该函数仍会收到一个指针。
  • @EnochThomas 好的,所以我最后的评论会令人困惑,因为我没有提到 WHAT 指针将传递给函数。该函数将接收string* 指针,然后您不需要(*x)[i],因为它不是指向数组的指针 - 它是一个数组,因此您只需要x[i],就像您传递了向量一样按价值。
  • 那么 & 和 * 的组合是向量独有的吗?因为这是我第一次看到对 pvec 的引用,同时有一个指向向量的指针。
  • @EnochThomas 您可以获取几乎任何东西的地址,然后取消引用它以返回原始对象。正如上面许多人所说,这个例子在 C++ 中真的很弱。在 C 中很常见到 avoid copying a large object,但在 C++ 中,您通常会看到 string&amp; ptrToElement(const vector&lt;string&gt;&amp; pVec, int i),其中 &amp; 生成 pVec,返回的 string referencences
【解决方案2】:

飞翔已经给出了很好的解释。我想添加一个关于*的解释。

在你的代码中,*有两种不同的含义,我想这可能是你不太理解的原因之一。

  • vector&lt;string&gt;*,这意味着指向向量对象的指针。 * 是类型的一部分。
  • (*pVec)* 这里是取消引用指针到它的指针。这里解引用的目的是使用vector的operator []来访问vector元素。您可以直接使用指针来执行此操作,代码类似于pVec-&gt;operator[](i)

【讨论】:

    【解决方案3】:

    正如 Igor Tandetnik 所说,代码没有多大意义。

    pVec 是一个指向字符串向量的指针,*pVec 给出了它指向的向量。然后,[i] 在向量内给出索引为i 的字符串,最后,&amp; 给出指向该字符串的指针。所以这个函数返回一个指针,指向i 指向的字符串向量内的索引元素pVec

    【讨论】:

      猜你喜欢
      • 2013-04-10
      • 1970-01-01
      • 1970-01-01
      • 2016-04-21
      • 1970-01-01
      • 2011-01-12
      • 2011-12-06
      相关资源
      最近更新 更多