Member 14771149 Ответов: 3

C++ , я хочу сделать динамический массив в main и передать его функции, которая возвращает два массива, один для положительного, а другой для отрицательного


в этой функции всегда отображается ошибка, что a и b являются инициализированными переменными, но я думаю, что в коде есть больше проблем

Что я уже пробовал:

#include <iostream>
using namespace std;
void PosNeg(int* arr, int n, int* a, int* b, int& cn, int& cp)
{
    cn = 0, cp = 0;
    for (int i = 0; i < n; i++) {
        if (arr[i] >= 0) {
            cp++;
        }
        else {
            cn++;
        }
    }
    a = new int[cn];
    b = new int[cp];
    for (int i = 0; i < n; i++) {
        if (arr[i] < 0) {
            arr[i] = a[i];
        }
        else {
            arr[i] = b[i];
        }

    }
    delete[]a;
    delete[]b;
}
int main() {
    int n, cn, cp;
    int* a;
        int* b;
    cout << "Enter number of elements:" << endl;
    cin >> n;
    int* A = new int[n];
    cout << "Enter the elements:" << endl;
    for (int i = 0; i < n; i++) {
        cin >> A[i];
    }
  
    PosNeg(A, n, a, b, cn, cp);
    for (int i = 0; i < cn; i++) {
        cout << a[i] << " ";
    }
    for (int i = 0; i < cp; i++) {
        cout << b[i] << " ";
    }
}

3 Ответов

Рейтинг:
22

CPallini

Это исправляет это (некрасиво, как вам уже сказали) C++ код

#include <iostream>
using namespace std;

void PosNeg(int* arr, int n, int* &a, int* &b, int& cn, int& cp)
{        
    cn = 0, cp = 0; 
    for (int i = 0; i < n; i++) {
        if (arr[i] >= 0) {
            cp++;
        }
        else {
            cn++;
        }
    } 
    a = new int[cp];
    b = new int[cn];
    int in = 0;
    int ip = 0;
    for (int i = 0; i < n; i++) {
        if (arr[i] >= 0) {
            a[ip++] = arr[i];
        }
        else {
            b[in++] = arr[i];
        }
    }
}
int main() {
    int n, cn, cp;
    int* a;
    int* b;

    cout << "Enter number of elements:" << endl;
    cin >> n;

    int* A = new int[n];

    cout << "Enter the elements:" << endl;
    for (int i = 0; i < n; i++) {
        cin >> A[i];
    }

    PosNeg(A, n, a, b, cn, cp);
    cout << "non-negative: ";
    for (int i = 0; i < cp; i++) {
        cout << a[i] << " ";
    }
    cout << "\nnegative: ";
    for (int i = 0; i < cn; i++) {
        cout << b[i] << " ";
    }
    cout << "\n";
    delete [] a;
    delete [] b;
}


Рейтинг:
16

Stefan_Lang

Решение 1 делает хорошую работу по исправлению всех ваших ошибок. Однако большинство из этих ошибок были бы невозможны, если бы вы использовали вместо этого функции C++. Вот другое решение, которое позволяет избежать большинства ловушек, в которые вы попали:

#include <iostream>
#include <vector>

using namespace std;

pair<vector<int>,vector<int>> PosNeg(vector<int> input_values)
{
    std::vector<int> positives;
    std::vector<int> negatives;
    for (size_t i = 0; i < input_values.size(); ++i)
        if (input_values[i] < 0)
            negatives.push_back(input_values[i]);
        else
            positives.push_back(input_values[i]);
    return make_pair(negatives, positives);
}

int main()
{
    // read values
    std::vector<int> values;
    int n;
    cout << "Enter numbers. Enter any character to finish." << endl;
    do
    {
        cin >> n;
        if (cin.fail())
            // could not read (or convert to) integer value --> exit loop
            break;
        else
            // store this value
            values.push_back(n);
    } while (cin.good());

    // separate
    auto results = PosNeg(values);

    // write output
    cout << "negative values:" << endl;
    for (size_t i = 0; i < results.first.size(); ++i)
        cout << results.first[i] << " ";
    cout << endl;
    cout << "positive values:" << endl;
    for (size_t i = 0; i < results.second.size(); ++i)
        cout << results.second[i] << " ";
    cout << endl;

    return 0;
}


Улучшения по сравнению с тем, что вы делали:
1. нет необходимости выделять какой-либо массив с помощью std::vector
--> нет никакого способа испортить ваше освобождение массива
2. нет необходимости отслеживать размеры массива с помощью std::vector
--> нет необходимости заранее определять требуемые размеры массивов
--> нет необходимости передавать размеры массива в функцию и из нее
3. можно добавить дополнительные значения с помощью vector::push_back()
--> нет необходимости отслеживать значения индекса массива
--> нет способа использовать неверный индекс (ваш вышел за рамки, потому что вы использовали индекс входного массива и для выходных массивов!)
4. можно вернуть два результирующих массива в качестве возврата функции с помощью std::pair
--> нет необходимости указывать (и инициализировать) результирующие массивы перед вызовом функции
--> нет необходимости без необходимости расширять список аргументов функции выходными значениями
--> нет способа испортить передачу выходных значений по значению, а не по ссылке (вы это сделали)

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

Я надеюсь, что это даст вам представление о полезности типов C++, таких как vector и pair, и даст вам стимул прочитать о функциях C++, чтобы вы могли правильно использовать их в своих будущих программах.


CPallini

У меня 5.
"как вам было сказано", - не случайно прозвучало в моем ответе:
https://www.codeproject.com/Questions/5262520/Cplusplus-function-to-reorder-even-elements-in-an

Stefan_Lang

Спасибо. Я и вас тоже обвинил - иначе зачем бы мне ссылаться на ваше решение ;-)

Рейтинг:
10

Rick York

Начните с рассмотрения того, что происходит с переменной a в функции main. Он объявлен как указатель на целое число и не инициализируется. Он передается в функцию PosNeg. Для проверки это неинициализированный указатель, передаваемый по значению функции. Попав в функцию, ей присваивается вновь выделенный массив размером cn или количеством отрицательных значений. Чтобы просмотреть еще раз, значение a в стеке присваивается понитеру вновь выделенному массиву целых чисел. Затем массиву arr присваиваются значения из a, которые никогда не были установлены. Наконец, массив a удаляется. Как вы вообще можете ожидать, что в a будут какие-то данные?

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