qsort语义 [英] qsort semantics

查看:83
本文介绍了qsort语义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个char [M] [N]类型的对象A.每个A [i]是一个包含字符串的缓冲区

,我想使用

strcmp函数对A的M个字符串进行排序。 qsort函数的描述说我必须传递指向要排序的数组的第一个对象的指针。

这导致我写下以下内容:


char A [M] [N];

int cmp(const void * a,const void * b){

int v = strcmp(*(char(*)[N])a,*(char(*)[N])b);

if(v< 0)return -1;

else if(v == 0)返回0;

否则返回1;

}

void sortA(void ){

qsort(& A [0],sizeof A / sizeof * A,sizeof * A,cmp);

}


但我也希望能够使用我的比较函数来排序其他第二个数组维度不同的字符串数组。

例如,我可能想用它对

类型char [2 * M] [2 * N]的对象进行相同的排序。然后我想像这样重写:


char A [M] [N],B [2 * M] [2 * N];

int cmp(const void * a,const void * b){

int v = strcmp(a,b);

if(v< 0)return -1 ;

否则if(v == 0)返回0;

否则返回1;

}

void sortA(void){

qsort(& A [0] [0],sizeof A / sizeof * A,sizeof * A,cmp);

}

void sortB(void){

qsort(& B [0] [0],sizeof B / sizeof * B,sizeof * B,cmp);

}


但是现在我并没有严格遵循qsort

函数的描述。我现在不是*真的*传递一个指向第一个对象的指针

要排序的数组,而不是我将指针传递给第一个

要排序的数组的第一个对象的字节。


想象一下我自己如何实现qsort函数,我知道

这样可以正常工作,但滥用qsort功能的描述

这样会让我感到不舒服。


您认为编写此类代码是否可以?

解决方案

2007年9月20日星期四00:09:12 -0700,gauss010写道:


假设我有一个char [M] [N]类型的对象A.每个A [i]是一个包含字符串的缓冲区

,我想使用

strcmp函数对A的M个字符串进行排序。 qsort函数的描述说我必须传递指向要排序的数组的第一个对象的指针。

这导致我写下以下内容:


char A [M] [N];

int cmp(const void * a,const void * b){

int v = strcmp(*(char(*)[N])a,*(char(*)[N])b);



strcmp指向const字符,而不是指向数组。

如果strcmp在这里有一个可见的原型,你可以只是

int cmp(const void * a,const void * b){return strcmp(a,b); }


K& R2使用(int(*)(const void *,const void *))strcmp作为qsort的

参数,但我认为标准委员会已将

视为UB(而const void * s必须与const char * s具有相同的

表示,这是特别不正常的

实现可以以不同的方式将它们传递给函数...)


if(v< 0)return -1;

else if(v == 0)返回0;

否则返回1;



为什么你不能回到v?


}

void sortA(void){

qsort(& A [0],sizeof A / sizeof * A,sizeof * A,cmp);

}


但我也希望能够使用我的比较功能来排序其他

第二个数组维度大小不同的字符串数组。

例如,我可能想用它对
$的对象进行相同的排序b $ b类型char [2 * M] [2 * N]。然后我想像这样重写:


char A [M] [N],B [2 * M] [2 * N];

int cmp(const void * a,const void * b){

int v = strcmp(a,b);

if(v< 0)return -1 ;

否则if(v == 0)返回0;

否则返回1;

}

void sortA(void){

qsort(& A [0] [0],sizeof A / sizeof * A,sizeof * A,cmp);

}

void sortB(void){

qsort(& B [0] [0],sizeof B / sizeof * B,sizeof * B,cmp);

}


但是现在我并没有严格遵循qsort

函数的描述。我现在不是*真的*传递一个指向第一个对象的指针

要排序的数组,而不是我将指针传递给第一个

要排序的数组的第一个对象的字节。



你传递的是void *,它们实际上是指向char的指针,上面有

的句法盐。当然,它们指向第一个字节。

qsort()知道它们的对象大小的唯一方法是b / b
指向的是,通过第二个字节和第三个

参数。

-

Army1987(将NOSPAM替换为电子邮件)

如果你是从Windows机器发送电子邮件,请关闭微软的

傻瓜??智能行情?特征。这样你就可以避免通过你的邮件洒垃圾
字符了。 - Eric S. Raymond和Rick Moen


也许使用:

int compare(const void * aa,const void * bb)

{

const char * const * a = aa;

const char * const * b = bb;

返回strcmp(a,b);

}


使用qsort比较C字符串。


On Thu,2007年9月20日12:02:28 -0700,user923005写道:


也许使用:

int compare(const void * aa,const void * bb)

{

const char * const * a = aa;

const char * const * b = bb;

返回strcmp(a,b);

}


来比较C字符串使用快速排序。



为什么?

strcmp需要两个const char * s ...


-

Army1987(将NOSPAM替换为电子邮件)

如果您要从Windows计算机发送电子邮件,请关闭Microsoft的

愚蠢的??智能行情?特征。这样你就可以避免通过你的邮件洒垃圾
字符了。 - Eric S. Raymond和Rick Moen


Suppose I have an object A of type char[M][N]. Each A[i] is a buffer
containing a string, and I want to sort the M strings of A using the
strcmp function. The description of the qsort function says that I
must pass a pointer to the first object of the array to be sorted.
This leads me to write the following:

char A[M][N];
int cmp(const void *a, const void *b) {
int v = strcmp(*(char (*)[N])a, *(char (*)[N])b);
if (v < 0) return -1;
else if (v == 0) return 0;
else return 1;
}
void sortA(void) {
qsort(&A[0], sizeof A / sizeof *A, sizeof *A, cmp);
}

But I also want to be able to use my comparison function to sort other
arrays of strings whose second array dimension is of a different size.
For example, I may want to use it to do the same sort on an object of
type char[2*M][2*N]. Then I think of rewriting it like this:

char A[M][N], B[2*M][2*N];
int cmp(const void *a, const void *b) {
int v = strcmp(a,b);
if (v < 0) return -1;
else if (v == 0) return 0;
else return 1;
}
void sortA(void) {
qsort(&A[0][0], sizeof A / sizeof *A, sizeof *A, cmp);
}
void sortB(void) {
qsort(&B[0][0], sizeof B / sizeof *B, sizeof *B, cmp);
}

But now I''m not strictly following the description of the qsort
function. I''m now not *really* passing a pointer to the first object
of the array to be sorted, rather I''m passing a pointer to the first
byte of the first object of the array to be sorted.

Imagining how I would implement the qsort function myself, I know that
this will work fine, but abusing the description of the qsort function
like this makes me uncomfortable.

Do you think it''s OK to write such code?

解决方案

On Thu, 20 Sep 2007 00:09:12 -0700, gauss010 wrote:

Suppose I have an object A of type char[M][N]. Each A[i] is a buffer
containing a string, and I want to sort the M strings of A using the
strcmp function. The description of the qsort function says that I
must pass a pointer to the first object of the array to be sorted.
This leads me to write the following:

char A[M][N];
int cmp(const void *a, const void *b) {
int v = strcmp(*(char (*)[N])a, *(char (*)[N])b);

strcmp takes pointers to const chars, not to arrays.
If strcmp has a visible prototype here, you could just
int cmp(const void *a, const void *b) { return strcmp(a, b); }

K&R2 uses (int (* )(const void *, const void *))strcmp as an
argument to qsort, but I think the standard committee has since
deemed it UB (whereas const void *s are required to have the same
representations as const char*s, a particularly perverse
implementation could pass them to functions in different ways...)

if (v < 0) return -1;
else if (v == 0) return 0;
else return 1;

Why couldn''t you just return v?

}
void sortA(void) {
qsort(&A[0], sizeof A / sizeof *A, sizeof *A, cmp);
}

But I also want to be able to use my comparison function to sort other
arrays of strings whose second array dimension is of a different size.
For example, I may want to use it to do the same sort on an object of
type char[2*M][2*N]. Then I think of rewriting it like this:

char A[M][N], B[2*M][2*N];
int cmp(const void *a, const void *b) {
int v = strcmp(a,b);
if (v < 0) return -1;
else if (v == 0) return 0;
else return 1;
}
void sortA(void) {
qsort(&A[0][0], sizeof A / sizeof *A, sizeof *A, cmp);
}
void sortB(void) {
qsort(&B[0][0], sizeof B / sizeof *B, sizeof *B, cmp);
}

But now I''m not strictly following the description of the qsort
function. I''m now not *really* passing a pointer to the first object
of the array to be sorted, rather I''m passing a pointer to the first
byte of the first object of the array to be sorted.

You''re passing void *, which are essentially pointers to char with
syntactic salt on them. Of course they point to the first byte.
The only way for qsort() to know how large the objects they are
intended to point to are, is through the second and third
argument.
--
Army1987 (Replace "NOSPAM" with "email")
If you''re sending e-mail from a Windows machine, turn off Microsoft''s
stupid a??Smart Quotesa?? feature. This is so you''ll avoid sprinkling garbage
characters through your mail. -- Eric S. Raymond and Rick Moen


Maybe use:
int compare (const void *aa, const void *bb)
{
const char * const *a = aa;
const char * const *b = bb;
return strcmp (a, b);
}

to compare C strings using qsort.


On Thu, 20 Sep 2007 12:02:28 -0700, user923005 wrote:

Maybe use:
int compare (const void *aa, const void *bb)
{
const char * const *a = aa;
const char * const *b = bb;
return strcmp (a, b);
}

to compare C strings using qsort.

Why?
strcmp takes two const char *s...

--
Army1987 (Replace "NOSPAM" with "email")
If you''re sending e-mail from a Windows machine, turn off Microsoft''s
stupid a??Smart Quotesa?? feature. This is so you''ll avoid sprinkling garbage
characters through your mail. -- Eric S. Raymond and Rick Moen


这篇关于qsort语义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆