简体   繁体   English

C ++中的无效指针

[英]Void pointers in C++

I have written this qsort: 我写了这个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**. 它表示从char **到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;
}

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. 允许从任何指针类型到void *的隐式转换,因为void *被定义为具有足够范围的指针类型,它可以表示任何其他指针类型可以包含的任何值。 (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 . 这并不意味着void *具有与任何其他指针类型相同的大小或表示,但是:将指针从另一个指针类型转换为void * 不一定会使底层表示保持不变 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. double *转换为void *就像从double转换为int - 它必须在编译器的完整视图中发生,你无法隐藏编译器后面的转换。

So this implies that while void * is a generic pointer, void ** is not a generic pointer-to-pointer. 所以这意味着虽然void *是一个通用指针,但void ** 不是一个通用的指向指针的指针。 It's a pointer to void * - a void ** pointer should only ever point to real void * objects (whereas void * itself can point to anything). 它是一个指向void *的指针 - 一个void **指针应该只指向真正的void *对象(而void *本身可以指向任何东西)。

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 * . 这就是为什么type **void **之间没有隐式转换的原因 - 这是因为double *int *之间没有隐式转换。

Now, there is one special case: for historical reasons, char * is guaranteed to have the same size, representation and alignment requirements as void * . 现在,有一个特例:由于历史原因, char *保证具有与void *相同的大小,表示和对齐要求。 This means that conversions between char ** (in particular) and void ** are actually OK, as an exception to the general rule. 这意味着char ** (特别是)和void **之间的转换实际上是正常的,作为一般规则的例外。 So in your particular case, your code is correct if you add a cast to void ** when you pass strarr to qsort1() . 因此,在您的特定情况下,如果在将strarr传递给qsort1()时将strarr添加到void ** ,则代码是正确的。

However, your qsort1() is only defined to correctly work on arrays of void * or char * (including unsigned char * etc.). 但是,您的qsort1()仅定义为正确处理void *char * (包括unsigned char *等)的数组。 You can't use it to sort an array of double * pointers, for example (although it would actually work on most common environments today). 例如,您不能使用它来对double *指针数组进行排序(尽管它实际上可以在当今大多数常见环境中使用)。

Any pointer can be implicitly converted to a void pointer. 任何指针都可以隐式转换为void指针。 But your first parameter isn't a void pointer - it's an array of void pointers, and there is no implicit conversion to that. 但是你的第一个参数不是一个void指针 - 它一个void指针数组,并没有隐式转换。 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. 但是没有看到代码就很难说。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM