关于qsort比较函数中void*指针类型转换的困惑
关于qsort比较函数中指针转换的困惑解答
首先要明确:你看到的这段代码在C标准里其实是不严谨的,正确写法需要加上显式强制类型转换:
struct part *p1 = (struct part *)p; struct part *q1 = (struct part *)q;
部分编译器允许void*隐式转换为其他指针类型,但标准C要求显式转换,这点先做补充说明。
接下来解决你的核心困惑:
- qsort调用比较函数时,传入的
p和q不是指针变量本身,而是指向你要排序的数组元素的指针。比如你排序的是struct part类型的数组,p其实是数组中某个元素的地址,只是被转换成void*类型(因为qsort是通用排序函数,要兼容任意类型的数组)。 struct part *p1 = (struct part *)p;这句话的意思,是把原本指向struct part对象的void*指针,转换回struct part*类型。转换后p1和p指向同一个内存地址——也就是那个struct part类型的数组元素,而非指向p这个指针变量。
举个具体例子:
假设你有这样的数组:
struct part inventory[] = {{1, "bolt"}, {3, "nut"}, {2, "washer"}};
当qsort调用compare_parts时,会传入&inventory[0]和&inventory[1]这类地址,这些地址的原始类型是struct part*,但被转换成void*作为函数参数。转换回struct part*后,你就能通过p1->part_number访问元素的部件编号了。
你之前的误解是把p当成了struct part类型的对象,但实际上p是指向struct part对象的指针,只是类型被临时改成了void*。转换操作是让编译器重新识别这个指针的指向类型,而非让新指针指向原指针变量。
内容的提问来源于stack exchange,提问作者Urthona26
相关产品推荐
相关产品推荐

