2017-06-02 80 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

相关问题