经过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

相关文章
相关标签/搜索