Skip to content

Commit af80da3

Browse files
authored
Create 5.4.3检查函数正确性的套路.md
1 parent cb62111 commit af80da3

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# 5.4.3检查函数正确性的套路
2+
3+
- 问题:
4+
- 找到并改正以下**C函数**中的错误,该函数的本意是从单链表中删除头元素:
5+
6+
```c
7+
void removeHead(ListElement* head){
8+
free(head);// line 1
9+
head = head->next;// line 2
10+
}
11+
```
12+
13+
- 考虑4个方面:
14+
1. 检查数据是否正确进入函数
15+
1. 变量已声明。不能访问一个未声明的变量。
16+
2. 变量访问类型正确。不能用X类型去访问Y类型的变量。
17+
3. 数据足够完整。函数里应该拥有一切被需要的数据。
18+
2. 检查每一行代码。
19+
1. 验证每一行代码是否能够正确执行。
20+
2. 验证每一行代码的结果是否符合预期。
21+
3. 检查输出结果是否正确。
22+
1. 确保函数能够更新那些预期将被更新的变量。
23+
2. 确保函数的输出结果符合预期。
24+
4. 检查常见错误。
25+
1. 是否考虑了传入参数为空值的情况。
26+
2. 是否考虑了操作失败的情况。比如涉及到内存分配和I/O操作。
27+
- 解题:
28+
1. 检查数据是否正确进入函数
29+
1. 在链表中,只要给定头指针,就能访问每一个元素。所以需要的数据都可以访问。
30+
2. 检查每一行代码
31+
1. line1释放了head,这样来看是对的
32+
2. line2为head分配了一个新值head→next,但head已经在line1行被释放。
33+
3. 为解决此问题,使用一个临时变量来存储head→next,然后释放head,并使用临时变量来更新head
34+
35+
```c
36+
void removeHead(ListElement* head){
37+
ListElement *temp = head->next;// line 1
38+
free(head);// line 2
39+
head = temp;// line 3
40+
}
41+
```
42+
43+
3. 检查输出结果
44+
1. 已知:
45+
1. 在C语言中,所有函数参数按值传递,所以在函数内部中对某个值的修改不会影响到函数外部到原始变量。
46+
2. 在C语言中,变量不能按引用传递。
47+
3. 因此,当你需要在函数内部修改函数外部的变量时,需要向函数传递一个指向变量的指针,以便通过该指针来修改变量的值。
48+
49+
```c
50+
void removeHead(ListElement** head){
51+
ListElement *temp = (*head)->next;// line 1
52+
free(*head);// line 2
53+
*head = temp;// line 3
54+
}
55+
```
56+
57+
4. 检查错误条件
58+
1. 若head传入的是空,则line 1会出错。

0 commit comments

Comments
 (0)