Проблема вызова функции в изучении структуры данных - PullRequest
2 голосов
/ 22 июня 2019

вызов функции в структуре данных

Я хочу удалить i-й элемент таблицы последовательности и удалить его, вызвав мою собственную определенную функцию DelList в главной функции, но после компиляции я могу 't распечатать значение удаленного элемента, как и ожидалось.Код перед строкой 48 работает нормально, но кажется, что функция DelList не может быть вызвана, в результате чего удаленные элементы не будут напечатаны.Есть ли проблема с вызовом функции DelList?Или есть проблема с возвратом функции DelList?Спасибо

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

#define MAXSIZE 100  
#define OK 1
#define ERROR 0

typedef int ElemType;  /*Assume that the data elements in the sequence table 
                        are integers*/
typedef struct {
    ElemType elem[MAXSIZE];
    int last;
}SeqList;

int  DelList(SeqList *L, int i, ElemType *e)
/*The i-th data element is deleted in the sequence table L, and its value is returned with the pointer parameter e. The legal value of i is 1 ≤ i ≤ L. last +1 */
{
    int k;
    if ((i < 1) || (i > L->last + 1))
    {
        printf("Deleting the location is not legal!");
        return(ERROR);
    }
    *e = L->elem[i - 1];  /* Store the deleted element in the variable pointed to by e*/
    for (k = i; i <= L->last; k++)
        L->elem[k - 1] = L->elem[k];  /*Move the following elements forward*/
    L->last--;
    return(OK);
}

void main()
{
    SeqList *l;
    int p, r;
    int *q;
    int i;
    l = (SeqList*)malloc(sizeof(SeqList));
    q = (int*)malloc(sizeof(int));
    printf("Please enter the length :");
    scanf("%d", &r);
    l->last = r - 1;
    printf("Please enter the value of each element:\n");
    for (i = 0; i <= l->last; i++)
    {
        scanf("%d", &l->elem[i]);
    }
    printf("Please enter the location of the element you want to delete:\n");
    scanf("%d", &p);
    DelList(l, p, q);
    printf("The deleted element value is:%d\n", *q);
}

Компиляция может пройти, но не тот результат, который я хочу

1 Ответ

3 голосов
/ 22 июня 2019

Существует небольшая опечатка, вызывающая горе:

for (k = i; i <= L->last; k++) {
//          ^

Здесь индекс k увеличивается, но не проверяется относительно конца массива.После записи после конца массива поведение не определено.

Измените эту строку на:

for (k = i; k <= L->last; k++) {
//          ^

Дополнительные замечания:

  • Iрекомендуем использовать SeqList.length вместо SeqList.last.Итерации с i <= last гораздо менее естественны, чем i < length.Одноиндексирование увеличивает когнитивную нагрузку - вы можете уменьшить пользовательский ввод, чтобы нормализовать его, прежде чем отправлять в свою функцию, которая затем может работать с массивом с нулевым индексом.
  • Рассмотрите возможность использования динамической памяти , чтобы избежать фиксированного размера массива, особенно если вы берете данные из ввода / вывода.Как минимум добавьте проверку границ, чтобы избежать переполнения буфера .
  • Попробуйте использовать двусвязный список , если вы планируете выполнять частые удаления в серединесписок.Исключением из массива, кроме самого дальнего правого элемента, является O (n), в то время как двусвязный список может сделать это в O (1).Недостатком является отсутствие произвольного доступа и некоторые накладные расходы, связанные с созданием узлов.
  • Использование описательных имен переменных.l, p, r, q будут только мешать усилиям по отладке.
  • Используйте #include <stdbool.h> вместо #DEFINE OK 1.
  • Если вы не включеныстарый компилятор, переменные не нужно объявлять в верхней части области.
  • Не нужно приводить результат malloc() (хотя я понимаю, что этот вопрос начинался с тега C ++).
  • Всегда free выделенная память.Вы можете объявить l и q в стеке и использовать оператор ссылки & для передачи адреса в функции.
  • Используйте из него int main() и return 0;уведомить оболочку об успешном завершении вашей программы.

Вот возможная перезапись, которая затрагивает некоторые из этих пунктов:

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

typedef struct {
    int *data;
    int length;
} SeqList;

bool list_delete(SeqList *list, int idx_to_remove, int *removed_element) {
    if (idx_to_remove < 0 || idx_to_remove >= list->length) {
        return false;
    }

    *removed_element = list->data[idx_to_remove];
    list->length--;

    for (int i = idx_to_remove; i < list->length; i++) {
        list->data[i] = list->data[i+1];
    }

    return true;
}

int main() {
    SeqList list;
    int deleted_element;
    int idx_to_delete;

    printf("Please enter the length: ");
    scanf("%d", &list.length);
    list.data = malloc(sizeof(int) * list.length);

    for (int i = 0; i < list.length; i++) {
        printf("Enter the value for element %d: ", 1 + i);
        scanf("%d", &list.data[i]);
    }

    do {
        printf("Please enter the index of the element you want to delete: ");
        scanf("%d", &idx_to_delete);
    } while (!list_delete(&list, idx_to_delete - 1, &deleted_element));

    printf("The deleted element value is: %d\n", deleted_element);
    puts("The elements left in the list are:");

    for (int i = 0; i < list.length; i++) {
        printf("%d ", list.data[i]);
    }

    puts("");
    free(list.data);
    return 0;
}

Пример выполнения:

Please enter the length: 4
Enter the value for element 1: 11
Enter the value for element 2: 22
Enter the value for element 3: 33
Enter the value for element 4: 44
Please enter the index of the element you want to delete: 6
Please enter the index of the element you want to delete: -1
Please enter the index of the element you want to delete: 5
Please enter the index of the element you want to delete: 4
The deleted element value is: 44
The elements left in the list are:
11 22 33
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...