Как обратить массив с помощью указателей в C - PullRequest
0 голосов
/ 21 марта 2019

Я пытаюсь напечатать реверс массива с помощью указателей, например.ввод 4 8 15 7, я хочу напечатать 7 15 8 4.

Когда я его запускаю, он переворачивает некоторые числа, но не все?Иногда это не меняет цифры.Я очень запутался.

Мне нужно, чтобы он работал для неизвестного числа элементов в массиве, поэтому я использовал циклы while в readIntoArray и printArray.Я действительно просто борюсь с «reverseArray» и «swap».

void reverseArray(double numbers[], int size);
void printArray(double numbers[], int size);
int readIntoArray(double numbers[]);
void swap(double *a, double *b);

int main(void) {
    double numbers[MAX_SIZE];
    int size = readIntoArray(numbers);
    reverseArray(numbers, size);
    printArray(numbers, size);
    return 0;
}

int readIntoArray(double numbers[]) {
    double in;
    int i = 0;
    while (i < MAX_SIZE && scanf("%lf", &in) != 0) {
        numbers[i] = in;
        i++;
    }
    return i;
}

void reverseArray(double numbers[], int size){
    int x = 0;
    double *a = &numbers[x];
    double *b = &numbers[size - x];
    double temp;
    while (x < size){
        swap(a,b);
        x++;
    }
}

void printArray(double numbers[], int size){
    int i = 0;
    while (i<size){
        printf("%lf ", numbers[i]);
        i++;
    }
}

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

Как мне заставить это работать?Чего мне не хватает?

Ответы [ 4 ]

2 голосов
/ 21 марта 2019

У вас есть ряд явных проблем, но основная проблема заключается в использовании вами различных размеров шрифта в swap, например.

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

Вы предоставляете тип double в качестве параметра (обычно 8-байтовое значение), но затем используете int temp; (обычно 4-байтовое значение) в качестве временного указателя. Таким образом, даже если у вас все остальное правильно, вы сохраняете только первые 4 байта *a в temp.

Далее, вы в конечном итоге дважды меняете местами (заканчиваете тем же, с чего начали), если развернетесь по всему диапазону 0 < size. Вместо этого вы хотите поменять местами каждый конечный элемент в диапазоне 0 < size / 2. Например:

void reverseArray(double numbers[], size_t size){
    for (size_t i = 0; i < size / 2; i++)
        swap (&numbers[i], &numbers[size - i - 1]);
}

( примечание: счетчики обычно должны быть size_t вместо int (у вас не может быть отрицательного числа строк))

Далее вам нужно исправить scanf валидацию. scanf() != 0 позволяет scanf() = EOF проверить TRUE, что явно не то, что вы хотите. Вы проверяете возврат по количеству спецификаторов преобразования , например

size_t readIntoArray(double numbers[]) {
    double in;
    size_t i = 0;
    while (i < MAX_SIZE && scanf("%lf", &in) == 1) {    /* <== here */
        numbers[i] = in;
        i++;
    }
    return i;
}

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

#include <stdio.h>

#define MAX_SIZE  128

size_t readIntoArray(double numbers[]) {
    double in;
    size_t i = 0;
    while (i < MAX_SIZE && scanf("%lf", &in) == 1) {
        numbers[i] = in;
        i++;
    }
    return i;
}

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

void reverseArray(double numbers[], size_t size){
    for (size_t i = 0; i < size / 2; i++)
        swap (&numbers[i], &numbers[size - i - 1]);
}

void printArray(double numbers[], size_t size){
    int i = 0;
    while (size--)
        printf("%g ", numbers[i++]);
    putchar ('\n');
}

int main(void) {

    double numbers[MAX_SIZE] = { 0 };
    size_t size = readIntoArray(numbers);
    reverseArray (numbers, size);
    printArray (numbers, size);

    return 0;
}

Пример использования / Вывод

$ echo "4 8 15 7" | ./bin/revarrswap
7 15 8 4

Посмотрите вещи и дайте мне знать, если у вас есть вопросы.

1 голос
/ 21 марта 2019

Этот код:

double *a = &numbers[x];
double *b = &numbers[size - x];
double temp;
while (x < size){
    swap(a,b);
    x++;
}

Никогда не изменяет значения a и b.Несмотря на то, что вы изменяете x, вы уже присвоили адреса первым и последующим последним элементам этим переменным и продолжаете обменивать их на все значения x.

Несколько лучшая реализация, которая должнадостичь того, что вы хотели:

for (unsigned i = 0; i != size/2; i++) {
    swap(&numbers[i], &numbers[size-i-1]);
}
0 голосов
/ 21 марта 2019

Посмотрите на функцию reverseArray():

void reverseArray(double numbers[], int size){
    int x = 0;
    double *a = &numbers[x];
    double *b = &numbers[size - x];
    double temp;
    while (x < size){
        swap(a,b);
        x++;
    }
}

Прежде всего, здесь

double *b = &numbers[size - x];

ваш код обращается к массиву сверх его размера.Если размер массива, скажем, 10, то допустимые индексы массива от 0 до 9 и size - x даст вам 10, потому что в этот момент значение x равно 0.Доступ к массиву вне его размера: неопределенное поведение .

В reverseArray() функции вы присваиваете указатели конкретным элементам массива numbers указателям a и b и не изменяя их в цикле while.В каждой итерации цикла функция swap() в конечном итоге обменивает значение одних и тех же двух указателей, и из этих двух указателей один указывает за массив.Более того, цикл повторяется size раз.Вместо этого он должен повторяться только size / 2 раз.

Значение reverseArray() должно быть таким:

void reverseArray(double numbers[], int size){
    int x = 0;
    while (x < size / 2){
        swap(&numbers[x], &numbers[(size - 1) - x]);
        x++;
    }
}

В коде есть другие проблемы, такие как использование переменной tempтипа int в swap() функция для обмена double значениями типа, без обработки scanf() возврата должным образом и т. д., что было очень хорошо объяснено @David C. Rankin в его посте.Повторять их бессмысленно.

0 голосов
/ 21 марта 2019
#include <stdio.h>

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

void reverse(double numbers[], int size) {
    int half = size / 2;

    for (int i = 0; i < half; i++) {
        swap(numbers[i], numbers[size-1-i]);
    }
}

int main() {
    double ns[5] = {1,2,3,4,5};

    reverse(ns, 5);

    for (int i=0; i<5;i++) {
        printf("%d\n", ns[i]);
    }

    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...