這是在 C 中練習 qsort 函式的簡單代碼。
int compareF(const void *a, const void *b) {
// return (*(int**)a)[0] - (*(int**)b)[0];
const int *pr1 = *(const int **)a;
const int *pr2 = *(const int **)b;
return pr1[0] - pr2[0];
}
int main() {
int *array[] = {(int[]){2,2,3}, (int[]){1,2,1},(int[]){1,3,3},(int[]){0,2,3},(int[]){1,2,0}};
qsort(array, 5, sizeof(int[3]), compareF);
for (int i = 0; i < 5; i ) {
for (int j = 0; j < 3; j ) {
printf("%d ", array[i][j]);
}
printf("\n");
}
return (0);
}
我不明白第 3 行和第 4 行為什么用指標以這種方式進行型別轉換。這是我的理解。首先,不管我們如何使用語法,我們是否設定新變數來保存引數,就像這兩個回傳狀態一樣。其次,它需要型別大小寫,因為引數是 void 型別,所以函式不知道型別。第一個 * 用于取消參考引數 a,以便它可以訪問地址 a。我們使用 int** 因為..?
主函式中有二維整數陣列。在我的理解中,CompareF 函式每次只將 array[0] 和 array[1] 作為引數。所以我不明白為什么用兩個 ** 輸入大小寫。
相同的代碼,只修改了一行代碼
int array[3][2]= {{1,4},{3,6},{2,8}};
當陣列以這種方式定義時,型別轉換是否以同樣的方式發生?
const int *pr1 = *(const int[])a;
const int *pr2 = *(const int[])b;
要么
const int *pr1 = (const int*)a;
const int *pr2 = (const int*)b;
第一種情況不起作用,第二種情況起作用。但是它不需要 * 來取消參考嗎?喜歡
const int *pr1 = *(const int*)a;
const int *pr2 = *(const int*)b;
uj5u.com熱心網友回復:
對于初學者來說,這個呼叫 qsort
qsort(array, 5, sizeof(int[2]), compareF);
是不正確的。第三個引數是陣列元素的大小。由于陣列元素的型別是int *那么第三個引數必須是sizeof( int * )或者是相同的sizeof( *array )
qsort(array, 5, sizeof( *array ), compareF);
該函式qsort將指向陣列元素的compareF指標作為型別指標傳遞給比較函式const void *。
作為元素,如果陣列具有型別,int *則指向陣列元素的指標具有型別int **。
因此,在函式中compareF,您需要將型別的指標轉??換const void *為 types const int **。取消參考這樣的指標
const int *pr1 = *(const int **)a;
您將獲得原始陣列的一個元素。
由于陣列的元素指向具有型別的復合文字的第一個元素,因此int[3]例如pr1[0]比較函式中的運算式給出了復合文字的第一個元素,運算式pr1[1]給出了復合文字的第二個元素,依此類推。
一般使用這個return陳述句
return pr1[0] - pr2[0];
是不正確的,因為提供的運算式可能會為有符號整數型別產生溢位int。
比較復合文字的所有元素,對原始陣列的元素(指向復合文字的第一個元素的指標)進行排序會更有趣。
這是一個演示程式。
#include <stdio.h>
#include <stdlib.h>
enum { M = 3 };
int compareF( const void *a, const void *b )
{
const int *pr1 = *( const int ** )a;
const int *pr2 = *( const int ** )b;
size_t i = 0;
while ( i != M && pr1[i] == pr2[i] ) i;
return i == M ? 0 : ( pr2[i] < pr1[i] ) - ( pr1[i] < pr2[i] );
}
int main(void)
{
int * array[] =
{
(int[M]){2,2,3},
(int[M]){1,2,1},
(int[M]){1,3,3},
(int[M]){0,2,3},
(int[M]){1,2,0}
};
const size_t N = sizeof( array ) / sizeof( *array );
qsort( array, N, sizeof( *array ), compareF );
for ( size_t i = 0; i < N; i )
{
for ( size_t j = 0; j < M; j )
{
printf( "%d ", array[i][j] );
}
putchar( '\n' );
}
}
程式輸出為
0 2 3
1 2 0
1 2 1
1 3 3
2 2 3
如您所見,如果兩個復合文字的第一個元素彼此相等,則比較第二個元素,依此類推。
如果你有一個二維陣列宣告為
int array[3][2]= {{1,4},{3,6},{2,8}};
那么這意味著元素型別又是陣列型別int[2]。所以函式呼叫看起來像
qsort(array, sizeof( array ) / sizeof( *array ), sizeof( int[2] ), compareF);
And pointer to an element of the array will have the type int ( * )[2].
So dereferencing the pointer within the comparison function you will get an array of the type int[2] (an element of the original array) that that used as an expression is converted implicitly to pointer to its first element.
Here is a demonstration program.
#include <stdio.h>
#include <stdlib.h>
enum { M = 2 };
int compareF( const void *a, const void *b )
{
const int *pr1 = *( const int ( * )[M] )a;
const int *pr2 = *( const int ( * )[M] )b;
size_t i = 0;
while ( i != M && pr1[i] == pr2[i] ) i;
return i == M ? 0 : ( pr2[i] < pr1[i] ) - ( pr1[i] < pr2[i] );
}
int main(void)
{
int array[][M] =
{
{ 1, 4 }, { 3, 6 }, { 2, 8 }
};
const size_t N = sizeof( array ) / sizeof( *array );
qsort( array, N, sizeof( *array ), compareF );
for ( size_t i = 0; i < N; i )
{
for ( size_t j = 0; j < M; j )
{
printf( "%d ", array[i][j] );
}
putchar( '\n' );
}
}
The program output is
1 4
2 8
3 6
Pay attention to that the comparison function shall return 0 when two compared elements are equal each other. Relative to the function compareF it means that after the loop
size_t i = 0;
while ( i != M && pr1[i] == pr2[i] ) i;
i will be equal to M because all elements of the compared onne-dimensional arrays are equal each other.
uj5u.com熱心網友回復:
傳遞給的 compare 函式在要比較qsort任何兩個陣列元素時呼叫,它獲取每個陣列元素的地址。
int *您有一個正在排序的陣列,因此每個元素的地址都有 type int **。這與引數轉換為的型別相匹配compareF。解參考這些指標然后給我們一個型別的值,int *它實際上包含在陣列中。
此外,第三個引數 toqsort不正確。陣列元素沒有 typeint[2]而是有 type int *。如果 anint是 4 個位元組,而指標是 8 個位元組,那么它們恰好是相同的,但你不能依賴它。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/434178.html
下一篇:又是指標、&和指標?
