Передача массива, созданного в функция другие функции


Я начинаю свое приключение программирования на C++. Я хочу написать небольшую программу, которая создает массив в функции create (размер должен быть определен в функции Create) и передачи их на дисплей функцию, которая будет печатать введенных значений.

#include <iostream>

using namespace std;

int *create(int & n);
void display(int * arr, int n);

int main()
{
    int n;
    int * arr = create(n);
    display(arr, n);


    delete[] arr;

    return 0;
}

int *create(int & n) {
    cout << "How many elements? ";
    cin >> n;
    int * arr = new int[n];
    int element;
    for(int i = 0; i < n; i++) {
        cout << endl << "Enter " << i << " array element: ";
        cin >> element;
        arr[i] = element;
    }

    return arr;
}

void display(int * arr, int n) {
    for(int i = 0; i < n; i++) {
        cout << endl << i << " element: " << arr[i];
    }
}

Я ищу любую критику, оптимизация и все, что поможет мне стать лучшим программистом, а не привычкой с самого начала.



145
3
c++
задан 25 марта 2018 в 04:03 Источник Поделиться
Комментарии
1 ответ

Во-первых, обычные упреки:


  • Не использовать using namespace std;

  • Не используйте сырые new и delete

  • Включать заголовки в коде используется (например, <iostream>)

  • Предпочитаю префикс ++i за постфикс i++ В общем привычка

  • Предпочитаю опустить подразумеваемых return 0; от main (если вы пытаетесь подчеркнуть, что возвращаемое значение-это разные по разным codepaths, который не применяется в данном случае)

Но специфические для вашего проектированию API:


  • Ваша функция create имеет два выхода: указатель на новый массив и размер нового массива, n. Бывший возвращается в качестве возвращаемого значения; последняя передается по ссылке (в out-параметр шаблона). Вместо того, чтобы возвращать эти две части информации по двум разным маршрутам, вы должны объединить их: либо пройти в два из параметров (фу!) или передать из двух значений по возвращению.

Принимая второй подход (два значения по доходности) и применяя наши правила , кроме "не сырые new и delete"мы в конечном итоге с этим:

#include <iostream>
#include <utility>

std::pair<int *, int> create() {
int n;
std::cout << "How many elements? ";
std::cin >> n;
int *arr = new int[n];
for (int i = 0; i < n; ++i) {
int element;
std::cout << std::endl << "Enter " << i << " array element: ";
std::cin >> element;
arr[i] = element;
}
return {arr, n};
}

void display(int *arr, int n) {
for (int i = 0; i < n; ++i) {
std::cout << std::endl << i << " element: " << arr[i];
}
}

int main() {
auto [arr, n] = create(n);
display(arr, n);
delete [] arr;
}

В JavaScript-просмотр [arr, n] это c++17 синтаксис, но не волнуйтесь, мы собираемся избавиться от него в нашей следующей рефакторинг.

Применяя "не сырые new и delete" позволяет упростить значительно дальше:

#include <iostream>
#include <vector>

std::vector<int> create() {
int n;
std::cout << "How many elements? ";
std::cin >> n;
std::vector<int> result;
for (int i = 0; i < n; ++i) {
int element;
std::cout << std::endl << "Enter " << i << " array element: ";
std::cin >> element;
result.push_back(element);
}
return result;
}

void display(const std::vector<int>& vec) {
for (int i = 0; i < int(vec.size()); ++i) {
std::cout << std::endl << i << " element: " << vec[i];
}
}

int main() {
auto vec = create(n);
display(vec);
}

Последнее, что я бы рассмотреть возможность сделать это мутация исключения из кодекса. У тебя эти переменные int n и int element что не инициализируются, а затем использовать std::cin >> ... мутировать их значения. Это может быть более простым, чтобы написать "инт-получение функции" и использовать его постоянно. Плюс, это дает нам место, чтобы повесить отсутствует std::flush:

#include <iostream>
#include <vector>

template<class T>
T input(const char *prompt) {
T result;
// Print out everything in `prompt` (C++17 syntax)
std::cout << prompt << " " << std::flush;
std::cin >> result; // Should we add some error-checking?
// What if the user types "hello world" here?
return result;
}

std::vector<int> create() {
std::vector<int> result;
int n = input<int>("How many elements?");
for (int i = 0; i < n; ++i) {
result.push_back(input<int>("Enter the next array element:"));
}
return result;
}

void display(const std::vector<int>& vec) {
for (int i = 0; i < int(vec.size()); ++i) {
std::cout << std::endl << i << " element: " << vec[i];
}
}

int main() {
display(create(n));
}

Обратите внимание, что я изменил ваш запрос "Enter the 42 array element:" просто "Enter the next array element:". Это произошло потому, что я не хочу заморачиваться, объясняя, как писать с переменным числом аргументов шаблона Версия input что бы принять input<int>("Enter the ", i, " array element:"). Вполне возможно — даже тривиальным, в C++17, где мы можем написать (std::cout << ... << prompt_pieces) << " " << std::flush — но я хочу, чтобы держать простой код простой.

Теперь мы локализовали все неприглядное "государственный мутация" в утробе input<int>; мы не должны думать о мутациях, пока мы читаем create.

4
ответ дан 25 марта 2018 в 05:03 Источник Поделиться