возвращение двух созданных массивов в c ++ - PullRequest
5 голосов
/ 15 февраля 2010

Привет У меня есть текстовый файл, содержащий два массива и одно значение (все целые числа) как это

3 90 22 5 60 33 24

Где первое число обозначает, сколько целых чисел нужно прочитать. Я могу прочитать все это в одной функции. Нужно ли несколько функций, чтобы использовать разные матрицы и первую переменную?

    ifstream in(SOMEFILE.dat);
    if (!in) {
    cerr << "Cannot open file.\n";
    return -1;}
    in >> VAR;
    A=new int[VAR]; 
    B=new int[VAR];
    for(int i=0 ;i<VAR;i++){
      in >>A[i];
    }
 for(int i=0 ;i<VAR;i++){
      in >>B[i];
    }

       in.close();

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

I would like A to be 90 22 5
B to be 60 33 24
And VAR to be 3

Спасибо

Ответы [ 4 ]

2 голосов
/ 15 февраля 2010

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

struct Coord {
   int x, y, z;
};

и затем передайте структуру функции:

void f( Coord & c ) {
}

То же самое относится и к массивам, но в вашем случае вы бы сделали структуру содержащей указатели.

Ваш вопрос фактически открывает огромные области программирования на C ++, о которых вы, похоже, не знаете. Некоторые вещи, о которых вы должны прочитать, прежде чем идти дальше:

  • концепция конструкций, как изложено выше
  • конструкторы и деструкторы для конструкций
  • когда и когда не использовать динамическое выделение памяти
  • использование контейнеров стандартной библиотеки C ++, таких как std :: vector

Это может показаться много, но как только вы поймете это, вы найдете программирование на C ++ намного, намного проще и безопаснее.

1 голос
/ 15 февраля 2010

Самый простой способ - определить тип, скажем, структуру, которая представляет данные из одной строки:

struct MyMatrix
{
  int size;
  int *a;
  int *b;
};

Затем напишите функцию, которая читает один такой экземпляр из строки текста:

struct MyMatrix load_matrix(std::ifstream& stream)
{
  MyMatrix m;

  stream >> m.size;

  m.a = new int[m.size];
  for(int i=0 ;i < m.size; i++)
      stream >> m.a[i];

  m.b = new int[m.size];
  for(int i=0 ;i < m.size; i++)
      stream >> m.b[i];

  return m;
}

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

0 голосов
/ 15 февраля 2010

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

Вместо ручного управления памятью ваших массивов с помощью new и delete[], вы можете использовать std::vector для достижения эквивалентного поведения. Каждый вектор хранит свой собственный размер, поэтому вам не нужно возвращать для этого дополнительную переменную.

Подводя итог, в этом случае вы можете просто вернуть кортеж из двух векторов. В стандартной библиотеке двухэлементные кортежи представлены классом std::pair. Следовательно, ваша функция вернет пару векторов: std::pair<std::vector<int>, std::vector<int> >. Так как это много для ввода, лучше использовать typedef.

Это одна из возможных реализаций вашей функции. Обратите внимание, что вы можете избежать написания вручную циклов благодаря стандартному классу istream_iterator:

typedef std::pair<std::vector<int>, std::vector<int> > Data;
Data read(std::ifstream & ifs)
{
    int n;
    ifs >> n;
    typedef std::istream_iterator<int> in_it;

    std::vector<int> a(n);
    std::copy(in_it(ifs), in_it(), a.begin());

    std::vector<int> b(n);
    std::copy(in_it(ifs), in_it(), b.begin());

    return Data(a, b);
}

И вот как бы вы использовали свою функцию. Обратите внимание, что вы не возвращаете размер неявным образом, но вы можете легко получить его с помощью std::vector::size().

int main() {

  std::ifstream ifs("SOMEFILE.txt");
  Data data = read(ifs);

  unsigned int n = data.first.size();
  std::vector<int> & a = data.first;
  std::vector<int> & b = data.second;

  return 0;
}

РЕДАКТИРОВАТЬ: Предложение Нила об использовании выделенного struct лучше масштабируется и приводит к более читабельному коду, поэтому вам, безусловно, следует учитывать это. В этом случае ваша структура будет:

struct Data {
    std::vector<int> a, b;
};

И ваша main функция будет идентична, за исключением того, что вам придется заменить first и second на a и b.

0 голосов
/ 15 февраля 2010

Или просто используйте параметры по ссылке.

int theFunction(int*& arrayA, int*& arrayB){
    int size;
    // ...
    arrayA = new int[size];
    arrayB = new int[size];
    // ...
    return size;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...