[英]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.