C++ 中的空指针

发布于 2024-08-28 04:24:09 字数 1213 浏览 8 评论 0原文

我写了这个 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

浅语花开 2024-09-04 04:24:09

允许从任何指针类型到 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, because void * 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 a void * does not necessarily leave the underlying representation unchanged. Converting from double * to void * is just like converting from double to int - 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 to void * - a void ** pointer should only ever point to real void * objects (whereas void * itself can point to anything).

This is why there's no implicit conversions between type ** and void ** - it's for the same reason that there's no implicit conversions between double * and int *.

Now, there is one special case: for historical reasons, char * is guaranteed to have the same size, representation and alignment requirements as void *. This means that conversions between char ** (in particular) and void ** are actually OK, as an exception to the general rule. So in your particular case, your code is correct if you add a cast to void ** when you pass strarr to qsort1().

However, your qsort1() is only defined to correctly work on arrays of void * or char * (including unsigned char * etc.). You can't use it to sort an array of double * pointers, for example (although it would actually work on most common environments today).

泛泛之交 2024-09-04 04:24:09

任何指针都可以隐式转换为 void 指针。但是您的第一个参数不是 void 指针 - 它是一个 void 指针数组,并且没有对此进行隐式转换。您可能想将您的函数声明为:

void qsort(void *,int low,int high, int (*compare)(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:

void qsort(void *,int low,int high, int (*compare)(void*,void*));

but it's difficult to say without seeing the code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文