免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 3596 | 回复: 10
打印 上一主题 下一主题

[函数] 关于指向函数的指针问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-03-07 20:50 |只看该作者 |倒序浏览
自己 看the c programming  language这本书的时候,敲了一段代码如下:
/*此程序实现的功能对输入的文本行用快速排序算法进行排序,排序时分为两种情况当命令行参数为-n时按数字大小排序,否则按照首字符的ASCII码排序*/
#include<stdio.h>
#include<string.h>
//#include<stdlib.h>
#define MAXLINES 5000//待排序的最大行数
#define MAXLEN 1000/*每个输入文本行的最大长度*/
char * lineptr[MAXLINES];
int readlines(char * lineptr[],int nlines);
void writelines(char * lineptr[],int nlines);
void qsort(void *lineptr[],int left,int right,
           int (*comp)(void *,void *));
int numcmp(char *,char *);
void swap(void * v[],int i ,int j );
/*对输入文本行进行排序*/
main(int argc,char * argv[])
{
    int nlines;/*读入的输入行数*/
    int numeric=0;/*若进行数值排序,则numeric的值为1*/
    if(argc>1&&strcmp(argv[1],"-n")==0)
      numeric=1;
    if((nlines=readlines(lineptr,MAXLINES))>=0)
    {
      qsort((void **)lineptr,0,nlines-1,
   /*第23行*/  (int(*)(void *,void *))(numeric?numcmp:strcmp));
      writelines(lineptr,nlines);
      return 0;
    }
    else
    {
            printf("input too big to sort\n");
            return 1;
    }
}
/*qsort函数:以递增顺序对v[left]...v[right]进行排序*/
void qsort(void *v[],int left,int right,
            int (*comp)(void *,void *))
{
        int i,last;
        if(left>=right)
                return;
        swap(v,left,(left+right)/2);
        last=left;
        for(i=left+1;i<right;i++)
                if((*comp)(v,v[left])<0)
                 swap(v,++last,i);
        swap(v,left,last);
         qsort(v,left,last-1,comp);
         qsort(v,last+1,right,comp);
}
/*numcmp函数:按数值比较字符串S1,S2的大小*/
int numcmp(char *s1,char *s2)
{
  double v1,v2;
  v1=atof(s1);
  v2=atof(s2);
  if(v1<v2)
          return -1;
  else if(v1>v2)
          return 1;
  else
          return 0;
}
void swap(void *v[],int i ,int j)
{
        void *temp;
        temp=v;
        v=v[j];
        v[j]=temp;
}
/*readlines函数:读取输入行*/
int readlines(char * lineptr[],int maxlines)
{
}
gcc编译出错 信息为:
Qsort.c: In function `main':
Qsort.c:23: warning: pointer type mismatch in conditional expression
我的理解是23行条件表达式中指针类型不匹配,可仔细看了好久,百思不得其解,希望得到大家的帮助。
先谢谢了。

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
2 [报告]
发表于 2007-03-07 21:34 |只看该作者
(int(*)(void *,void *))(numeric?numcmp:strcmp))

改成:

(numeric ? (int(*)(void *,void *))numcmp : (int(*)(void *,void *))strcmp))

论坛徽章:
0
3 [报告]
发表于 2007-03-07 21:46 |只看该作者
谢谢,问题解决了,可是为你什么分开写就可以编译通过,我合起来写就不行了呢?而且我的写法和书上的是一样的,希望得到你的解答。

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
4 [报告]
发表于 2007-03-07 21:57 |只看该作者
或者把
int numcmp(char *s1,char *s2)
改成:
int numcmp(const char *s1, const char *s2)
也行。
这样刚才改动的地方就不用改了。
我想是现在的编译器更加严格,所以会有一个warning。
对于exp1?exp2:exp3,要求exp2和exp3的类型应该一致
或者它们可以符合自动类型转换规则。
而且warning里面已经说了:pointer type mismatch
我想你应该清楚了。

论坛徽章:
0
5 [报告]
发表于 2007-03-08 16:38 |只看该作者

又遇到新问题

你的意思是strcmp函数原型是int strcmp(const char * s1,const char * s2)所以numcmp的参数也要换成const的指针是吗?
我现在将程序完成后编译是通过了,运行时又遇到了一个段错误,我用gdb调试逐步执行,发现是到85行出现的这个错误,想了好久找了好久还是不知道错误究竟出在哪啊?现再一次把完整代码帖出,希望能得到大家的帮助。85行strcpy(p,line);已经加粗。
/*此程序实现的功能对输入的文本行用快速排序算法进行排序,排序时分为两种情况当命令行参数为-n时按数字大小排序,否则按照首字符的ASCII码排序*/
#include<stdio.h>
#include<string.h>
//#include<stdlib.h>
#define MAXLINES 5000//待排序的最大行数
#define MAXLEN 1000/*每个输入文本行的最大长度*/
char * lineptr[MAXLINES];
int readlines(char * lineptr[],int nlines);
void writelines(char * lineptr[],int nlines);
void qsort(void *lineptr[],int left,int right,
           int (*comp)(void *,void *));
int numcmp(const char *,const char *);
void swap(void * v[],int i ,int j );
int getline(char line[],int maxline);
/*对输入文本行进行排序*/
main(int argc,char * argv[])
{
    int nlines;/*读入的输入行数*/
    int numeric=0;/*若进行数值排序,则numeric的值为1*/
    char oneline[1024];
    if(argc>1&&strcmp(argv[1],"-n")==0)
      numeric=1;
    if((nlines=readlines(lineptr,MAXLINES))>=0)
    {
      qsort((void **)lineptr,0,nlines-1,
      (int(*)(void *,void *))(numeric?numcmp:strcmp));
    // (numeric ? (int(*)(void *,void *))numcmp : (int(*)(void *,void *))strcmp));
     writelines(lineptr,nlines);
      return 0;
    }
    else
    {
            printf("input too big to sort\n");
            return 1;
    }
}
/*qsort函数:以递增顺序对v[left]...v[right]进行排序*/
void qsort(void *v[],int left,int right,
            int (*comp)(void *,void *))
{
        int i,last;
        if(left>=right)
                return;
        swap(v,left,(left+right)/2);
        last=left;
        for(i=left+1;i<right;i++)
                if((*comp)(v,v[left])<0)
                 swap(v,++last,i);
        swap(v,left,last);
         qsort(v,left,last-1,comp);
         qsort(v,last+1,right,comp);
}
/*numcmp函数:按数值比较字符串S1,S2的大小*/
int numcmp(const char *s1, const  char *s2)
{
  double v1,v2;
  v1=atof(s1);
  v2=atof(s2);
  if(v1<v2)
          return -1;
  else if(v1>v2)
          return 1;
  else
          return 0;
}
void swap(void *v[],int i ,int j)
{
        void *temp;
        temp=v;
        v=v[j];
        v[j]=temp;
}
/*readlines函数:读取输入行*/
int readlines(char * lineptr[],int maxlines)
{
    int len,nlines;
    char*p, line[MAXLEN];
    nlines=0;
    while((len=getline(line,MAXLEN))>0)
    {
            if(nlines>=maxlines)
                    return -1;
            else
            {
                    line[len-1]='\0';
                    strcpy(p,line);
                    lineptr[nlines++]=p;
            }
    }
            return nlines;
}
int getline(char s[],int lim)
{
        int c,i;
        for(i=0;i<lim-1&&(c=getchar())!=EOF&&c!='\n';++i)
        {
                s=c;
        }
        if(c=='\n'){
                s=c;
                ++i;
        }
        s='\0';
        return i;
}
void writelines(char *lineptr[],int nlines)
{
        while(nlines-->0)
        {
                printf("%s\n",*lineptr++);
        }
}

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
6 [报告]
发表于 2007-03-08 16:47 |只看该作者
p指向哪里呢?
既然是抄书上的,也要抄的一样呀。

论坛徽章:
0
7 [报告]
发表于 2007-03-08 16:53 |只看该作者
恩,p只是一个起到暂时存储的作用,我写得和书上是一样的,K&R也 没有让p指向哪里。

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
8 [报告]
发表于 2007-03-08 16:56 |只看该作者
原帖由 believetruelove 于 2007-3-8 16:53 发表
恩,p只是一个起到暂时存储的作用,我写得和书上是一样的,K&R也 没有让p指向哪里。

  1.            if (nlines >= maxlines || p = alloc(len) == NULL)
  2.                return -1;
  3.            else {
  4.                line[len-1] = '\0';  /* delete newline */
  5.                strcpy(p, line);
  6.                lineptr[nlines++] = p;
  7.            }
复制代码

做人要厚道。

论坛徽章:
0
9 [报告]
发表于 2007-03-08 17:05 |只看该作者
大哥,什么也不说了,惭愧!!

论坛徽章:
0
10 [报告]
发表于 2007-03-08 19:51 |只看该作者
我也在看这本书,不过我是个菜鸟,加QQ交流下吧~    175906164  注明 C programming
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP