2017-06-02 77 views
-2

可有人請解釋的什麼是qsort void * x和*(int *)x?

  1. *(int*)x;
  2. const void *x
  3. qsort(mass, 2*c, sizeof(int), sort)
  4. return i>0 ?i:(-1.0*i)

工作在這個代碼:

#include<bits/stdc++.h> 
using namespace std; 
#define ll long long 

int sortt(const void *x, const void *y) 
{ 
    int e=*(int*)x; 
    int e1=*(int*)y; 
    if(e>e1) 
     return 1; 
    else 
     return -1; 
} 

double abss(double i) 
{ 
    return i>0 ?i:(-1.0*i); 
} 


int main() 
{ 
    freopen("input.txt", "r", stdin); 
    freopen("output.txt", "w", stdout); 
    int n,m,i,t=1,sum; 
    while(scanf("%d %d",&n,&m)==2) 
    { 
     double avg=0,balance=0; 
     int a[15]; 
     sum=0; 
     for(i=0; i<15; i++) 
      a[i]=00000000; 
     for(i=0; i<m; i++) 
     { 
      cin>>a[i]; 
      sum+=a[i]; 
     } 
     avg=(double)sum/n; 
     for(i=m; i<2*n; i++) 
     { 
      a[i]=0; 
     } 

     qsort(a,2*n,sizeof(int),sortt); 
     printf("Set #%d\n",t++); 
     int first,last; 
     for(i=0; i<n; i++) 
     { 
      first=a[i]; 
      last=a[2*n-i-1]; 
      if(first==0 && last !=0) 
      { 
       printf(" %d: %d\n",i,last); 
      } 
      else if(first==0 && last==0) 
      { 
       printf(" %d:\n",i); 
      } 
      else 
      { 
       printf(" %d: %d %d\n",i,first,last); 
      } 
      balance+=abss(((double)first+(double)last)-avg); 
     } 
     printf("IMBALANCE = %0.5lf\n\n",balance); 
    } 
    return 0; 
} 

它是一種UVA OJ問題(410)解決 是什麼cpprefernce瞭解快速排序此排序風格,內置排序功能 CPP之間的差異,但不明白多少:(

+0

建議閱讀材料:http://en.cppreference.com/w/c/algorithm/qsort。 –

+1

不要包含。使用std :: sort。 – 2017-06-02 22:47:34

回答

0

qsort原型如下:

void qsort(
    void *base, 
    size_t nel, 
    size_t width, 
    int (*compar)(const void *, const void *) 
) 

base是一個指向要排序的內存區域的指針(a)。 nel是元素的數量(2 * c),而width是每個元素的大小(sizeof (int))。 compar是指向函數的指針,該函數應該接受指向該區域中元素的兩個指針,並返回第一個是小於(-1),等於(0)還是大於(1)。

qsort使用void指針,因爲它設計用於任何類型的操作。所以在比較功能中,你必須將轉換成這個const void*指針纔會收到適當的類型。 *(int*)x僅僅意味着「將xconst void *轉換爲int *,並將其解引用以獲得int」。

比較器接受const void *指針,因爲它不應該修改被排序數組的內容。因此,*(const int *)x在風格上稍好,因爲它保留const-度。

最後,return i > 0 ? i : -1.0 * i使用條件運算符?:,它在語義上與if相同,但以表達式而不是語句的形式;它只是意味着:

if (i > 0) 
    return i; 
else 
    return -1.0 * i; 

在C和std::sort在C++ qsort之間的區別是,C++排序保留靜態類型信息,提高了安全性,並且可以由編譯器是專門於特定類型和比較器,通過避免間接函數調用來提高性能。

+0

謝謝,但基本背後*(int *)x仍然不清楚..需要研究更多關於指針:) –

+0

但是,當我使用'sort'instaed'qsort' 不會回覆相同的值嗎? –

+1

另一個很大的區別是'std :: sort'可以處理非POD類型,而在這些類型上使用'qsort'則是未定義的行爲。 – PaulMcKenzie

0

在C中,qsort能夠排序任意數據類型(例如intdouble,自定義數據類型由struct引入,...)。由於它不知道數據類型和它們的大小,除了元素數組和元素數量之外,它還需要兩個額外的東西:(1)當算法需要交換兩個元素時必需的一個元素的大小,和(2)比較功能,其決定兩個元件xy是否x>y,x<yx==y。由於qsort可以使用任何數據類型,因此比較函數的簽名採用xy作爲數據類型void*

如果你的數組包含整數,那麼你通過sizeof(int)。比較函數需要比較整數,但它們作爲指針傳遞給void,即void* x;所以你必須將它轉回到指向int的指針,即(int*)x,然後解引用它以得到值(不是指針),即*(int*)x。 希望它有幫助。

注意,在C++ qsort被限制爲對象的trivial type

25.5 C庫函數

的qsort:...的行爲是不確定除非陣列 中的對象由基座指向是微不足道的類型。

+0

當涉及到C++時,'qsort'將不會處理任何數據類型。如果類型是非POD,那麼在這些類型的序列中使用'qsort'就是未定義的行爲。 – PaulMcKenzie

+0

@PaulMcKenzie:謝謝你的寶貴意見;一些細節:是否必須是POD? 'qsort'是指'平凡類型',它比POD限制性更小,不是嗎? –

+1

我猜如果'std :: is_trivial '返回'T'類型的'true',那麼它可以用於調用'qsort'。但我不會嘗試命運,而是總是使用'std :: sort'。在C++程序中使用'qsort'完全沒有優勢。 – PaulMcKenzie

相關問題