C++ 中的空指针
我写了这个 qsort:
void qsort(void *a[],int low,int high, int (*compare)(void*,void*));
当我调用它时,
char *strarr[5];
它说从 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;
}
I have written this qsort:
void qsort(void *a[],int low,int high, int (*compare)(void*,void*));
When I call this on
char *strarr[5];
It says invalid conversion from char** to void**. Why this is wrong?
This is the code:
#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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
允许从任何指针类型到 void * 的隐式转换,因为 void * 被定义为具有足够范围的指针类型,可以表示任何值任何其他指针类型都可以。 (从技术上讲,仅限其他对象指针类型,不包括指向函数的指针)。
但这并不意味着
void *
具有与任何其他指针类型相同的大小或表示形式:将指针从其他指针类型转换为void *
不一定保持底层表示不变。从double *
转换为void *
就像从double
转换为int
- 它必须完全发生从编译器的角度来看,您无法隐藏编译器背后的转换。因此,这意味着虽然
void *
是通用指针,但void **
不是通用指针到指针。它是一个指向void *
的指针 -void **
指针应该只指向真正的void *
对象(而void *< /code> 本身可以指向任何内容)。
这就是为什么
type **
和void **
之间没有隐式转换的原因 - 与double *
之间没有隐式转换的原因相同和int *
。现在,有一种特殊情况:由于历史原因,
char *
保证与void *
具有相同的大小、表示和对齐要求。这意味着char **
(特别是)和void **
之间的转换实际上是可以的,作为一般规则的例外。因此,在您的特定情况下,如果您在将strarr
传递给qsort1( 时向
。void **
添加强制转换,则您的代码是正确的)但是,您的
qsort1()
仅定义为在void *
或char *
数组(包括unsigned char *< /代码> 等)。例如,您不能使用它对双 * 指针数组进行排序(尽管它实际上可以在当今最常见的环境中工作)。
An implicit conversion from any pointer type to
void *
is allowed, becausevoid *
is a defined to be a pointer type that has a sufficient range that it can represent any value that any other pointer type can. (Technically, only other object pointer types, which excludes pointers to functions).This does not mean that
void *
has the same size or representation as any other pointer type, though: Converting a pointer from another pointer type to avoid *
does not necessarily leave the underlying representation unchanged. Converting fromdouble *
tovoid *
is just like converting fromdouble
toint
- it has to happen in full view of the compiler, you can't hide that conversion behind the compiler's back.So this implies that while
void *
is a generic pointer,void **
is not a generic pointer-to-pointer. It's a pointer tovoid *
- avoid **
pointer should only ever point to realvoid *
objects (whereasvoid *
itself can point to anything).This is why there's no implicit conversions between
type **
andvoid **
- it's for the same reason that there's no implicit conversions betweendouble *
andint *
.Now, there is one special case: for historical reasons,
char *
is guaranteed to have the same size, representation and alignment requirements asvoid *
. This means that conversions betweenchar **
(in particular) andvoid **
are actually OK, as an exception to the general rule. So in your particular case, your code is correct if you add a cast tovoid **
when you passstrarr
toqsort1()
.However, your
qsort1()
is only defined to correctly work on arrays ofvoid *
orchar *
(includingunsigned char *
etc.). You can't use it to sort an array ofdouble *
pointers, for example (although it would actually work on most common environments today).任何指针都可以隐式转换为 void 指针。但是您的第一个参数不是 void 指针 - 它是一个 void 指针数组,并且没有对此进行隐式转换。您可能想将您的函数声明为:
但在没有看到代码的情况下很难说。
Any pointer can be implicitly converted to a void pointer. But your first parameter isn't a void pointer - it's an array of void pointers, and there is no implicit conversion to that. You probably want to declare your function as:
but it's difficult to say without seeing the code.