使用函数指针,完成一个sort()函数,能对任何类型的数组元素进行排序: 回调函数 以及 memcpy ()原型实现

进来复习了一下C语言指针,一直没有写过太多关于函数指针的代码,而且对回调函数的理解一直都是在理论上,基本上没有太写过关于它的代码,进来得空,写了一个小程序加深下自己对回调函数和函数指针的理解。

问题描述: 编写一个sort()函数,使它能够对任何类型的数组元素进行排序。

下面是我写的代码:

/*
 使用函数指针的回调函数技巧,设计一个能排序int 和char 数组的sort()函数
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define   FALSE  0
#define   TRUE   1
//sort 函数
void sort(const void *,const int number,unsigned width,int(*compare)(void  *,void  *),void (*swap)(void  *,void  *));
int compare_int(void  *,void  *);
int compare_char(void  *,void  *);
void swap_int(void  *,void  *);
void swap_char(void  *,void  *);
void print(const void *_tmp,int num,int width,void (*_printf)(const void *));
void print_int(const void * );
void print_char(const void *);

int main(void)
{
    int  num=10;
    int  a_int[10]={9,2,3,8,1,5,6,4,7,12};
    char c_char[10]={'g','h','t','a','d','w','q','b','m','c'};
    //使用sort对上述两个数组进行排序
    sort(a_int ,num,sizeof (int),compare_int ,swap_int );
    sort(c_char,num,sizeof(char),compare_char,swap_char);
   //打印排序结果
    print(a_int,num,sizeof (int),print_int);
    print(c_char,num,sizeof(char),print_char);
}

//the sort function
/*sort排序函数使用普通的选择排序*/
void sort(const void *_tmp,const int number,unsigned width,int(*compare)(void *,void *),void (*swap)(void *,void *))
{
    int i,j,small;
     for(i=0;i<number-1;i++)
       {
        small=i;
        for(j=i+1;j<number;j++)
              if(compare((((char *)_tmp)+j*width),(((char *)_tmp)+small*width)))//if(_tmp+j<_tmp_small) return TURE;
                    small=j;
        if(small!=i)
           swap((((char *)_tmp)+i*width),(((char *)_tmp)+small*width));
       }
}
//compare int function
int compare_int( void * tmp_a, void *tmp_b)
{
      if(*(int *)tmp_a<*(int *)tmp_b)
           return TRUE;
      else
           return FALSE;
}
//compare char  function
int compare_char( void * tmp_a, void *tmp_b)
{
      if(*(char *)tmp_a<*(char *)tmp_b) //使用char的比较方式或其他strcmp()函数
           return TRUE;
      else
           return FALSE;
}
//swap int function
void swap_int( void * tmp_a, void *tmp_b)
{
         int temp;
             temp           =  *(int *)tmp_a;
             *(int *)tmp_a  =  *(int *)tmp_b;
             *(int *)tmp_b  =  temp;
}
//swap char function
void swap_char( void * tmp_a, void *tmp_b)
{
         char temp;
             temp           =  *(char *)tmp_a;
             *(char *)tmp_a =  *(char *)tmp_b;
             *(char *)tmp_b =  temp;
}
//printf function
void print(const void *_tmp,int num ,int width, void (*_printf)(const void *))
{
    int  i;
    for(i=0;i<num;i++)
         _printf(((char *)_tmp+i*width));
   printf("\n");
}

void print_int(const void *_tmp)
{
   printf("%d",*(int*)_tmp);
} 

void print_char(const void *_tmp)
{
   printf("%c",*(char*)_tmp);
}

这是运行结果的:

[[email protected] C_test]$ gcc   -o  sort  callback_sort.c
[[email protected] C_test]$ ./sort
1 2 3 4 5 6 7 8 9 12
a b c d g h m q t w

首先从结果可以看出,整个程序的设计符合题目的要求。

这里主要说说sort() 函数:

void sort(const void *,const int number,unsigned width,int(*compare)(void  *,void  *),void (*swap)(void  *,void  *));

sort函数共有5个参数,参数1:  const void *   由于需要对int[],char[]数组进行排序,所以使用void * 指针作为参数,可以接受任何类型指针。

参数2:  const int  number , 是数组元素的个数。

参数3:  unsigned int  width , 由于数组通过void * 传入函数,函数无法确定类型,(或一个元素占用的内存)

参数4: int(*compare)(void * ,void *),函数指针,使用void * 作为函数指针参数,就可以实现任何类型参数传递

参数5:void  (*swap)(void * ,void *), 函数指针,遇上面一致

其实函数指针调用那个函数进行比较,完成交换都是作为参数传递进函数的,其实最主要的还是sort() 中使用(width参数) 获取不同类型数组中每一个元素的过程。

使用(char*) 原子级内存操作

compare((((char *)_tmp)+j*width),(((char *)_tmp)+small*width))

先把void * 强制转化为 char * ,然后按照 width  i 的 关系,提取出具体的元素。 (void * 不能解引用,且占用4字节,虽然刚巧可以对int 进行访问,但不能满足char[] 的要求,这也就是为啥要传递 width的原因。)

其实这个有点像memcpy函数,

下面是我自己实现的一个memcpy()函数

void * memcpy(void *dst ,const void * src ,int num)
{
  assert((NULL!=src)&&(NULL!=dst));
  assert(num>0);
  char *tmp_dst=(char *)dst;
  char *tmp_src=(char *)src;
  while(num--)
     *tmp_dst++=*tmp_src++;
  return dst;
}

这个函数要注意的几点: void * 不能解引用  必须强制转化char *

函数入口参数合法性检测

返回值的设计(当返回dst时,可以完成连续赋值操作,但当你没有返回值时,就不可能实现连续赋值操作)

使用函数指针,完成一个sort()函数,能对任何类型的数组元素进行排序: 回调函数 以及 memcpy ()原型实现,布布扣,bubuko.com

时间: 2024-10-13 04:11:31

使用函数指针,完成一个sort()函数,能对任何类型的数组元素进行排序: 回调函数 以及 memcpy ()原型实现的相关文章

struts通过Ajax返回数据时,例如对象类型,没有执行Ajax的回调函数

<result type="json"  name="success">                 <param name="includeProperties">msg.*,对象.*</param>                <!--  <param name="includeProperties">msg</param> -->      

jQuery $.post()返回类型为json时不进入回调函数的原因及解决方法

这真是个让人特别抓心找挠肝的问题,真的差点被这个问题逼的放弃去使用json作为返回类型,而是去用html,但是有的时候就是要较汁一下.(即便现在问题解决了,我还是想说句"妈蛋",来发泄一下) 其实主要还是自己对json的不够了解,但是很纳闷,网上对路的解决方法几乎没有.所以虽然问题很小,但是还是想要分享出来,希望能帮到需要的人. 首先$.post()格式如下: $.post(url,data,success(data, textStatus, jqXHR),dataType) 参数描述

C语言通过指针对数组元素进行排序

// //  main.c //  Pointer_array // //  Created by ma c on 15/8/2. //  Copyright (c) 2015年 bjsxt. All rights reserved. //  要求:使用指针的指针输出字符串.首先要使用指针数组创建一个字符串数组,然后定义指向指针的指针,使其指向字符串数组,并使用其输出数组中的字符串.同时对数组中的内容进行升序排序. #include <stdio.h> #include<string.h

函数指针的一个的demo

#include <stdio.h> typedef void (*fun_cb)(int a, int b); static fun_cb exe_fun_cb; void fun_cb_input(int, int); void setUp_cb(fun_cb); void main() { setUp_cb(fun_cb_input); } void setUp_cb(fun_cb fun_cb_param) { printf("\n ready to use callback

Glide.with(Activity) 也是让 Activity 创建出一个 Fragment ,在 Fragment 的各个生命周期方法内插入回调函数后,执行代码来实现的

SupportActivity.java(support库)------------------------------ @Override @SuppressWarnings("RestrictedApi") protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); ReportFragment.injectIfNeededIn(this); }

函数指针作为函数參数,实现冒泡排序的升序排序和降序排序

#include<stdio.h> #define N 10//定义数组元素个数 int Ascending(int a,int b);//升序排列的函数声明 int Descending(int a,int b);//降序排列的函数声明 void swap(int*,int*);//交换数据的函数声明 void BubbleSort(int a[],int n,int (*compare)(int,int));//声明排序函数,通过函数指针作为函数调用 void Display(int a[

函数指针作为函数参数,实现冒泡排序的升序排序和降序排序

#include<stdio.h> #define N 10//定义数组元素个数 int Ascending(int a,int b);//升序排列的函数声明 int Descending(int a,int b);//降序排列的函数声明 void swap(int*,int*);//交换数据的函数声明 void BubbleSort(int a[],int n,int (*compare)(int,int));//声明排序函数,通过函数指针作为函数调用 void Display(int a[

回调函数(真好理解)

回调函数 在看LWIP时,见到用回调函数,再看某老外公司OPC源代码时,见到用回调函数.看我国内某些代码(我公司软件等)时没用到.于是,我对回调函数产生了很大的好奇.以前,我写VC程序时用到过回调函数,但是没有用C语言来使用.最近,看到国外大量的经典代码中广泛使用了回调函数(LWIP.某两个公司的OPC程序等),都是C语言来实现的,而不是VC windows程序中别人实现自己使用的那种. 为了弄明白这种函数的奥妙,首先提出三个问题: 1.        回调函数是什么东西? 2.        

从for_each开始说起 回调函数与仿函数

#include <iostream> #include <algorithm> using namespace std; //回调函数 void call_back(char elem) {  cout << elem << endl; } //仿函数 struct Functor {  void operator() (char elem)   {   cout << elem << endl;  }  }; int main()