Возвратите массив в C++

Предположим, что у меня есть массив

int arr[] = {...};
arr = function(arr);

У меня есть функция как

 int& function(int arr[])
 {
//rest of the code
        return arr;
 }

Какую ошибку я делаю здесь??

8
задан AndiDog 20 February 2010 в 13:20
поделиться

11 ответов

 int& function(int arr[])

В этой функции arr является указателем, и нет пути снова обратить его в массив. Это то же самое, что и

int& function(int* arr)

int arr[] = {...};
arr = function(arr);

При условии, что функции удалось вернуть ссылку на массив, это все равно не сработает. Нельзя назначить массиву. В лучшем случае вы можете связать результат с «ссылкой на массив X ints» (используя typedef, потому что синтаксис будет очень уродлив в противном случае):

typedef int ten_ints[10];

ten_ints& foo(ten_ints& arr)
{
   //..
   return arr;
}

int main()
{
    int arr[10];
    ten_ints& arr_ref = foo(arr);
}

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


Если требуется массив фиксированного размера, который можно назначить и передать по значению (с копируемым содержимым), существует std:: tr1:: array (или boost::: array ). std:: vector также является опцией, но это динамический массив, поэтому не является точным эквивалентом.

8
ответ дан 5 December 2019 в 06:09
поделиться

Семантика передачи и возврата массивов может быть довольно запутанной. Вместо этого используйте std::vector.

4
ответ дан 5 December 2019 в 06:09
поделиться

Вы возвращаете ссылку на int, а не ссылку на массив.

Вы хотите :

(int*)& function(int arr[])
{
     /// rest of the code
     return arr;
}

Однако, как уже сказали другие, это не лучшая практика.

3
ответ дан 5 December 2019 в 06:09
поделиться

Ошибка при доступе к переменной перед ее инициализацией. Значение неинициализированной переменной не равно None; доступ к нему просто вызывает исключение.

Исключение можно перехватить, если вам нравится:

>>> try:
...    foo = x
... except NameError:
...    x = 5
...    foo = 1

В классе можно задать значение по умолчанию None и проверить, изменилось ли оно в конкретном экземпляре (при условии, что None не является допустимым значением для данной переменной):

class Foo(object):
    bar = None
    def foo(self):
        if self.bar is None:
            self.bar = 5
        return self.bar
-121--4605224-

Имеются две основные проблемы:

  1. Преобразование битового представления в строку символов
  2. Выделение достаточного объема памяти для хранения символов.

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

Имеются два набора инструментов для работы с цифровой частью задачи: прямое битовое манипулирование (маскирование, сдвиг и т.д.) и арифметическая операция (*, + ,/, плюс, возможно, связь математических функций log () ).

В принципе, вы можете обращаться к побитовому представлению напрямую, но это не будет переносимым в случае, если форматы представления с плавающей запятой изменятся в будущем. Метод , предложенный edgar.holleis , должен быть портативным.

-121--1721911-

Следуя работам и не кажется грязным или неправильно понятным!

int* returnarray(int a[])
{
    for (unsigned int i = 0; i < 3; i++)
    {
        a[i] *= 2;
    }
    return a;
}

int main(int argc, char* argv[])
{
    int arr[3] = {1,2,3};
    int* p = returnarray(arr);
    for (unsigned int i = 0; i < 3; i++)
    {
        cout << "p[" << i << "] = " << p[i] << endl; 
    }
        cin.get();
        return 0;
}
3
ответ дан 5 December 2019 в 06:09
поделиться
  • Массив в качестве аргумента на самом деле является указателем. Массивы автоматически "приводятся" к указателям, если они указаны в качестве аргумента
  • В C/C++ нельзя присвоить массив другому массиву. Вам придется использовать memcpy или цикл для копирования значений.
  • Если функция изменяет аргумент arr, она фактически изменяет значение переменной arr, переданной вызывающей стороной. Опять же потому, что массив на самом деле является указателем. Поэтому в вызывающей функции arr присваивается arr, что здесь бесполезно.
1
ответ дан 5 December 2019 в 06:09
поделиться

Думаю, лучше всего вернуть его как указатель на массив. Вот пример:

{
   ...
   int newLength = 0;
   int* arr2 = ChangeArray(arr, length, newLength);
   ...
   delete[] arr2;
}

int* ChangeArray(int arr[], int length, int& newLength)
{
   // reversing the number - just an example
   int* newArr = new int[length];
   for(int i = 0; i < length; i++)
   {
      newArr[i] = arr[length-i-1];
      newLength++;
   }
   return newArr;
}
2
ответ дан 5 December 2019 в 06:09
поделиться

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

При этом вы не можете передавать или возвращать массивы по значению, и вам нужно избегать распада массива до указателя (см., Например, здесь ), используя указатели или ссылки на него:

int (&f(int (&arr)[3]))[3]
{
    return arr;
}

Если вы не хотите жестко указывать размер, вы можете использовать функции шаблона:

template<size_t n>
int (&f(int (&arr)[n]))[n]
{
    return arr;
}
6
ответ дан 5 December 2019 в 06:09
поделиться

Ну, arr совместим с int*, а не с int&. Ваш код не будет компилироваться. Возможно, вы хотели return arr[0]?

0
ответ дан 5 December 2019 в 06:09
поделиться

Используйте std:: vector следующим образом.

std::vector<int> function(const std::vector<int>& arr)
{
  return arr;
}

Массив типа

int arr[] = {...};

не полезно возвращать из функции, потому что он не может копировать сам себя.

0
ответ дан 5 December 2019 в 06:09
поделиться

Вы не можете назначить массив другому массиву в C ++. Рассмотрите возможность использования вектора STL: http://www.cplusplus.com/reference/stl/vector/

0
ответ дан 5 December 2019 в 06:09
поделиться

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

void foo(std::vector<int> &v) {
    for (int i = 0; i < 10; ++ i) {
        v.push_back(i);
    }
}

если вы используете:

std::vector<int> foo() {
    std::vector<int> v;
    for (int i = 0; i < 10; ++ i)
        v.push_back(i);

    return v;
}

будет происходить процесс копирования контейнера, это дорого стоит.

FYI: NRVO возможно устранить стоимость

0
ответ дан 5 December 2019 в 06:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: