Как передать вектор в параметр функции (мне нужны указатели?) - PullRequest
0 голосов
/ 30 января 2020

Когда мы передаем вектор в функцию, почему мы не можем сделать это как массив?

Например:

#include<bits/stdc++.h> 
using namespace std;


void func(vector<int> vect)
{
    vect.push_back(30);
}

int main()
{
    vector<int> vect;
    vect.push_back(10);
    vect.push_back(20);

    func(vect);

    for (int i = 0; i<vect.size(); i++)
        cout << vect[i] << " ";

    return 0;
}

В этом примере все работает нормально. Но если я делаю это так, почему он не работает как массив?

#include<bits/stdc++.h> 
using namespace std;

void func(vector<int> *vect)
{
    vect.push_back(30);
}

int main()
{
    vector<int> vect;
    vect.push_back(10);
    vect.push_back(20);

    func(&vect[0]);

    for (int i = 0; i<vect.size(); i++)
        cout << vect[i] << " ";

    return 0;
}

Так же, как массив, почему это невозможно?

Ответы [ 3 ]

2 голосов
/ 30 января 2020

vect[0] называет int, а не std::vector<int>.

&vect[0] - это int *, а не std::vector<int> *. Вы не можете вызвать функцию, ожидающую std::vector<int> * с int *

Вам необходимо изучить ссылки.

void func(vector<int> & vect) // use an existing std::vector<int>
{
    vect.push_back(30);
}
1 голос
/ 30 января 2020

В этом вызове функции

func(&vect[0]);

выражение аргумента имеет тип int *, в то время как параметр функции имеет тип std::vector<int> *

void func(vector<int> *vect)

, и не существует неявного преобразования от одного типа к другому.

По сути, объект типа std :: vector уже является указателем, заключенным в класс. Таким образом, передавая объект типа std :: vector по ссылке, вы фактически одновременно передаете указатель на выделенный массив, на который внутренне указывает вектор.

Обратите внимание, что в первой программе, представленной в вашем вопросе, вы передаете векторное значение вектора по значению.

void func(vector<int> vect)
{
    vect.push_back(30);
}

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

void func(vector<int> &vect)
{
    vect.push_back(30);
}

Нечто похожее, что вы имеете в виду, сделано для стандартного класса std::string в C ++ 17. Это класс std::string_view. Вы можете передать указатель на первый элемент объекта типа std :: string, как вы это делаете с массивами. Но вам также нужно передать длину массива символов, на который указывает указатель.

Вот демонстрационная программа.

#include <iostream>
#include <string>
#include <string_view>

void func( std::string_view s )
{
    std::string reversed_string( s.rbegin(), s .rend() );

    std::cout << reversed_string << '\n';
}

int main()
{
    std::string s( "Hello" );

    func( { &s[0], s.size() } );
}

Ее вывод

olleH
0 голосов
/ 30 января 2020

Это вполне возможно, но вы передаете элемент вектора, а не сам вектор:

void func(vector<int> *vect) {
    vect->push_back(30);   // <-- pointer type expression
}

int main() {

    vector<int> vect;
    vect.push_back(10);
    vect.push_back(20);

    func(&vect); // <-- pass the vector

    for (size_t i = 0; i < vect.size(); i++) // <-- iterator should be size_t type
        cout << vect[i] << " ";

    return 0;
}

Если вы хотите передать ссылку на элемент вектора, вы можете сделать это тоже Обратите внимание, что этот элемент уже должен существовать:

void func(int *vect_elem) {  //<-- pointer to int parameter
    *vect_elem = 30; // <-- assign 30 to the vector element
}

int main() {

    vector<int> vect;
    vect.push_back(10);
    vect.push_back(20);

    func(&vect[0]); //<-- reference an existing element of the vector

    for (size_t i = 0; i<vect.size(); i++)
        cout << vect[i] << " ";

    return 0;
}

В этом конкретном случае вам не нужны указатели, лучше использовать только ссылки, как это уже упоминалось, поскольку вам не нужно любая разыменование:

void func(vector<int> &vect) { //<-- parameter reference
    vect.push_back(30); 
}

int main() {

    vector<int> vect;
    vect.push_back(10);
    vect.push_back(20);

    func(vect); // <-- pass the vector

    for (size_t i = 0; i < vect.size(); i++)
        cout << vect[i] << " ";

    return 0;
}
void func(int &vect_elem) { //<-- parameter reference
    vect_elem = 30;
}

int main() {

    vector<int> vect;
    vect.push_back(10);
    vect.push_back(20);

    func(vect[0]); //<-- pass the element

    for (size_t i = 0; i<vect.size(); i++)
        cout << vect[i] << " ";

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