возвращение векторного указателя из функции - PullRequest
0 голосов
/ 05 июля 2018

Привет, я пытаюсь понять алгоритмы, но я просто не понимаю, используя их в функциях. В этом случае передача вектора в функцию. Основная проблема в понимании связана с возвращаемой частью "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] ));
    }

Ответы [ 3 ]

0 голосов
/ 05 июля 2018

Фэй Сян дал хорошее объяснение. Я хотел бы добавить объяснение о *.

В вашем коде есть два разных значения *, я думаю, что это может быть одной из причин, почему вы не понимаете это хорошо.

  • vector<string>*, это означает указатель на векторный объект. * является частью типа.
  • (*pVec). * здесь разыменование указателя на его pointee. Цель разыменования здесь - использовать вектор operator [] для доступа к элементу вектора. Вы можете использовать указатель, чтобы сделать это напрямую, код выглядит как pVec->operator[](i).
0 голосов
/ 05 июля 2018

Чтобы понять это, вам просто нужно визуализировать, что переменные и указатели действительно означают с точки зрения областей памяти.

Компилятор и загрузчик программ будут выбирать реальные адреса памяти, и эти местоположения, вероятно, будут меняться при каждом запуске программы, поэтому мы просто составим некоторые значения для демонстрационных целей.

vecInventory является векторным объектом, и он занимает некоторое количество памяти, потому что в нем есть некоторые данные, поэтому давайте просто для демонстрации скажем, что он хранится в памяти, начиная с адреса 100. Если вы пишете vecInventory в программе это относится к векторному объекту.

&vecInventory - адрес векторного объекта. Так что &vecInventory - это просто число 100, потому что это ячейка памяти векторного объекта.

Так что теперь, когда вы передаете &vecInventory в ptrToElement, эта функция получает значение 100, которое она хранит в pVec. Так что pVec содержит число 100.

*pVec означает вещь, хранящуюся в месте, указанном в указателе. pVec содержит значение 100, которое является ячейкой памяти векторного объекта, поэтому *pVec является векторным объектом.

Вы могли просто передать векторный объект vecInventory в ptrToElement напрямую, вместо того, чтобы передавать ячейку памяти векторного объекта, но передача значений в функцию означает копирование переданного значения. Поэтому, если вы передаете число (например, место в памяти), копируется только одно число, тогда как передача объекта напрямую может быть проблемой, если этот объект действительно большой, потому что копирование чего-то действительно большого может занять некоторое время. В этом случае это не имеет значения, потому что вектор маленький (данные, которые вы помещаете в вектор, не сохраняются в объекте вектора).

(*pVec)[i] - это значение, хранящееся в записи i вектора. Помните, я говорил, что данные, которые вы помещаете в вектор, не сохраняются в объекте vector? Поэтому, когда в вашем примере i = 0, давайте просто скажем для демонстрации, что значение по индексу 0 вектора сохраняется в памяти, начиная с адреса 50.

&(*pVec)[i] когда i = 0 - это число 50, потому что это место, где значение в индексе 0 хранится в памяти. Это означает, что значение, возвращаемое из ptrToElement(&vecInventory,0) - это число 50.

*( ptrToElement(&vecInventory,0) ) означает вещь, хранящуюся в месте, указанном в указателе. ptrToElement(&vecInventory,0) возвращает значение 50, которое является ячейкой памяти значения, хранящегося в индексе 0, поэтому *( ptrToElement(&vecInventory,0) ) является значением, хранящимся в индексе 0 векторного объекта.

Итак, в нашем примере:

  • vecInventory - векторный объект (который хранится в ячейке памяти 100)
  • &vecInventory - это ячейка памяти 100
  • pVec - это ячейка памяти 100
  • *pVec - векторный объект (который хранится в ячейке памяти 100)
  • (*pVec)[i] когда i = 0 - это значение по индексу 0 вектора (которое хранится в ячейке памяти 50)
  • &(*pVec)[i] - это ячейка памяти 50
  • ptrToElement(&vecInventory,0) - это ячейка памяти 50
  • *( ptrToElement(&vecInventory,0) ) - это значение по индексу 0 вектора (которое хранится в ячейке памяти 50)
0 голосов
/ 05 июля 2018

Как отметил Игорь Тандетник, код не имеет большого смысла.

pVec - указатель на вектор строк, а *pVec дает вектор, на который он указывает. Затем [i] дает строку, индексированную i внутри вектора, и, наконец, & дает указатель на строку. Таким образом, эта функция возвращает указатель на элемент, индексированный i внутри вектора строк, на который указывает pVec.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...