繁体   English   中英

在 qsort function 中执行指向字符串的正确方法

[英]Proper way to do a pointer-to-string in a qsort function

假设我有一个要排序的字符串数组,例如:

{"one", "two", "three", "four"};

使用qsort传递这些字符串时正确的转换操作是什么?

int scmp(const void *p1, const void *p2) {
    // string1 = ???   
};

我的想法是该项目将是“指向字符串的指针”,并且由于字符串是“指向字符的指针”,这会给我一个“指向指针的字符”。 以下是正确的方法吗?

// 1. Pointer-to String
(String) *

// 2. String = Pointer-to-char
(char*) *

// 3. What about const-ness? Doesn't qsort require the 'value' to be const? 
//    Also, what about string = unsigned char -- is that important here?
(const char*) *

那么, string1的正确定义是:

int scmp(const void *p1, const void *p2) {
    const char* string1 = (const char**) p1;
};

是正确的方法吗? 您可以看到弄清楚指针声明(或在本例中为强制转换)是多么乏味(至少对我而言)。 有没有更直接的方法来做到这一点 - 也就是说,如果我知道我想要一个“指向unsignedconst ”,我可以在不到5分钟?

qsort提供比较 function 与两个指向数组元素的 const 指针开始排序。 您正在对“字符串”数组进行排序,也就是说char*数组。 char*数组是char*[] ,指向此类数组中元素的指针是指向char*的指针,即char** ,指向该数组中元素的 const 指针是char*const* .

您可能最终会使用strcmp来比较两个字符串或类似的东西。 如果它是strcmp本身,你最终会得到:

int scmp(void const* va, void const* vb) {
  const char* a = *(char* const*)va;
  const char* b = *(char* const*)vb;
  return strcmp(a, b);
}

我在ab中添加了不必要但无害的const限定符,因为strcmp不会改变它的 arguments。 除此之外,示例代码与您在man qsort中查看示例代码时所发现的非常相似

由于qsort()如何使用指向元素的指针,这有点混乱,所以如果元素本身是指针,那么您需要以某种方式将void*转换为char* ,但还要在此过程中取消对它的引用。

下面是一个如何编写 function 的示例:

int qs_strcmp(const void* a, const void* b) {
  return strcmp(*((const char**) a), *((const char**) b));
}

还有一个测试程序来展示它是如何工作的:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>


int main(void) {
  char *list[] = {
    "boba",
    "dada",
    "zapa",
    "cobb",
    "acdc",
    "abba"
  };

  int list_len = sizeof(list) / sizeof(char*);

  qsort(&list[0], list_len, sizeof(char*), qs_strcmp);

  for (int i = 0; i < list_len; ++i) {
    printf("%s\n", list[i]);
  }

  return 0;
}

暂无
暂无

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

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