C语言中利用qsort函数对字符串数组按ASC码进行排序并输出、
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言中利用qsort函数对字符串数组按ASC码进行排序并输出、相关的知识,希望对你有一定的参考价值。
结果不对、求解释~
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<string.h>
int comp(const void *,const void *);
int main()
char name[5][20];//5个人的名字
int i;
for(i=0;i<5;i++)
scanf("%s",name[i]);//输入部分
qsort(name,5,sizeof(name[0]),comp);//排序
for(i=0;i<5;i++)
printf("%s\n",name[i]);//输出
getch();
return 0;
int comp(const void *p,const void *q)
return -strcmp(*(char **)p,*(char **)q);
int comp(const void *p,const void *q)
return -strcmp(*(char **)p,*(char **)q);//这里出了问题、代码修改如下
int comp(const void *p,const void *q)
return -strcmp((char *)p,(char *)q);//现在就可以正确排序了、、、
哪位高手能告诉我为什么?
比如p,q指向的字符串分别是"abc","def",那么不管你把p,q强制转换成几级指针,*(char **)p和*(char **)q得到的值都是字符'a'和'd'的ASCII码值,而不是整个"abc","def"字符串。然后comp函数再把'a'和'c'的ASCII码值当成两个地址去运算,当然出错了。追问
那么对int型排序为什么要先强制转换,再取值呢?
return (*(int *)p - *(int *)q);
因为C语言规定,字符串的首地址就代表整个字符串,比如char *p="abc";
那么printf("%s",p)就可以输出"abc" ,而不是printf("%s",*p);
而其他类型没有字符串的这个特性,必须用(*指针)这样的方式才能获得指针指向的值。
原来如此、
对int型排序就是要先强制转换指针类型为(int *)、然后再用(*)取值、进行比较~~~
对吧~
是的。
之所以字符串有特性,是因为国际标准规定,ASCII码值为0的字符为字符串结束符,字符串的末尾必定有字符串结束符,当然这个结束符是不可显示的。字符串结束符只被允许用于当做字符串末尾的标志,没有任何其他用途,所以,即使只给你一个字符串的首地址指针,我们只要在遍历字符串时看到数值为0的字符,就知道到字符串末尾了。
而其他类型的数据中,任何数据都可能是有意义的,所以无法规定某个值去做该类型数组的结束符,因此就无法具备数组首地址即代表整个数组这个特性了。当然,通过数组首地址还是能遍历整个数组的,只不过数组本身并没有保存数组大小的信息,所以你不知道数组的末尾在哪里。
谢谢、
解释的很清晰、你和楼上的那位都很热心、十分感激你们、
你十四级、他四级、我就采纳他的了哈~
能不能加你QQ啊?为了保护你的隐私、我说我的QQ吧、
我的QQ:1203456195
如果方便的话、交个朋友、我想往C/C++、VC方面发展~
晚安啦~
你的comp函数应该这么写:
int comp(const void *p,const void *q)
return -strcmp(*(char (*)[20])p,*(char (*)[20])q);
/* 参数为指向数组的指针,而不是指向指针的指针。
你是要从大到小排列吗?不是的话就把负号去掉。*/
追问
return -strcmp((char *)p,(char *)q);//现在就可以正确排序了、、、
为什么这样也可以呢?
因为指向数组的指针指向的是数组的首地址,也就是字符串的首地址,所以这样也可以。
追问也就是说、p和q就是字符串的指针?
追答字符串的指针就是指向字符串首地址的指针,在这种情况下等价于指向数组的指针。
你可以这么想:name是含有5个元素的数组,每个元素都是一个数组,qsort传递给比较函数的是指向元素的指针,也就是指向数组的指针,所以当name定义为二维数组或者是指针的数组的情况是不同的。
也就是说如果name的定义是
char *name[5];
的话,比较函数的参数类型就是char**了。
“qsort传递给比较函数的是指向元素的指针”这句话、说到了点上、我就困惑它传的是什么。。。。
那么、指向一个字符数组的指针、就是这个字符数组的首字母的地址了?
是的,这两个是同一个地址。
追问能不能解释下"当name定义为二维数组或者是指针的数组的情况是不同的"这句话?有什么不同?
我还有一个例子、
int main()
int i;
char *str[4] ="zha", "zhonn", "zhono", "wu";
qsort(str,4,sizeof(str[0]),comp);
//输出结果。。。
int comp(const void *p,const void *q)
return -strcmp(*(char **)p,*(char **)q);//这个就可以进行排序、
二维数组的元素是数组(char[]),而上述例子的元素为指针(char*),comp函数收到的参数为指向元素的指针,类型分别为char(*)[]和char**,而指向数组的指针指向的地址和其第一个元素的地址相同,所以情况一也可以用char*来代替指向数组的指针,而情况二中由于数组的元素为char*,comp的参数类型就是char**。
追问原来如此~
能不能加你QQ啊?为了保护你的隐私、我说我的QQ吧、
我的QQ:1203456195
如果方便的话、交个朋友~
晚安啦~
如何用c语言给输入的二维数组每一行排序
可以用stdlib.h中的qsort函数如果是int a[10][10]的话
排序第i行
qsort(a[i],10,sizeof(int),comp);
就可以了,comp是一个比较函数
int comp(const void *m1, const void *m2)
return *(int*)m1-*(int*)m2;
这样就可以排序了,如果要反序,就将comp中的m1和m2互换,可以试试,如果不对可以Hi我 参考技术A #include <stdio.h>
void main()
int a[3][4],i,j,t,m,x;
printf("输入一3×4二维整型数组:\n");
for(i=0;i<3;i++)
for(j=0;j<4;j++)
scanf("%d",*(a+i)+j);
for(x=1;x<5;x++)
for(i=0;i<3;i++)
for(t=0;t<3;t++)
if(*(*(a+i)+t+1)<*(*(a+i)+t))
m=*(*(a+i)+t+1);
*(*(a+i)+t+1)=*(*(a+i)+t);
*(*(a+i)+t)=m;
printf("每行按从小到大的排序后为:\n");
for(i=0;i<3;i++)
for(j=0;j<4;j++)
printf("%6d",*(*(a+i)+j));
printf("\n");
本回答被提问者采纳 参考技术B 这是最基本的排序算法
依次比较两个把大的放在前面
循环
循环
就可以了
以上是关于C语言中利用qsort函数对字符串数组按ASC码进行排序并输出、的主要内容,如果未能解决你的问题,请参考以下文章