簡體   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