經過qsort(void * lineptr[], int left, int rifht, int (*comp)(void *, void *))解讀指針函數和void指針

原函數是《The C programint  language 》5.11文本行排序的程序,以下:數組

void qsort(void *v[], int left, int right, int (*comp)(void *,void *)) 
{
	int i,last;
	
	if( left >= right)
		return;
	
	swap(v,left,(left+right)/2);
	last = left;
	for(i = left + 1; i <= right; ++i)
		if(comp(v[i],v[left]) < 0)
			swap(v,++last,i);
	swap(v,left,last);
	qqsort(v,left,last-1,comp);
	qqsort(v,last+1,right,comp);
}


該函數有如下特色:函數

1. 參數  void *v[] ,這是把main函數傳遞的實參轉換爲通用的void * * 類型的形參,那對於實參的須要本身強制轉換,好比把  char * lineptr[] 傳遞給  v,必須這樣(void ** )lineptr,spa

   那爲何能這樣轉化  .net

    1. 任意的類型均可以賦給相應的void類型的  指針

    2. 該void的類型也能夠強制轉換爲該類型code

   那爲何要這樣轉換  blog

   1. 這樣轉換能夠知足函數通用性的要求,任何類型均可以轉換爲相應的void類型,相對於這個程序,把char 轉換爲 void,只要在comp模型中提供了comp(char *,char *)去調用,就把void 轉換爲 char 類型進行運算,符合程序通用化的要求;排序

   2. 之因此能夠用void的1階以上指針,是由於各類類型的地址字節都是固定了,win32用4個字節表示指針,因此只要該函數內的void類型的運算都是對地址的運算均可以,不能對相應的void的類型進行四則和取值運算,由於它雖然指向對應變量的首地址,可是他不知道該地址指向的數據類型,因此除了地址運算其餘的都不能進行,也就是說使用這種轉換函數,必須保證該函數內除了地址運算外,不能進行其餘的運算。get

還有對於 形參void * v [] 去代替實參  (void **)lineptr,對於一個指向void * 的數組來講,之因此行,是由於v[1]是能夠計算,數組中存的都是指針,固定4個字節,v[1] 的地址 v + 4就好了,由由於它指向的是地址,v[1]指向一個地址,改地址又是4個字節的大小,只有這些是能夠肯定,其餘的不行,不能對v[1][1],由於v[1]是個地址,可是這個地址指向的內容的類型不能斷定,不知道把改地址指向的那塊數據取幾個字節,轉換什麼類型,都不得而知。 ast

 

還有個強制轉換問題:

char  s[3][3];

void ** p = s;

把p轉換爲s的    ((char (*)[3])p)[0] = s[0] 

 

完整的程序見:http://blog.csdn.net/chenyiming_1990/article/details/9382177

相關文章
相關標籤/搜索