Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

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

‎5.4.3检查函数正确性的套路.md

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)

AltStyle によって変換されたページ (->オリジナル) /