1. 程式人生 > >關於嚴蔚敏老師《資料結構(C語言版)》書中程式碼的誤解

關於嚴蔚敏老師《資料結構(C語言版)》書中程式碼的誤解

清華大學嚴蔚敏老師的《資料結構(C語言版)》以其嚴謹被奉為經典,我是從其Pascal版一路追著買到C語言版,一直覺得這本書理論功力深厚,是不可多得的資料結構教材。但其編寫過程中為避免太過拘泥於具體語言細節,使用了ADT描述,具體演算法中使用了偽碼描述,對於新手直接把程式碼原樣照抄是沒法直接在電腦執行的,也就驗證不了書本上的程式碼執行效果,因而有人說嚴老師寫的不中不洋,不神不鬼,看到這些評論,我只想說,那是你根本沒有完整看通整本書,更沒有學好C語言,下面我就其中幾個細節演示下如何將書上程式碼上機.

一、關於預定義變數。

第一個例子,書上23頁,線性表的初始化。

/初始化線性表 
Status Init_Sqlist(sqlist *L)
{
	L->elem=(ElemType *)malloc(lIST_INIT_SIZE*sizeof(ElemType));
	if(!L->elem)
		return OVERFLOW;
	else
	{
			L->Length=0;
	        L->ListSize=lIST_INIT_SIZE;
		return OK;
	}

以上程式碼是初始化線性表的書上原碼,如果照抄到C裡,肯定會報錯,因為其中的Status、OVERFLOW、OK都是未定義的,但你把書翻到第10頁,你看他上面有什麼,預定義常量和型別呀。

#define TRUE       1
#define FALSE      0
#define OK         1
#define ERROR      0
#define OVERFLOW  -2

typedef int Status;    //函式型別,其值是函式結果狀態碼
typedef int ElemType;  //資料型別 

你把這組定義加進去,再把下面的結構體宣告加進去,你看他到底能不能跑?


#define lIST_INIT_SIZE 100
#define LISTINCREMENT  10
typedef struct 
	{
	ElemType *elem;
	int ListSize;
	int Length;
	}sqlist;

有人說你這程式碼跟書上還是不一樣呀?對的,書上使用的是&L,我這裡用的是*L,因為我是在純C裡跑,你要是在C++裡跑,照抄也行,在C裡執行,就要做一點變通。對於結構體的引用,書上用的是“.',我用的是”->“,但你要是定義的是指標,這兩種搞法都沒問題。

二、關於引用(&)和指標(*)。

第二個例子,線性表中指定刪除,書上第24頁。

Status ListDelete_Sqlsit(sqlist *L,int i,ElemType *e)
{
	ElemType *p,*q;
	
	int k;
    if(L->Length==0)
		 {
    		printf("Empty List.");
    		return ERROR;
         }
	if(i<1||i>L->Length) 
	      	 {
    		printf("illegal place.");
    		return ERROR;
         }
	p=&(L->elem[i-1]);
	e=p;
	
	///*  書上原句,原以為有問題,實際上是指標變數不會定義,囧。 
	q=L->elem+L->Length-1;
	for(++p;p<=q;++p) *(p-1)=*p;
	//*/
	
	/* 文都洪教授的寫法,其實也可行,就是沒深度。 
	for(k=i;k<L->Length;k++)
		{
		L->elem[k]=L->elem[k+1];
		}
  */
	--L->Length;
	return OK;
}

以上程式碼是做過修改後的,實際上也就是對所用的變數做了一個明確定義,比如下面這一行,

ElemType *p,*q;

然後將下面原書函式中的&引用全部重新定義成指標*。

Status ListDelete_Sqlsit(sqlist &L,int i,ElemType &e)

        歸根到底,還是對C語言的把握不到位,對地址,指標的理解不到位,所以,請按照課程的要求,務必修好先行課程再來學資料結構,不然你又要懷疑人生且出言不遜了。