2012-07-05 52 views
1

以下代碼取自here爲什麼不需要將參數傳遞給qsort比較器函數?

* qsort example */ 
#include <stdio.h> 
#include <stdlib.h> 

int values[] = { 40, 10, 100, 90, 20, 25 }; 

int compare (const void * a, const void * b) 
{ 
    return (*(int*)a - *(int*)b); 
} 

int main() 
{ 
    int n; 
    qsort (values, 6, sizeof(int), compare); 
    for (n=0; n<6; n++) 
    printf ("%d ",values[n]); 
    return 0; 
} 

我們有一個比較函數與其簽名中的參數,但是當我們在qsort中調用它時,沒有參數被傳遞。 ab的值是如何傳遞給函數的?由於

+0

與你的問題沒有關係,但是你的比較函數有一個主要的錯誤,除非你事先知道你的數組中的整數範圍受到'INT_MAX'的限制。 – 2012-07-06 03:42:12

+0

@R ..我只是把它從cpluscplus.com,謝謝您的好意 – Steve 2012-07-07 00:17:00

+0

另一個原因cplusplus.com是C和C++信息的殘暴惡劣源... – 2012-07-07 00:59:41

回答

4

在該表達式中的上下文:

qsort (values, 6, sizeof(int), compare); 

標識功能衰變成一個指向函數(而不是函數調用)子表達式compare。該代碼實際上相當於:

qsort (values, 6, sizeof(int), &compare); 

這正是發生,因爲參數的函數(你可能還是以前沒看過,但更常見)使用時,陣列同樣的事情:

void f(int * x); 
int main() { 
    int array[10]; 
    f(array);  // f(&array[0]) 
} 
+0

所以寫一個函數指針無符號只是偷懶的方法做到這一點? – Steve 2012-07-05 22:21:54

+1

在函數調用中,編譯器將函數的指針轉換爲該函數的指針。原因是,就像數組一樣,一個函數不能真正被值傳遞,所以語言具有特定的規則,這些規則將在函數聲明和調用中執行轉換。 'typedef void function(); void f(function f);'在聲明中被轉換爲'typedef void function();'void f(function * f);'並且'f(myvoidfunction)'被轉換爲'f(&myvoidfunction)'召喚地點。 – 2012-07-05 22:25:09

+0

我不會稱之爲懶惰的方式;我會稱之爲一致的方式。 '()'運算符(即函數調用運算符)將函數指針作爲其操作數。除非你到處去寫作'(功能)(...);'每次進行函數調用時,它是不一致的,當你想用一個函數的地址非呼叫目的寫'&function'。 – 2012-07-06 03:40:40

1

qsort傳遞它要比較數組中的任何一個項目的地址。例如,&values[3]&values[5]

因爲它並沒有真正瞭解實際類型的數組中的項目,它採用了size參數正確計算的地址。看到這個實現,例如:http://insanecoding.blogspot.ie/2007/03/quicksort.html

3

當調用快速排序,你傳遞一個指針,這就是爲什麼你不指定任何參數的函數。

裏面的qsort實現從「價值」陣列的動產價值和所說的「比較」功能。這就是'a'和'b'如何通過。

相關問題