我写了这个qsort:
void qsort(void *a[],int low,int high, int (*compare)(void*,void*));
Run Code Online (Sandbox Code Playgroud)
当我打电话给你
char *strarr[5];
Run Code Online (Sandbox Code Playgroud)
它表示从char**到void**的无效转换.为什么这是错的?
这是代码:
#include<cstdlib>
#include<cstdio>
#include<iostream>
using namespace std;
inline void strswap(void *a,void *b) {
char *t=*(char**)a;
*(char**)a=*(char**)b;
*(char**)b=t;
}
int strcompare(void *a, void *b) {
return strcmp(*(char**)a,*(char**)b);
}
void qsort1(void *a[],int low,int high, int (*compare)(void*,void*), void (*swap)(void*,void*)) {
if(low>=high)
return;
int q=low-1;
for(int i=low;i<=high-1;i++)
if((*compare)(&a[i],&a[high]) < 0)
swap(&a[i],&a[++q]);
swap(&a[high],&a[++q]);
qsort1(a,low,q-1,compare,swap);
qsort1(a,q+1,high,compare,swap);
}
int main() {
const int n=3;
//int a[n]={4,6,8,12,10,9,8,0,24,3};
char *strarr[5]={"abcd","zvb","cax"};
qsort1(strarr,0,n-1,strcompare,strswap);
for(int i=0;i<n;i++)
cout << strarr[i] << " ";
cout << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
caf*_*caf 12
void *允许从任何指针类型隐式转换,因为它void *被定义为具有足够范围的指针类型,它可以表示任何其他指针类型可以的任何值.(从技术上讲,只有其他对象指针类型,它排除了指向函数的指针).
但这并不意味着它void *具有与任何其他指针类型相同的大小或表示形式:将指针从另一个指针类型转换为a void * 不一定会使底层表示保持不变.从转换double *到void *就像是从转换double到int-它在编译器的众目睽睽之下发生的,你不能隐藏编译器的背后是转换.
所以这意味着虽然void *是通用指针,但void **它不是通用指针指针.它是一个指针void *- void **指针应该只指向真实void *对象(而void *它本身可以指向任何东西).
这就是为什么在type **和之间没有隐式转换void **的原因 - 这是因为double *和之间没有隐式转换int *.
现在,有一个特例:由于历史原因,char *保证具有相同的大小,表示和对齐要求void *.这意味着char **(特别是)之间的转换void **实际上是正常的,作为一般规则的例外.因此,在你特殊情况下,如果你添加一个投给你的代码是正确的void **,当你传递strarr给qsort1().
但是,您qsort1()的定义仅适用于数组void *或char *(包括unsigned char *等).例如,您不能使用它来对double *指针数组进行排序(尽管它实际上可以在当今最常见的环境中使用).
小智 10
任何指针都可以隐式转换为void指针.但是你的第一个参数不是一个void指针 - 它是一个void指针数组,并没有隐式转换.您可能希望将您的函数声明为:
void qsort(void *,int low,int high, int (*compare)(void*,void*));
Run Code Online (Sandbox Code Playgroud)
但是没有看到代码就很难说.