Застрял в цикле для ввода значений в массив на языке Си - PullRequest
0 голосов
/ 14 ноября 2018

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

#include <stdio.h>
#include <stdlib.h>

void swap(int *x, int *y)
{
    int temp = *x;
    *x = *y;
    *y = temp;
}

int *sort(int *array)
{
    int finish = 1;
    while (finish = 1)
    {
        finish = 0;
        for (int i = 0; i <= sizeof(array); i++)
        {
            if ((array + i) > (array + i + 1))
            {
                swap(array + i, array + i + 1);
                finish = 1;
            }
        }
    }
    return array;
}
int main()
{
    int s, res;
    printf("Give me the size of the array being sorted(larger than 1) : ");
    do
    {
        res = scanf("%d", &s);
        if (res != 1)
        {
            printf("Wrong Input!\n");
            exit(1);
        }
        if (s < 2)
            printf("Only numbers equal or larger than 2\n");

    } while (s < 2);
    int array[s];
    for (int i = 0; i < s; i += 1)
    {
        scanf("%d", array + i);
        printf("%d %d %d\n\n", *(array + i), i, i < s); // I used this to check if my values were ok
    }
    printf("end of reading the array"); //I added this line to see if I would exit the for loop. I am not seeing this message
    sort(array);
    printf("\n");
    for (int i = 0; i < sizeof(array); i++)
        printf("%d\n\n", array + i);
    printf("Array has been sorted! Have a nice day!\n\n************************************************************");
    return 0;
}

Ответы [ 3 ]

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

См. Аннотации в коде:

#include <stddef.h>  // size_t  1)
#include <stdio.h>
#include <stdlib.h>

void swap(int *x, int *y)
{
    int temp = *x;
    *x = *y;
    *y = temp;
}

int *sort(int *array, size_t size)  // needs an extra parameter to know the size of the array
{
    int finish = 1;
    while (finish /* = 1 * you don't want assignment, you want comparison: */ == 1)
    {
        finish = 0;
        for (int i = 0; i /* <= sizeof(array) */ < size - 1; i++)  // i should be of type size_t
        {
            // if ((array + i) > (array + i + 1)) you are not dereferencing:
            if(array[i] > array[i + 1]) 
            {
                // swap(array + i, array + i + 1);  // easier to read imho:
                swap(&array[i], &array[i + 1]);
                finish = 1;
            }
        }
    }
    return array;  // why does this function return anything? it is never used.
}
int main()
{
    int s; /* , res;  no need for an extra variable res */
    printf("Give me the size of the array being sorted(larger than 1) : ");
    do
    {
        // res = scanf("%d", &s);
        // if (res != 1)
        if (scanf("%d", &s) != 1)
        {
            printf("Wrong Input!\n");
            // exit(1);  // should be EXIT_FAILURE. Use return instead of exit() when in main().
            return EXIT_FAILURE;
        }
        if (s < 2)
            printf("Only numbers equal or larger than 2\n");

    } while (s < 2);
    int array[s];
    for (int i = 0; i < s; /* i += 1* idiomatic: */ ++i)  // size_t would be the correct type for s and i.
    {
        scanf("%d", /* array + i  use indexes: */ &array[i]);
        printf("%d %d %d\n\n", array[i], i, i < s);  // again: indexes. i < s is allready ensured by the condition of the for-loop
    }
    printf("end of reading the array");
    // sort(array);  // sort will have no idea about the size of array use
    sort(array, s); // instead.

    printf("\n");
    for (int i = 0; i < /* sizeof(array) 2) */ s; i++)
        printf("%d\n\n", /* array + i * again you don't dereference */ array[i]);
    printf("Array has been sorted! Have a nice day!\n\n************************************************************");
    return 0;
}

1) size_t - это тип, который гарантированно будет достаточно большим, чтобы в нем помещались объекты всех размеров и индексы в них. Спецификатор преобразования для scanf(): "%zu".

2) sizeof(array) в main() даст количество байтов в array, но вам нужно количество элементов, поэтому вам придется использовать sizeof(array) / sizeof(*array). Но это не нужно, так как вы уже знаете его размер. Это s.

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

Эта строка

printf("end of reading the array");

не имеет перевода строки в конце строки.Это проблема, потому что printf является частью семейства функций, называемых «буферизованный ввод-вывод».Библиотека C поддерживает буфер вещей, которые вы хотите распечатать, и отправляет их на терминал только в том случае, если буфер заполнен или встречает \n в потоке символов.Вы не увидите end of reading the array на своем экране, пока не напечатаете перевод строки.Вы делаете это только после вызова sort().Итак, все, что вы знаете, это то, что ваша программа входит в бесконечный цикл в какой-то момент до конца sort.

Итак, на самом деле есть три цикла, которые могут быть бесконечными: цикл for, который вы определили,Цикл while в цикле sort и цикл for внутри цикла while.Как указывают другие ответы, вы допустили классическую ошибку при использовании присваивания в условном while

while (finish = 1)
//            ^ not enough equals signs

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

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

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

В функции сортировки sizeof(array) возвращает размер указателя.(Вы можете проверить это самостоятельно, используя printf("%d", sizeof(array).

. Решение состоит в том, чтобы изменить вашу функцию на:

int sort(int* array, size_t size) { ... }

и вызвать ее с правильным размером массива:

sort(array, s);
...