c - 数据结构学习中的函数调用问题
问题描述
数据结构中的函数调用
我想删除序列表中的第i个元素,通过在main函数中调用自己定义的DelList函数来删除,但是编译后无法按预期打印出被删除元素的值。第 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);
}
编译可以通过但不是我想要的结果
解决方案
有一个小错字引起悲痛:
for (k = i; i <= L->last; k++) {
// ^
在这里,k
索引正在递增,但未针对数组末尾进行测试。写入数组末尾之后,行为未定义。
将此行更改为:
for (k = i; k <= L->last; k++) {
// ^
补充说明:
- 我建议使用
SeqList.length
而不是SeqList.last
. 迭代 fromi <= last
远不如i < length
. 单索引增加了认知负荷——您可以在将用户输入发送到您的函数之前减少用户输入以对其进行规范化,然后该函数可以对零索引数组进行操作。 - 考虑使用动态内存来避免数组的固定大小,尤其是当您从 I/O 获取数据时。至少,添加边界检查以避免缓冲区溢出。
- 如果您计划在列表中间执行频繁删除,请考虑使用双向链表。除了最右边的元素之外的数组删除是 O(n),而双向链表可以在 O(1) 中完成。缺点是没有随机访问以及与创建节点相关的一些开销。
- 使用描述性变量名称。
l
,p
,r
,q
只会阻碍调试工作。 - 使用
#include <stdbool.h>
而不是#DEFINE OK 1
. - 除非您使用的是旧编译器,否则不需要在作用域的顶部声明变量。
- 无需强制转换结果
malloc()
(尽管我意识到这个问题开始时标记为 C++)。 - 总是
free
分配内存。您可以在堆栈上声明l
和q
并使用&
引用运算符将地址传递给函数。 - 使用
int main()
andreturn 0;
from 它来通知外壳程序您的程序已成功终止。
这是一个可能的重写,它解决了其中一些问题:
#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
推荐阅读
- typescript - 打字稿中带有“this”的调用签名
- swiftui - 不能在同一个View中多次使用基于UIView的UIViewRepresentable
- reactjs - 将 Fluent UI Nav 中的 Chevron 移动到右侧
- python - 为什么梯度下降算法不收敛?
- html - 文字叠加相对定位
- php - 控制台调用未定义方法 Illuminate\Foundation\Application::where() 中的 Laravel ACL 错误
- python - 如何让 pygame 将单击鼠标识别为单击鼠标?
- postman - allauth rest_freamework CSRF 验证失败。请求中止
- android - 在Android中将变量从父视图传递到子视图
- c# - System.IndexOutOfRangeException: '索引超出了数组的范围。' 当我尝试在 C# 中将 csv 转换为 dataGridView