簡體   English   中英

如何在C中輸入指向char的指針數組?

[英]How to qsort an array of pointers to char in C?

假設我在C中有一個指向char的指針數組:

char *data[5] = { "boda", "cydo", "washington", "dc", "obama" };

我希望使用qsort對這個數組進行排序:

qsort(data, 5, sizeof(char *), compare_function);

我無法提出比較功能。 由於某種原因,這不起作用:

int compare_function(const void *name1, const void *name2)
{
    const char *name1_ = (const char *)name1;
    const char *name2_ = (const char *)name2;
    return strcmp(name1_, name2_);
}

我做了很多搜索,發現我必須在qsort里面使用**

int compare_function(const void *name1, const void *name2)
{
    const char *name1_ = *(const char **)name1;
    const char *name2_ = *(const char **)name2;
    return strcmp(name1_, name2_);
}

這很有效。

任何人都可以解釋在這個函數中使用*(const char **)name1嗎? 我根本不明白。 為什么雙指針? 為什么我原來的功能不起作用?

謝謝,Boda Cydo。

如果它有助於將事情直接放在頭腦中,那么應該在比較器中投射指針的類型與傳遞給qsort的數據指針的原始類型相同(qsort docs調用base )。 但是對於qsort是通用的,它只是將所有內容都處理為void* ,而不管它是什么“真正”。

所以,如果你正在排序一個int數組,那么你將傳入一個int* (轉換為void* )。 qsort將返回兩個指向比較器的void*指針,您將其轉換為int* ,並取消引用以獲取實際比較的int值。

現在用char*替換int

如果你正在排序一個char*數組,那么你將傳入一個char** (轉換為void* )。 qsort將返回兩個指向比較器的void*指針,轉換為char** ,並取消引用以獲取實際比較的char*值。

在您的示例中,因為您正在使用數組,所以傳入的char**char* “decaying”數組到其第一個元素的指針的結果。 由於第一個元素是char* ,因此指向它的指針是char**

想象一下,你的數據是double data[5]

您的比較方法將接收指針(double *,傳遞為void *)到元素(double)。
現在再次用char *替換double。

qsort足以排序由除指針之外的其他東西組成的數組。 這就是尺寸參數存在的原因。 它不能直接將數組元素傳遞給比較函數,因為它在編譯時不知道它們有多大。 因此它傳遞指針。 在你的情況下,你得到指向char *char **指針。

比較函數獲取指向要排序的數組中對象類型的指針。 由於數組包含char * ,因此比較函數會將指針指向char * ,即char **

來自man qsort

The  contents of the array are sorted in ascending 
order according to a comparison function pointed to by
compar, which is called with two arguments that **point**
to the objects being compared.

所以聽起來比較函數獲取指向數組元素的指針。 現在,指向char *的指針是char ** (即指向char **指針的指針)。

char *data[5] = { "boda", "cydo", "washington", "dc", "obama" };

是一個聲明,要求編譯器提供一個大小為5的字符指針數組。 你已經初始化了那些指向字符串文字的指針,但是對於編譯器來說,它仍然是一個包含五個指針的數組。

當您將該數組傳遞給qsort ,指針數組會根據C數組參數傳遞規則衰減為指向第一個元素的指針。

因此,在獲得包含常量的實際字符數組之前,必須先處理一個間接層。

@bodacydo這里有一個程序,可以解釋其他程序員試圖傳達的東西,但這將是“整數”的背景

#include <stdio.h>


int main()
{
    int i , j;
    int *x[2] = {&i, &j};

    i = 10; j = 20;

    printf("in main() address of i = %p, address of j = %p \r\n", &i, &j);

    fun(x);
    fun(x + 1);

    return 0;
}


void fun(int **ptr)
{
    printf("value(it would be an address) of decayed element received = %p, double dereferenced value is %d \r\n",*ptr, **ptr);
    printf("the decayed value can also be printed as *(int **)ptr = %p \r\n", *(int **)ptr );
}

也許從我這里給你一個代碼示例更容易。 我正在嘗試對TreeNodes數組進行排序,並且我的比較器的前幾行看起來像:

int compareTreeNode(const void* tt1, const void* tt2) {
   const TreeNode *t1, *t2;
   t1=*(const TreeNode**)tt1;
   t2=*(const TreeNode**)tt2;

之后,使用t1和t2進行比較。

暫無
暫無

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

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