C: обратный массив с помощью указателей? - PullRequest
0 голосов
/ 22 ноября 2018

Я не вижу, где я сделал ошибку в этом коде:

void swap(int* a, int* b)
{
int temp = *a;

*a = *b;
*b = temp;
}

void array_reverse(int *begin, int *end)
{
    int *end2 = end;
    int *q = 0;
    for (q = begin; q < end; q += 1)
    { 
        swap(q, end2); 
        end2 -= 1;
    }
}

он должен инвертировать массив:

arr{ 1, 2, 3}

становится:

arr{ 3, 2, 1}

Мой вывод:

[ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10] 

становится:

[111009824,  2,  3,  4,  5,  6,  7,  8,  9, 10]

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

Ответы [ 3 ]

0 голосов
/ 22 ноября 2018

Иногда полное переписывание помогает выявить проблемы в оригинале.Это также уменьшает потребность в плагиате или копировании и вставке.Вот еще один способ написания цикла с использованием while.(исправлено, спасибо).

void array_reverse(int *first, int *last)
{
    int *f = first;
    int *l = last;
    while (f < l)
    { 
        swap(f, l);
        f++, l--;
    }
}
0 голосов
/ 23 ноября 2018

Были две проблемы.В цикле for end должен был быть end2.

for (q = begin; q < end2; q += 1) {
    swap(q, end2); 
    end2 -= 1; }

Другой проблемой был вызов.Это должно было быть array_reverse (a, a+9);, потому что array индексы начинаются с 0.Предоставление a+10 для второго аргумента с array длиной 10 передает указатель на бессмыслицу за пределами массива.

Я должен выразить некоторую признательность за вопрос, он заставил меня исследовать фундаментальное различие между "подстановка адресов указателей вокруг «и подстановка» данных, на которые указывают указатели.

Еще одна вещь, на которую стоит обратить внимание, состоит в том, что в C аргументы функции являются копиями по значению . Мы можем переписать array_reverse, как это без каких-либо неблагоприятных последствий. Почему это работает?

void array_reverse(int *begin, int *end)
    for ( ;begin < end; ) swap(begin++, end--)

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

0 голосов
/ 22 ноября 2018

Проблема связана с циклом for

void array_reverse(int *begin, int *end)
{
    int *end2 = end;
    int *q = 0;
    for (q = begin; q < end; q += 1)
    { 
        swap(q, end2); 
        end2 -= 1;
    }
}

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

void array_reverse(int *begin, int *end)
{
    int *end2 = end;
    int *q = 0;
    for (q = begin; q < end2; q += 1)
    { 
        end2 -= 1;
        swap(q, end2); 

    }
}

Вызов функции будет выглядеть примерно так

int test[10] = {1,2,3,4,5,6,7,8,9,10};
array_reverse(test, test + 10);
...