簡體   English   中英

qsort 中的 const 限定符比較 function

[英]const qualifier in qsort compare function

我有這個用 qsort 以兩種方式對字符串數組( argv本身)進行排序。 我從 linux man 3 qsort示例開始。 cmpstringp只有一行:

 /* The actual arguments to this function are "pointers to
    pointers to char", but strcmp(3) arguments are "pointers
    to char", hence the following cast plus dereference */

 return strcmp(*(const char **) p1, *(const char **) p2);

我試圖重新制定它,它編譯時沒有警告只有

char *const* sp1 = vep1

const屬於中間 - 它是argv條目(?)。 至少這是 qsort 聲明所要求的。 上面來自手冊頁的演員表似乎不同且復雜。

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

/* vep: void pointer to elements being qsorted 
   sp: string pointer (char **)            */
int 
cmpstringp(const void *vep1, const void *vep2) {

    char *const *sp1 = vep1,
         *const *sp2 = vep2;

    return strcmp(*sp1, *sp2);
}
/* Make char* from void*, and even char    */
int 
cmpchar(const void *p1, const void *p2) {

    const char *cp1 = p1,
               *cp2 = p2;

    char c1 = *cp1,
         c2 = *cp2;

    if (c1 == c2)
        return 0;
    else
        return c1 > c2 ? 1 : -1;
}

/* Sort cmd line args in two ways with qsort */
int main(int argc, char **argv) {

    /* sort chars of each string */
    for (int i = 1; i < argc; i++)
    qsort(argv[i],                  // base / first  
          strlen(argv[i]), 1,       // n_elems, elem_size
          cmpchar);

    /* sort argv strings 1 to argc-1 */
    qsort(argv + 1,
          argc - 1, sizeof *argv,
          cmpstringp);

    for (int j = 1; j < argc; j++)
        puts(argv[j]);

    return 0;
}

第二個 cmp function cmpchar有一個額外的分配級別。 沒有的話,只會有一些無害的星星,比如if (*cp1 == *cp2)

如何對 C 中的 argv 元素進行排序? 有一個類似手冊頁的解決方案,直接在strcmp()中進行轉換。

但是我的免演員方法不是更正確嗎? 在我將const放在它所屬的位置之前,我收到了警告。

char * const char *const *sp1 = vep1中間的 const 表示 * *sp1指定的任何內容都是const 這是必需的,因為const void *表示指針直接指向的 memory 應該是const

你是對的, const void *在沒有強制轉換的情況下不能分配給const char **因為它不是 const 正確的。 我個人盡量避免強制轉換,因此我更喜歡你的代碼而不是使用強制轉換的代碼。

但是,使用const char *const *sp1會更正確一些,因為cmpstringp沒有理由實際上也不適用於const char **

重新排序和對齊后,從右到左轉換和保留的內容變得更加清晰:

   int cmpstringp(void const *vep1, const void *vep2) {
    
                char * const *sp1    = vep1, ...

const被復制,並且“to void”被“to pointer(to char)替換。它甚至不必是指針(例如結構)。如果,那么我懷疑這個 const-ness 可以傳播到所有引用,只是因為“比較” function 根本不應該修改。它可能會修改所有對象,但不能修改正在排序的對象。

這一切都很有趣,但邏輯上很復雜。 就像有一排盒子里面有字母。 首先,您根據自己對每個框內的字母進行排序(不觸摸框),然后根據字母對框進行排序(但不觸摸它們,字母)。

感謝您的評論和回答。


6.5.16.1 簡單賦值可能會處理這種情況。

指針分配的 3 個項目符號似乎需要:

  • 兼容的類型,或者一個是無效的
  • 左側具有右側的所有限定符。
  • null 指針在右邊沒問題

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM