编译器隐式地转换确定的指针类型,分配、条件表达式使用操作符==和!=,函数调用使用三种隐式的指针转换,如下节所描述,三种隐式指针转换:
l 一个指针对象类型可以隐式地转换为void指针,反之亦然;
l 一个给定类型的指针可以隐式地转换为一个该类型更合格的版本;
l 一个null指针常可以隐式地转换为任意指针类型。
Void指针为具有void *类型的指针,通常称为多用途指针,可以表示任意对象的地址,而不关心它的类型,例如,malloc()函数返回一个void指针,在你使用内存块前,void指针必须转换为指向一个对象的指针。
Example 4-1示范了void指针的多个用途,程序使用标准函数qsort() 对数组进行排序,此函数定义在头文件stlib.h中,其原型如下:
void qsort( void *array, size_t n, size_t element_size,
int (*compare)(const void *, const void *) );
qsort()以升序排列数组元素,以array地址开始,使用快速排序算法,假定函数具有n的元素,其大小为element_size。
第4个参数compare为qsort()调用的用做排序的函数指针,用来比较的两个元素的地址通过此函数指针的参数传入,通常,比较函数由程序定义,其返回值必须大于0,或小于0,或等于0,以表示第一个元素大于、或小于、或等于第二个元素。
Example 4-1. A comparison function for qsort( )
#include <stdlib.h>
#define ARR_LEN 20
/*
* A function to compare any two float elements,
* for use as a call-back function by qsort( ).
* Arguments are passed by pointer.
*
* Returns: -1 if the first is less than the second;
* 0 if the elements are equal;
* 1 if the first is greater than the second.
*/
int floatcmp( const void* p1, const void* p2 )
{
float x = *(float *)p1,
y = *(float *)p2;
return (x < y) ? -1 : ((x == y) ? 0 : 1);
}
/*
* The main( ) function sorts an array of float.
*/
int main( )
{
/* Allocate space for the array dynamically: */
float *pNumbers = malloc( ARR_LEN * sizeof(float) );
/* ... Handle errors, initialize array elements ... */
/* Sort the array: */
qsort( pNumbers, ARR_LEN, sizeof(float), floatcmp );
/* ... Work with the sorted array ... */
return 0;
}
在上面的例子中,malloc()函数返回一个void *,接着,在qsort()中对pNumbers赋值时被隐式地转换为float*,第一个参数隐式地由float*转换为void*,函数名floatcmp隐式地解释为函数指针,最终,当floatcmp()被qsort()调用时,它接收void*类型的参数,在初始化float变量前必须显式地转换为float*类型。