2013-09-26 2 views
0

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

#include<iostream> 

    using namespace std; 

    void printArray(int a[], const int n) 
    { 
     for(int i=0;i<n;i++) 
     { 
      cout<<a[i]; 
      i!=n-1 ? cout<<", " : cout<<""; 
     } 
    } 

    void reverse(int a[], const int n) 
    { 
     int reverse[n]; 
     for(int i=0;i<n;i++) 
     { 
      reverse[n-1-i]=a[i]; 
     } 
     a = reverse; 
    } 

    int main() 
    { 
     int *a,n; 
     cin>>n; 
     a = new int[n]; 
     for(int i=0;i<n;i++) 
      a[i]=0; 
     a[0]=1; 
     reverse(a,n); 
     printArray(a,n); 
     delete [] a; 
     a = NULL; 
     return 0; 
    } 

После вызова функции обратного хода массив из основного не изменяется, пожалуйста, совет! :(

+3

Вам необходимо передать массив по ссылке, а не по значению. – Jamal

+0

@Jamal, но также избежать утечки памяти и потенциально ссылаться на мертвый объект – vlad

+0

@vlad: О, да, здесь используется и «новый». Я пропустил это. – Jamal

ответ

4

Вы не копировать данные из reverse обратно a. - вы вместо того, чтобы указывать его (a) в ячейку памяти, которая больше не будет существовать (действительна) после вашего возвращения функции необходимо скопировать значения от reverse назад a. и я не рекомендовал бы использовать то же имя для функции и переменной.

Попробуйте

void reverse(int a[], const int n) 
{ 
    int reverse[n]; 
    for(int i=0;i<n;i++) 
    { 
     reverse[n-1-i]=a[i]; 
    } 
    for(int i=0;i<n;i++) 
    { 
     a[i]=reverse[i]; 
    } 
} 

как было отмечено в комментариях, выше показывает один способ получения обратных данных в массив a. Это не единственный способ - memcpy считается более эффективной функцией. Еще более эффективным было бы сделать на месте разворот - для этого потребовался бы цикл только n/2 итераций, в то время как вышеперечисленные петли для 2n и, следовательно, примерно на 4x менее эффективны.

Я рекомендую вам изучить все предоставленные ответы - они выделяют различные аспекты обработки памяти, эффективности кода и т. Д .; что-то узнать у всех из них.

+2

Или с одним 'for-loop':' for (int i = 0; i

+0

От того, как формулируется вопрос, похоже, что они ищут замену элементов на месте, но это может быть только я. Тем не менее, на месте, безусловно, предпочтительнее выделять и копировать? – Skizz

+1

Я согласен с тем, что было бы целесообразным разворот на месте. Я пытался «изменить как можно меньше кода», поскольку OP, похоже, пытается понять «что не так с« a = reverse »,«? » а не «делать домашнее задание для меня, поэтому я получаю A». Метод ZacHowland, очевидно, более эффективен. – Floris

5

Вы не можете назначить один массив другому. Вместо копия из reverse обратно в a:

std::copy(reverse, reverse + n, a); 

Или, возможно,

memcpy(a, reverse, n * sizeof(int)); 
0

Ага, вы знаете, вы должны пройти int a[], указатель на a, чтобы reverse(), но вы по-прежнему сталкиваются с той же проблема. Вы не можете изменить указатель, хранящийся в a, если вы не пройдете & a до reverse().

+1

И даже если бы он это сделал - это место памяти будет недействительным после возвращения функции. – Floris

+0

Да, это стек памяти – Chen

1

Указатели! Они действительно полезны.

void reverse (int *a, const size_t n) 
{ 
    int *b = a + n - 1; 
    while (b > a) 
    { 
    const int swap_value = *a; 
    *a = *b; 
    *b = swap_value; 
    ++a; 
    --b; 
    } 
} 
+0

Бонусные баллы, если вы его изменяете, чтобы требовать только одного приращения на итерацию вместо увеличения и уменьшения;) –

Смежные вопросы