-
问题:
- 找到并改正以下C函数中的错误,该函数的本意是从单链表中删除头元素:
void removeHead(ListElement* head){ free(head);// line 1 head = head->next;// line 2 }
- 考虑4个方面:
- 检查数据是否正确进入函数
- 变量已声明。不能访问一个未声明的变量。
- 变量访问类型正确。不能用X类型去访问Y类型的变量。
- 数据足够完整。函数里应该拥有一切被需要的数据。
- 检查每一行代码。
- 验证每一行代码是否能够正确执行。
- 验证每一行代码的结果是否符合预期。
- 检查输出结果是否正确。
- 确保函数能够更新那些预期将被更新的变量。
- 确保函数的输出结果符合预期。
- 检查常见错误。
- 是否考虑了传入参数为空值的情况。
- 是否考虑了操作失败的情况。比如涉及到内存分配和I/O操作。
- 检查数据是否正确进入函数
- 解题:
-
检查数据是否正确进入函数
- 在链表中,只要给定头指针,就能访问每一个元素。所以需要的数据都可以访问。
-
检查每一行代码
-
line1释放了head,这样来看是对的
-
line2为head分配了一个新值head→next,但head已经在line1行被释放。
-
为解决此问题,使用一个临时变量来存储head→next,然后释放head,并使用临时变量来更新head
void removeHead(ListElement* head){ ListElement *temp = head->next;// line 1 free(head);// line 2 head = temp;// line 3 }
-
-
检查输出结果
-
已知:
- 在C语言中,所有函数参数按值传递,所以在函数内部中对某个值的修改不会影响到函数外部到原始变量。
- 在C语言中,变量不能按引用传递。
- 因此,当你需要在函数内部修改函数外部的变量时,需要向函数传递一个指向变量的指针,以便通过该指针来修改变量的值。
void removeHead(ListElement** head){ ListElement *temp = (*head)->next;// line 1 free(*head);// line 2 *head = temp;// line 3 }
-
-
检查错误条件
- 若head传入的是空,则line 1会出错。
void removeHead(ListElement** head){ if(head && *head){ ListElement *temp = (*head)->next;// line 1 free(*head);// line 2 *head = temp;// line 3 } }
-