指针函数回调的问题

时间:2021-05-23 19:02:46
如题。
编写一个名叫sort的函数,它用于对一个任何类型的数组进行排序,为了使函数更为通用,它的其中的一个参数必须是一个指向比较回调函数的指针。该回调函数由调用程序提供,比较函数接受两个参数,也就是两个指向需要进行比较的值的值的指针,如果两个值相等,函数返回零,如果第一个值小于第二个值,函数返回一个小于零的整数。如果第一个值大于第二个值,函数返回一个大于零的整数。
sort函数的参数将是:
1 一个指向需要排序的数组的第一个值的指针。
2 数组中值的个数
3 每一个数组元素的长度。
4 一个指向比较回调函数的指针。
如:
void sort(void *arrary,int n ,int size,int(*p())(void *,void *))
这种型的函数在嵌入式中用得比较多,我搞了一天都没有搞懂,也就是一有复杂的参数时就不会了,所以希望各位高手能给一个比较复杂能用的例子,加注解。

14 个解决方案

#1


void sort(void *arrary,int n ,int size, int(*p)(void *,void *)) 

#2




1. http://topic.csdn.net/t/20041007/15/3431197.html
2.
Newsgroups: comp.lang.c 
From: "S.Tobias" <s...@FamOuS.BedBuG.pAlS.INVALID> - Find messages by this author  
Date: 28 Jan 2005 19:25:02 GMT 
Local: Fri, Jan 28 2005 11:25 am  
Subject: Re: How to understand function prototype signal() 
Reply to Author | Forward | Print | Individual Message | Show original | Report Abuse  


None <lovecreatesbea...@gmail.com> wrote: 
> void (*signal(int sig, void (*func)(int)))(int); 


  void (*)(int) 

type pointer to (function with one int parameter returning void) 


  *signal() 


signal is a function returning pointer 
(Note: 
  (*signal)() 
would mean: signal is a pointer to function) 


  void (*signal())(int); 


signal is a function returning pointer to (function with one int 
param returning void) 


  void (*signal(int sig, void (*func)(int)))(int); 


signal is a function with two parameters, returning pointer etc... 
The first parameter is type int, the second parameter is type: 


  void (*)(int) 


ie. pointer to function with one int parameter returning void. 


The original declaration is equivalent to: 
  void (*signal(int, void (*)(int)))(int); 
ie. the parameters of `signal' don't have to be named, similarly 
parameter to `func' was not named. 


Note that the type of the second parameter of `signal' is the same 
as the type that `signal' returns, ie. "pointer to (fn with one int 
param, returning void)". 


It's easier to understand if you declare a type: 


  typedef void (*ptr_void_fn_int)(int); 
  ptr_void_fn_int signal(int, ptr_void_fn_int); 


(ptr_void_fn_int is type "pointer to (fn with one etc...)"). 


`signal' function for a given signal number sets the new signal 
handler you supply (which is type ptr_void_fn_int) and returns 
you the previous handler (which naturally has to be the same type). 
(For exact `signal' semantics see N869 7.14.1.1.) 


> void interrupt ( *oldhandler)(); 
> -Is it legal? 
> -If it's a right prototype, what does identifier "interrupt" mean? Will 
> it be a type qualifier. 


`interrupt' is not an ISO C keyword.  It probably denotes function 
call convention, and means that the function `oldhandler' points to 
will be called from outside as an interrupt handler (but I might be 
very wrong here).  You have to consult your compiler manual. 

-- 
Stan Tobias 
mailx `echo s...@FamOuS.BedBuG.pAlS.INVALI­D | sed s/[[:upper:]]//g` 

  




 Polarislee 

signal是一个函数: 
它有两个参数。第一个是 int。第二个是指向参数为 int,返回值为 void 的函数的指针; 
它的返回值是一个函数指针,一个指向一个参数为 int,返回值为 void 的函数。 

#3


感觉用函数模板比较合适

#4


void sort(void *arrary,int n ,int size,int(*p())(void *,void *)) 
你这里的P是1个函数,返回值是1个函数指针,不符合你的需求.1L的是对的.
你说的是是么复杂参数?

#5


mark

#6


引用 4 楼 weiyijiji 的回复:
void sort(void *arrary,int n ,int size,int(*p())(void *,void *)) 
你这里的P是1个函数,返回值是1个函数指针,不符合你的需求.1L的是对的. 
你说的是是么复杂参数?




这个函数我主要是用来进行排序的。也就是说不管是什么类型的数组都能用。我的函数原形写的时候多与了一个"()",真正的应像1L的那样,但是不和道怎么才能实现。但必须用指针函数的回调。这在嵌入式中用得比较多。C语言写。

#7


如果用C++,建议使用STL,有关于排序的模版函数,直接使用就可以了,如果用C,网上应该有现成的代码,这类问题太普遍了。

#8


引用 7 楼 simulationz 的回复:
如果用C++,建议使用STL,有关于排序的模版函数,直接使用就可以了,如果用C,网上应该有现成的代码,这类问题太普遍了。

网上没有,我找过几次了,都没有找到。


#include "stdio.h"
#include "stdlib.h"
void main()
{
void sqow(void *,void *);
void funtion(void *,void *,void (*p)(void *,void *));
int a,b;
int *p,*q;
p=&a;
q=&b;
printf("请输入两个整数:\n");
scanf("%d %d",p,q);
printf("这两个数交换位置后为:\n");
funtion(p,q,sqow);
printf("%d  %d",*p,*q);
printf("\n");
}
void sqow(void *a,void *b)
{     
    int temp;
    temp=*(int*)a;
        *(int*)a=*(int *)b;
        *(int *)b=temp;
}
void funtion(void *a,void *b,void(*p)(void *,void *))
{
  p(a,b);
}


这是我自己写的。只写了一个用于整型的交换用于测试。
想把它写成一个对任何类型数组都适用的,就是写不出来了。

#9


楼上的可以用模版就可以通用了。

#10


引用 9 楼 shuyisheng 的回复:
楼上的可以用模版就可以通用了。


大哥还没有明白我的意思,不用模版,就用一个void sort(void *arrary,int n ,int size,int(*p)(void *,void *)) 排序函数,加上无数个对各种类型的数的比较函数。根据传给sort的参数的不同,它自动去调用想应的比较函数。int(*p)(void *,void *)这个函数指针指向的是比较函数。

#11



#include <stdio.h>
#include <stdlib.h>
#include <string.h>


void sort(void *arrary,int n ,int size,int(*p)(void *,void *))
{
int i,j;

void * temp=malloc(sizeof(char)*size);
for(i=0;i<n;i++)
{
for(j=0;j<n-1-i;j++)
{
char * p1=(char *)(arrary)+j*size;
char * p2=(char *)(arrary)+j*size+size;
if(p(p1,p2)>0)
{

memcpy(temp,p1,size);
memcpy(p1,p2,size);
memcpy(p2,temp,size);
}
}
}
free(temp);
}

int i_comp(void * p1,void * p2)
{
return *(int*)p1-*(int*)p2;
}

int d_comp(void * p1,void * p2)
{
return *(double *)p1-*(double *)p2;
}

void main()
{
int a[]={2.2,5.6,4.1,6.0,9,7,8};
int i;

sort(a,sizeof(a)/sizeof(a[0]),sizeof(a[0]),i_comp);
for(i=0;i<sizeof(a)/sizeof(a[0]);i++)
printf("%d\t",a[i]);
}





#12



#include <stdio.h>
#include <stdlib.h>
#include <string.h>


void sort(void *arrary,int n ,int size,int(*p)(void *,void *))
{
int i,j;

void * temp=malloc(sizeof(char)*size);
for(i=0;i<n;i++)
{
for(j=0;j<n-1-i;j++)
{
char * p1=(char *)(arrary)+j*size;
char * p2=(char *)(arrary)+j*size+size;
if(p(p1,p2)>0)
{

memcpy(temp,p1,size);
memcpy(p1,p2,size);
memcpy(p2,temp,size);
}
}
}
free(temp);
}

int i_comp(void * p1,void * p2)
{
return *(int*)p1-*(int*)p2;
}

int d_comp(void * p1,void * p2)
{
return (int)(*(double *)p1-*(double *)p2);
}

void main()
{
double a[]={2.2,5.6,4.1,6.0,9,7,8};
int i;

sort(a,sizeof(a)/sizeof(a[0]),sizeof(a[0]),i_comp);
for(i=0;i<sizeof(a)/sizeof(a[0]);i++)
printf("%f\t",a[i]);

printf("\n");

int b[]={4,5,7,9,1,4,9,2};
sort(b,sizeof(b)/sizeof(b[0]),sizeof(b[0]),i_comp);
for(i=0;i<sizeof(b)/sizeof(b[0]);i++)
printf("%d\t",b[i]);

}



5.600000        4.100000        2.200000        6.000000        9.000000
7.000000        8.000000
1       2       4       4       5       7       9       9       请按任意键继续.
. .

#13



#include <stdio.h>
#include <stdlib.h>
#include <string.h>


void sort(void *arrary,int n ,int size,int(*p)(void *,void *))
{
int i,j;

void * temp=malloc(sizeof(char)*size);
for(i=0;i<n;i++)
{
for(j=0;j<n-1-i;j++)
{
char * p1=(char *)(arrary)+j*size;
char * p2=(char *)(arrary)+j*size+size;
if(p(p1,p2)>0)
{

memcpy(temp,p1,size);
memcpy(p1,p2,size);
memcpy(p2,temp,size);
}
}
}
free(temp);
}

int i_comp(void * p1,void * p2)
{
return *(int*)p1-*(int*)p2;
}

int d_comp(void * p1,void * p2)
{
return (int)(*(double *)p1-*(double *)p2);

}

void main()
{
double a[]={2.2,5.6,4.1,6.0,9,7,8};
int i;

sort(a,sizeof(a)/sizeof(a[0]),sizeof(a[0]),d_comp);//晕,贴错了,忘记改回来了d_comp,这下对了
for(i=0;i<sizeof(a)/sizeof(a[0]);i++)
printf("%f\t",a[i]);

printf("\n");

int b[]={4,5,7,9,1,4,9,2};
sort(b,sizeof(b)/sizeof(b[0]),sizeof(b[0]),i_comp);
for(i=0;i<sizeof(b)/sizeof(b[0]);i++)
printf("%d\t",b[i]);

}



2.200000        4.100000        5.600000        6.000000        7.000000
8.000000        9.000000
1       2       4       4       5       7       9       9       请按任意键继续.
. .

#14


谢谢了,给你30分。

#1


void sort(void *arrary,int n ,int size, int(*p)(void *,void *)) 

#2




1. http://topic.csdn.net/t/20041007/15/3431197.html
2.
Newsgroups: comp.lang.c 
From: "S.Tobias" <s...@FamOuS.BedBuG.pAlS.INVALID> - Find messages by this author  
Date: 28 Jan 2005 19:25:02 GMT 
Local: Fri, Jan 28 2005 11:25 am  
Subject: Re: How to understand function prototype signal() 
Reply to Author | Forward | Print | Individual Message | Show original | Report Abuse  


None <lovecreatesbea...@gmail.com> wrote: 
> void (*signal(int sig, void (*func)(int)))(int); 


  void (*)(int) 

type pointer to (function with one int parameter returning void) 


  *signal() 


signal is a function returning pointer 
(Note: 
  (*signal)() 
would mean: signal is a pointer to function) 


  void (*signal())(int); 


signal is a function returning pointer to (function with one int 
param returning void) 


  void (*signal(int sig, void (*func)(int)))(int); 


signal is a function with two parameters, returning pointer etc... 
The first parameter is type int, the second parameter is type: 


  void (*)(int) 


ie. pointer to function with one int parameter returning void. 


The original declaration is equivalent to: 
  void (*signal(int, void (*)(int)))(int); 
ie. the parameters of `signal' don't have to be named, similarly 
parameter to `func' was not named. 


Note that the type of the second parameter of `signal' is the same 
as the type that `signal' returns, ie. "pointer to (fn with one int 
param, returning void)". 


It's easier to understand if you declare a type: 


  typedef void (*ptr_void_fn_int)(int); 
  ptr_void_fn_int signal(int, ptr_void_fn_int); 


(ptr_void_fn_int is type "pointer to (fn with one etc...)"). 


`signal' function for a given signal number sets the new signal 
handler you supply (which is type ptr_void_fn_int) and returns 
you the previous handler (which naturally has to be the same type). 
(For exact `signal' semantics see N869 7.14.1.1.) 


> void interrupt ( *oldhandler)(); 
> -Is it legal? 
> -If it's a right prototype, what does identifier "interrupt" mean? Will 
> it be a type qualifier. 


`interrupt' is not an ISO C keyword.  It probably denotes function 
call convention, and means that the function `oldhandler' points to 
will be called from outside as an interrupt handler (but I might be 
very wrong here).  You have to consult your compiler manual. 

-- 
Stan Tobias 
mailx `echo s...@FamOuS.BedBuG.pAlS.INVALI­D | sed s/[[:upper:]]//g` 

  




 Polarislee 

signal是一个函数: 
它有两个参数。第一个是 int。第二个是指向参数为 int,返回值为 void 的函数的指针; 
它的返回值是一个函数指针,一个指向一个参数为 int,返回值为 void 的函数。 

#3


感觉用函数模板比较合适

#4


void sort(void *arrary,int n ,int size,int(*p())(void *,void *)) 
你这里的P是1个函数,返回值是1个函数指针,不符合你的需求.1L的是对的.
你说的是是么复杂参数?

#5


mark

#6


引用 4 楼 weiyijiji 的回复:
void sort(void *arrary,int n ,int size,int(*p())(void *,void *)) 
你这里的P是1个函数,返回值是1个函数指针,不符合你的需求.1L的是对的. 
你说的是是么复杂参数?




这个函数我主要是用来进行排序的。也就是说不管是什么类型的数组都能用。我的函数原形写的时候多与了一个"()",真正的应像1L的那样,但是不和道怎么才能实现。但必须用指针函数的回调。这在嵌入式中用得比较多。C语言写。

#7


如果用C++,建议使用STL,有关于排序的模版函数,直接使用就可以了,如果用C,网上应该有现成的代码,这类问题太普遍了。

#8


引用 7 楼 simulationz 的回复:
如果用C++,建议使用STL,有关于排序的模版函数,直接使用就可以了,如果用C,网上应该有现成的代码,这类问题太普遍了。

网上没有,我找过几次了,都没有找到。


#include "stdio.h"
#include "stdlib.h"
void main()
{
void sqow(void *,void *);
void funtion(void *,void *,void (*p)(void *,void *));
int a,b;
int *p,*q;
p=&a;
q=&b;
printf("请输入两个整数:\n");
scanf("%d %d",p,q);
printf("这两个数交换位置后为:\n");
funtion(p,q,sqow);
printf("%d  %d",*p,*q);
printf("\n");
}
void sqow(void *a,void *b)
{     
    int temp;
    temp=*(int*)a;
        *(int*)a=*(int *)b;
        *(int *)b=temp;
}
void funtion(void *a,void *b,void(*p)(void *,void *))
{
  p(a,b);
}


这是我自己写的。只写了一个用于整型的交换用于测试。
想把它写成一个对任何类型数组都适用的,就是写不出来了。

#9


楼上的可以用模版就可以通用了。

#10


引用 9 楼 shuyisheng 的回复:
楼上的可以用模版就可以通用了。


大哥还没有明白我的意思,不用模版,就用一个void sort(void *arrary,int n ,int size,int(*p)(void *,void *)) 排序函数,加上无数个对各种类型的数的比较函数。根据传给sort的参数的不同,它自动去调用想应的比较函数。int(*p)(void *,void *)这个函数指针指向的是比较函数。

#11



#include <stdio.h>
#include <stdlib.h>
#include <string.h>


void sort(void *arrary,int n ,int size,int(*p)(void *,void *))
{
int i,j;

void * temp=malloc(sizeof(char)*size);
for(i=0;i<n;i++)
{
for(j=0;j<n-1-i;j++)
{
char * p1=(char *)(arrary)+j*size;
char * p2=(char *)(arrary)+j*size+size;
if(p(p1,p2)>0)
{

memcpy(temp,p1,size);
memcpy(p1,p2,size);
memcpy(p2,temp,size);
}
}
}
free(temp);
}

int i_comp(void * p1,void * p2)
{
return *(int*)p1-*(int*)p2;
}

int d_comp(void * p1,void * p2)
{
return *(double *)p1-*(double *)p2;
}

void main()
{
int a[]={2.2,5.6,4.1,6.0,9,7,8};
int i;

sort(a,sizeof(a)/sizeof(a[0]),sizeof(a[0]),i_comp);
for(i=0;i<sizeof(a)/sizeof(a[0]);i++)
printf("%d\t",a[i]);
}





#12



#include <stdio.h>
#include <stdlib.h>
#include <string.h>


void sort(void *arrary,int n ,int size,int(*p)(void *,void *))
{
int i,j;

void * temp=malloc(sizeof(char)*size);
for(i=0;i<n;i++)
{
for(j=0;j<n-1-i;j++)
{
char * p1=(char *)(arrary)+j*size;
char * p2=(char *)(arrary)+j*size+size;
if(p(p1,p2)>0)
{

memcpy(temp,p1,size);
memcpy(p1,p2,size);
memcpy(p2,temp,size);
}
}
}
free(temp);
}

int i_comp(void * p1,void * p2)
{
return *(int*)p1-*(int*)p2;
}

int d_comp(void * p1,void * p2)
{
return (int)(*(double *)p1-*(double *)p2);
}

void main()
{
double a[]={2.2,5.6,4.1,6.0,9,7,8};
int i;

sort(a,sizeof(a)/sizeof(a[0]),sizeof(a[0]),i_comp);
for(i=0;i<sizeof(a)/sizeof(a[0]);i++)
printf("%f\t",a[i]);

printf("\n");

int b[]={4,5,7,9,1,4,9,2};
sort(b,sizeof(b)/sizeof(b[0]),sizeof(b[0]),i_comp);
for(i=0;i<sizeof(b)/sizeof(b[0]);i++)
printf("%d\t",b[i]);

}



5.600000        4.100000        2.200000        6.000000        9.000000
7.000000        8.000000
1       2       4       4       5       7       9       9       请按任意键继续.
. .

#13



#include <stdio.h>
#include <stdlib.h>
#include <string.h>


void sort(void *arrary,int n ,int size,int(*p)(void *,void *))
{
int i,j;

void * temp=malloc(sizeof(char)*size);
for(i=0;i<n;i++)
{
for(j=0;j<n-1-i;j++)
{
char * p1=(char *)(arrary)+j*size;
char * p2=(char *)(arrary)+j*size+size;
if(p(p1,p2)>0)
{

memcpy(temp,p1,size);
memcpy(p1,p2,size);
memcpy(p2,temp,size);
}
}
}
free(temp);
}

int i_comp(void * p1,void * p2)
{
return *(int*)p1-*(int*)p2;
}

int d_comp(void * p1,void * p2)
{
return (int)(*(double *)p1-*(double *)p2);

}

void main()
{
double a[]={2.2,5.6,4.1,6.0,9,7,8};
int i;

sort(a,sizeof(a)/sizeof(a[0]),sizeof(a[0]),d_comp);//晕,贴错了,忘记改回来了d_comp,这下对了
for(i=0;i<sizeof(a)/sizeof(a[0]);i++)
printf("%f\t",a[i]);

printf("\n");

int b[]={4,5,7,9,1,4,9,2};
sort(b,sizeof(b)/sizeof(b[0]),sizeof(b[0]),i_comp);
for(i=0;i<sizeof(b)/sizeof(b[0]);i++)
printf("%d\t",b[i]);

}



2.200000        4.100000        5.600000        6.000000        7.000000
8.000000        9.000000
1       2       4       4       5       7       9       9       请按任意键继续.
. .

#14


谢谢了,给你30分。