在 c 中,如果我有 char *const* 指针,我如何访问每个元素?

in c, if i have char *const* pointer, how do i access each and every element?

这是用于qsort比较函数,

int cmp(const void *p, const void *q) {
    char *const* pp = p;
    char *const* qq = q;
    ...
}

我想比较两个字符串的元素。我试过 (*pp)[i] 因为 *pp 是 p,但它似乎不起作用。另外,以这种方式捕获 p 和 q 而不是仅仅创建两个 const char * 有什么好处?

最后但同样重要的是,我有另一个比较函数应该跳过前导空格

int wcmp(const void *p, const void *q) {

    const char *pp = p;
    const char *qq = q;
    size_t i = 0;
    size_t j = 0;

    while(isspace(*(pp+i))) {
        i++;
    }

    while(isspace(*(qq)+j)) {
        j++;
    }

    return strcmp(pp+i, qq+j);
}

但是当我用

测试它时
    d afdsa
   hello
  heal

输出是

  heal
    d afdsa
   hello

中间的"d afdsa"是怎么回事?

qsort 适用于 any 大小的元素。它可以工作的唯一方法是将 pointers 传递给元素的第一个字节,这些字节的类型为 const void *.

所以如果你有一个ints的数组,比较函数得到2个指向void的指针,实际上指向数组中的2个ints,你比较指向的对象:

int cmp(const void *p, const void *q) {
    int *pp = p;
    int *qq = q;
    return *pp - *qq; // for example, ignoring all possible UB and such.
}

同样,如果你有一个指向char的指针数组,即char *array[],那么每个元素都是一个指向char的指针,比较函数被传入2 个参数:指向这些元素的 const void 指针。当你把它们扔回去时,你会得到:

char *const *pp = p;

即指向指向 char 的常量指针的指针。您必须比较的实际对象是由这些指针指向的

这就是您的 wcmp 不起作用的原因:

int wcmp(const void *p, const void *q) {
    const char *pp = p;
    const char *qq = q;
    ...
}

如果要排序的数组中的每个元素都是 char,这将是合适的。但是元素是 pointers 到 char,所以这意味着 wcmp 的参数(每个指向数组中的一个元素)必须转换为 指向 char 的指针 :

int wcmp(const void *p, const void *q) {
    char *const *ptmp = p;
    char *const *qtmp = q;

然后您必须取消引用它们以获得指向 char

的实际指针
    char *pp = *ptmp; // dereference them
    char *qq = *qtmp; 

或者,您可以将这 2 个缩短为:

    char *pp = *(char *const *)p;
    char *qq = *(char *const *)q;

至于 wcmp 的其余部分,那不是真正的 C - 真正的 C 程序员喜欢更改指针:

    while(isspace(*pp)) {
        pp ++;
    }

    while(isspace(*qq)) {
        qq ++;
    }

    return strcmp(pp, qq);
}

即只要pp指向一个space字符,递增pp使其指向下一个字符;对 qq 也做同样的事情,然后比较第一个字符由 ppqq.

指向的字符串