天天看點

Pointers on C——12 Using Structures and Pointers.3

Debugging the Insert Function

調試插入函數

Unfortunately, the insert function is incorrect. Try inserting the value 20 into the list and you will see one problem: the while loop runs off the end of the list and then applies indirection to a NULL pointer. To solve this problem, we must test current to make sure that it is not NULL before evaluating current->value:

不幸的是,這個插入函數是不正确的。試試把2 0這個值插入到連結清單中,你就會發現一個問題:while 循環越過連結清單的尾部,并對一個NULL 指針執行間接通路操作。為了解決這個問題,我們必須對current的值進行測試,在執行表達式current->value 之前確定它不是一個NULL 指針:

while( current != NULL && current->value < value ){

The next problem is tougher. Trace the function to insert the value 3 into the list. What happens?

下一個問題更加棘手,試試把3 這個值插入到連結清單中,看看會發生什麼?

In order to add a node to the beginning of the list, the function must change the root pointer. The function, however, cannot access the variable root. The easiest way to fix this problem is to just make root a global variable so that the insertion function can modify it. Unfortunately, this approach is also the worst  way to fix the problem,because then the function works only for that one list.

為了在連結清單的起始位置插入一個節點,函數必須修改根指針。但是,函數不能通路變量root 。修正這個問題最容易的方法是把root 聲明為全局變量,這樣插入函數就能修改它。不幸的是,這是最壞的一種問題解決方法。因為這樣一來,函數隻對這個連結清單起作用。

The better solution is to pass a pointer to root as an argument. Then the function can use indirection both to obtain the value of root (the pointer to the first node of the list), and to store a new pointer into it. What is the type of this parameter?root is a pointer to a Node, so the parameter is of type Node **: a pointer to a pointer to a Node. The function in Program 12.2 contains these modifications. We must now call the function like this:

稍好的解決方法是把一個指向root 的指針作為參數傳遞給函數。然後,使用間接通路,函數不僅可以獲得root (指向連結清單第1 個節點的指針,也就是根指針〉的值,也可以向它存儲一個新的指針值。這個參數的類型是什麼呢? root 是一個指向Node 的指針,是以參數的類型應該是Node **,也就是一個指向Node 的指針的指針。程式12.2 的函數包含了這些修改。現在,我們必須以下面這種方式調用這個函數:

result = sll_insert( &root, 12 );

Pointers on C——12 Using Structures and Pointers.3
Pointers on C——12 Using Structures and Pointers.3
Pointers on C——12 Using Structures and Pointers.3

This second version contains some additional statements.

這第2 個版本包含了另外一些語句。

previous = NULL;

is needed so that we can check later whether the new value will be the first node in the list.

我們需要這條語旬,這樣我們在以後就可以檢查新值是否應為連結清單的第1 個節點。

current = *rootp;

uses indirection on the root pointer argument to get the value of root, a pointer to the first node in die list. Finally

這條語句對根指針參數執行間接通路操作,得到的結果是root 的值,也就是指向連結清單第1 個節點的指針。

if( previous == NULL )

*rootp = new;

else

previous->link = new;

was added to the end of the function. It checks whether the new value should be added to the beginning of the list. If so, we use indirection on the root pointer to make root point to the new node.

這條語句被添加到函數的最後。它用于檢查新值是否應該被添加到連結清單的起始位置。如果是,我們使用間接通路修改根指針,使它指向新節點。

This function works, and in many languages it is as good as you can get.However, we can do better because C allows you to get the address of (a pointer to) existing objects.

這個函數可以正确完成任務,而且在許多語言中,這是你能夠獲得的最佳方案。但是,我們還可以做得更好一些,因為C 允許我們獲得現存對象的位址〈即指向該對象的指針〉。

上一章 Pointers on C——12 Using Structures and Pointers.2