打印 void* 类型的值

Printing values of type void*

在下面:

int cmp (void* x, void*y) {
    printf("x: %s | y: %s\n", (char*) x, (char*) y);
    return 0;
}

int main(int argc, char *argv[]) {
    char * strings[] = {"xml", "json"};
    qsort(strings, sizeof(strings), sizeof(strings[0]), cmp);
}

如何查看 xy 的值?当前的方法会产生乱码,例如:

x: 2?|?? | y: 2?|??

sizeof(strings) 不是 return strings 中的元素数量,而是更大的元素。你的程序是不安全的。你想要 sizeof(strings)/sizeof(strings[0]).

虽然为第三个参数传递 sizeof(argv[0]) 恰好有效,但你真的应该说 sizeof(strings[0]) 否则你的代码很难阅读。

乱码是由 qsort 读取数组 strings 范围外并将野指针传递给 cmp 引起的。大多数废话是不可打印的,所以你得到了很多?字符。

Nate Eldredge 抓住了另一半。 ab 参数 cmp 应该转换为 char ** 而不是 char *.

再次阅读 qsort 的文档。传递给比较函数的参数不是要比较的对象,它们是指向这些对象的指针。所以 x,y 不是字符串本身(即指向字符串字符的指针),而是指向这些指针的指针。

所以你想写

int cmp (void *x, void *y) {
    printf("x: %s | y: %s\n", *(char**) x, *(char**) y);
    return 0;
}

另见 Joshua 关于 qsort 的大小参数问题的回答。

最后,qsort 比较函数应该接受指向 const void 的指针,而不仅仅是 void。当您不打算修改它们时,最好保留 const 。在这种情况下,您不打算修改 x 指向的指针,也不打算修改 *x 指向的字符。所以写成

会更好
int cmp (const void *x, const void *y) {
    printf("x: %s | y: %s\n", *(const char* const *) x, *(const char* const *) y);
    return 0;
}