鱼C论坛

 找回密码
 立即注册
查看: 2165|回复: 14

[已解决]关于指针的一个问题

[复制链接]
发表于 2017-12-11 09:46:03 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
比如我现在定义一个比较函数int cmp(int a,int b)return a>b;
然后一个数组 int num[5]={1,4,3,5,2}
sort(num,num+5,cmp)
这样就实现了降序排列,但是具体的实现过程是怎么样的呢?
假设sort函数使用冒泡排序的方法,它是怎么利用cmp的呢?
求大佬指点一下
最佳答案
2017-12-16 12:25:04
先上一段代码,冒泡排序随手写的,有问题自己改一改
#include <stdio.h>

typedef int (*PFN_CMP)(void*, void*); 

int cmp(void *n1, void *n2)
{
    return n1 > n2 ? 1 : (n1 < n2 ? -1 : 0);
}

void sort(void **pAry, int nCount, PFN_CMP pfnCmp)
{
    for (int i = 1; i < nCount - 1; i++)
    {
        for (int j = 0; j < nCount - i; j++)
        {
            if (pfnCmp(pAry[j], pAry[j + 1]) > 0)
            {
                void *pTmp = pAry[j];
                pAry[j] = pAry[j + 1];
                pAry[j + 1] = pTmp;
            }
        }
    }
}

int main(int argc, char *argv[])
{
    int num[5] = { 1, 4, 3, 5, 2 };

    sort((void**)num, sizeof(num) / sizeof(num[0]), cmp);

    for (int i = 0; i < sizeof(num) / sizeof(num[0]); i++)
    {
        printf("%d\t", num[i]);
    }

    return 0;
}

这个函数指针当参数,实际上在开发过程中比较常见的,这样做可以兼容各种各样的结构体(正常结构体是没办法用大于小于比较的吧),只要写一个结构体比较的函数,然后当成函数指针传进去,这个排序算法就可以复用
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-12-11 09:55:32 | 显示全部楼层
sort中的前两个参数决定了目标数组的长度及数据
第三个参数只是一个简单的函数指针,可以不添加,直接在函数体里面使用即可
按照冒泡排序的算法思路来写就可以了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-12-11 10:09:10 From FishC Mobile | 显示全部楼层
比如我比较1,4那个cmp传入cmp的是1和4吗,
return a>b有什么用呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-12-11 16:11:48 | 显示全部楼层
御笔剑客 发表于 2017-12-11 10:09
比如我比较1,4那个cmp传入cmp的是1和4吗,
return a>b有什么用呢?

不是,你还是要这样写cmp(1,4)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-12-11 16:27:29 | 显示全部楼层
BngThea 发表于 2017-12-11 16:11
不是,你还是要这样写cmp(1,4)

那我写的那个cmp有什么用呢?,它传入的a和b是谁?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-12-11 16:45:09 From FishC Mobile | 显示全部楼层
御笔剑客 发表于 2017-12-11 16:27
那我写的那个cmp有什么用呢?,它传入的a和b是谁?

cmp比较两个参数的大小啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-12-11 16:45:56 | 显示全部楼层
御笔剑客 发表于 2017-12-11 16:27
那我写的那个cmp有什么用呢?,它传入的a和b是谁?

在这里没有实际用处,只是为了检测这种用法
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-12-11 17:27:14 | 显示全部楼层
BngThea 发表于 2017-12-11 16:45
在这里没有实际用处,只是为了检测这种用法

为什么用了cmp以后sort就变成降序排序了呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-12-11 17:29:23 | 显示全部楼层
御笔剑客 发表于 2017-12-11 17:27
为什么用了cmp以后sort就变成降序排序了呢?

那要看你怎么用的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-12-11 17:58:17 | 显示全部楼层
BngThea 发表于 2017-12-11 17:29
那要看你怎么用的

我只是想知道 sort(num,num+5,cmp)这样,假设采用冒泡排序,第一次比较的是1和4,那么传入的这个函数指针cmp在其中起了什么用呢?  为什么return a>b就交换了4 和 1这两个数呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-12-11 18:30:24 From FishC Mobile | 显示全部楼层
御笔剑客 发表于 2017-12-11 17:58
我只是想知道 sort(num,num+5,cmp)这样,假设采用冒泡排序,第一次比较的是1和4,那么传入的这个函数指 ...

你代码都没给,叫人怎么分析?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-12-11 20:36:34 | 显示全部楼层
BngThea 发表于 2017-12-11 18:30
你代码都没给,叫人怎么分析?
#include <iostream>
#include <algorithm>
using namespace std;
int cmp(int a,int b)
{
    return a>b;
}
int main()
{
    int i;
    int num[5]={1,4,3,5,2};
    sort(num,num+5);        //升序排列
     for(i=0;i<5;i++)
        cout<<num[i]<<" ";
    cout<<endl;
    sort(num,num+5,cmp);     //传入cmp后降序排列
    for(i=0;i<5;i++)
        cout<<num[i]<<" ";

    return 0;

}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-12-11 21:47:36 | 显示全部楼层
前两个参数给定排序的范围,cmp只是个谓词函数,用来表明这个范围内的数据要以哪种规则排列,严格意义上应该返回bool值。你自己写排序是不是这么写的if(a>b){statement}else{statement},cmp这里就是用来代替条件判断的。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-12-16 12:25:04 | 显示全部楼层    本楼为最佳答案   
先上一段代码,冒泡排序随手写的,有问题自己改一改
#include <stdio.h>

typedef int (*PFN_CMP)(void*, void*); 

int cmp(void *n1, void *n2)
{
    return n1 > n2 ? 1 : (n1 < n2 ? -1 : 0);
}

void sort(void **pAry, int nCount, PFN_CMP pfnCmp)
{
    for (int i = 1; i < nCount - 1; i++)
    {
        for (int j = 0; j < nCount - i; j++)
        {
            if (pfnCmp(pAry[j], pAry[j + 1]) > 0)
            {
                void *pTmp = pAry[j];
                pAry[j] = pAry[j + 1];
                pAry[j + 1] = pTmp;
            }
        }
    }
}

int main(int argc, char *argv[])
{
    int num[5] = { 1, 4, 3, 5, 2 };

    sort((void**)num, sizeof(num) / sizeof(num[0]), cmp);

    for (int i = 0; i < sizeof(num) / sizeof(num[0]); i++)
    {
        printf("%d\t", num[i]);
    }

    return 0;
}

这个函数指针当参数,实际上在开发过程中比较常见的,这样做可以兼容各种各样的结构体(正常结构体是没办法用大于小于比较的吧),只要写一个结构体比较的函数,然后当成函数指针传进去,这个排序算法就可以复用
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-12-16 12:52:11 | 显示全部楼层
<(¥_$)> 发表于 2017-12-16 12:25
先上一段代码,冒泡排序随手写的,有问题自己改一改

我大概明白了,谢谢了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-29 01:55

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表