函数指针,用typedef定义函数指针的好处,输出各中基本类型如int,char,float,double型中最大值

本文探讨了在C++中使用函数指针实现泛型函数的方法,通过具体实例展示了如何根据不同类型的数据集查找最大值,并通过函数指针动态选择合适的函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先看看没有定义函数指针的这道题,目的都是输出数组中最大值:

#include<iostream>
#include<string.h>
#include<stdio.h>
using namespace std;
void * intMax(void * arg,int nCount)
{ int * agu=(int *)arg;
  static int Max=*agu;
  for(int i=1;i<nCount;i++)
   if(Max<*(agu+i))
    Max=*(agu+i);
   else
    continue;
  return &Max;

}
void * floatMax(void * arg,int nCount)
{ float * agu=(float *)arg;
 static float Max=*agu;
  for(int i=1;i<nCount;i++)
   if(Max<*(agu+i))
    Max=*(agu+i);
   else
    continue;
  return &Max;

}
void * doubleMax(void * arg,int nCount)
{ double* agu=(double *)arg;
  static double Max=*agu;
  for(int i=1;i<nCount;i++)
   if(Max<*(agu+i))
    Max=*(agu+i);
   else
    continue;
  return &Max;

}

void * charMax(void * arg,int nCount)
{ char* agu=(char *)arg;
  static char Max=*agu;
  for(int i=1;i<nCount;i++)
   if(Max<*(agu+i))
    Max=*(agu+i);
   else
    continue;
  return &Max;

}
void main()
{ /*  int a[]={3,2,56,45,78};
 void  * result=intMax(a,5);
 cout<<*((int *)result)<<endl;*/
 // float a[]={3.34f,2.34f,56.45f,45.32f,78.3456f};
 //void  * result=floatMax(a,5);
 //cout<<*((float*)result)<<endl;

 // double a[]={3.34,2.34,56.45,45.32,78.3456};
 //void  * result=doubleMax(a,5);
 //cout<<*((double*)result)<<endl;
 char  a[]={'A','a','h','f','B'};
 void  * result=charMax(a,5);
 cout<<*((char*)result)<<endl;


 }

 

观察观察者几个函数是不是有共同点:

(1)函数的返回值是某种类型的值而已

  (2)函数参数也是一样的,仅仅只是函数名不一样,虽然c中不存在函数重载形式,但是c++可以,比如下面这段代码在c中不行即在.c文件中不能运行,因为c语言不支持

函数重载,但在.cpp文件中可以

#include<stdio.h>
int max(int a,int b)
{
return a>b?a:b;
}

float max(float a,float b)
{
return a>b?a:b;
}
void main()
{

 int res=max(3,4);
 int res1=max(3.0f,4.0f);
 printf("%d\n",res);
 
 printf("%d\n",res1);
}

 注意把float max函数换个名字就能行如float max1(flaot a,float b)

 

又看一个有意思的题

在.cpp文件中下面的程序验证没问题

#include<iostream>
#include<string.h>
#include<stdio.h>
using namespace std;
typedef  void * (*pFun)(void *,int);

void * intMax(void * arg,int nCount)
{ int * agu=(int *)arg;
  static int Max=*agu;
  for(int i=1;i<nCount;i++)
   if(Max<*(agu+i))
    Max=*(agu+i);
   else
    continue;
  return &Max;

}
void * floatMax(void * arg,int nCount)
{ float * agu=(float *)arg;
 static float Max=*agu;
  for(int i=1;i<nCount;i++)
   if(Max<*(agu+i))
    Max=*(agu+i);
   else
    continue;
  return &Max;

}
void * doubleMax(void * arg,int nCount)
{ double* agu=(double *)arg;
  static double Max=*agu;
  for(int i=1;i<nCount;i++)
   if(Max<*(agu+i))
    Max=*(agu+i);
   else
    continue;
  return &Max;

}

void * charMax(void * arg,int nCount)
{ char* agu=(char *)arg;
  static char Max=*agu;
  for(int i=1;i<nCount;i++)
   if(Max<*(agu+i))
    Max=*(agu+i);
   else
    continue;
  return &Max;

}
void main()
{  /* int a[]={3,2,56,45,78};
 void  * result=intMax(a,5);
 cout<<*((int *)result)<<endl;
    float a[]={3.34f,2.34f,56.45f,45.32f,78.3456f};
 void  * result=floatMax(a,5);
 cout<<*((float*)result)<<endl;*/

 double a[]={3.34,2.34,56.45,45.32,78.3456};
 void  * result=doubleMax(a,5);
 cout<<*((double*)result)<<endl;
 char  a1[]={'A','a','h','f','B'};
 void  * result1=charMax(a1,5);
 cout<<*((char*)result1)<<endl;


 }

但是把他放到.c文件中出现了问题,经过改正如下。

在.c文件中改成这样可以

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

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

void * intMax(void * arg,int nCount)
{ int * agu=(int *)arg;int i;int pos;
int Max=*agu;
for( i=1;i<nCount;i++)
if(Max<*(agu+i))
{
 Max=*(agu+i);
 pos=i;
}
else
continue;
//return &Max;
return (void*)(agu+pos);;//解决返回局部地址警告
}
void * floatMax(void * arg,int nCount)
{ float * agu=(float *)arg;
float Max=*agu;int i;
for( i=1;i<nCount;i++)
if(Max<*(agu+i))
Max=*(agu+i);
else
continue;
return (void *)(agu+i);

}

void * doubleMax(void * arg,int nCount)
{
 double* agu=(double *)arg;
 double Max=*agu;int i;
 int pos;
 for( i=1;i<nCount;i++)
  if(Max<*(agu+i))
  {
   Max=*(agu+i);
   pos=i;
  }
  else
   continue;
  return (void*)(agu+pos);
  
}

void * charMax(void * arg,int nCount)
{ char* agu=(char *)arg;
char Max=*agu;int i,pos;
for( i=1;i<nCount;i++)
if(Max<*(agu+i))
{Max=*(agu+i);
pos=i;
}
else
continue;
return (void*)(agu+pos);

}
void main()
{
 // float a[]={3.34f,2.34f,56.45f,45.32f,78.3456f};
 // void  * result=floatMax(a,5);
 //cout<<*((float*)result)<<endl;
 char  a1[6]={'A','a','h','f','B'};
 double a[]={3.34,2.34,56.45,45.32,78.3456};
   int a2[]={3,2,56,45,78};
    void  * result2=intMax(a2,5);
 
 void  * result=doubleMax(a,5);
 
 void  * result1=charMax(a1,5);
 printf("%d\n",*((int*)result2));
 printf("%f\n",*((double*)result));
 printf("%c\n",*((char*)result1));
 
 
 
}

 当使用函数指针后的好处:

#include<iostream>
#include<string.h>
#include<stdio.h>
using namespace std;
typedef  void * (*pFun)(void *,int);

void * intMax(void * arg,int nCount)
{ int * agu=(int *)arg;
  static int Max=*agu;
  for(int i=1;i<nCount;i++)
   if(Max<*(agu+i))
    Max=*(agu+i);
   else
    continue;
  return &Max;

}
void * floatMax(void * arg,int nCount)
{ float * agu=(float *)arg;
 static float Max=*agu;
  for(int i=1;i<nCount;i++)
   if(Max<*(agu+i))
    Max=*(agu+i);
   else
    continue;
  return &Max;

}
void * doubleMax(void * arg,int nCount)
{ double* agu=(double *)arg;
  static double Max=*agu;
  for(int i=1;i<nCount;i++)
   if(Max<*(agu+i))
    Max=*(agu+i);
   else
    continue;
  return &Max;

}

void * charMax(void * arg,int nCount)
{ char* agu=(char *)arg;
  static char Max=*agu;
  for(int i=1;i<nCount;i++)
   if(Max<*(agu+i))
    Max=*(agu+i);
   else
    continue;
  return &Max;

}

pFun search_fun(char ch)//这个函数的作用就是动态的匹配具体的函数
{  pFun fun=NULL;
 switch(ch)
 {
 case 'i':
  fun=intMax;
  break;
 case 'f':
  fun=floatMax;
  break;
 case 'd':
  fun=doubleMax;
  break;
 case 'c':
    fun=charMax;
  break;
   default:
    fun=NULL;
    break;
 }
  return fun;
}

void main()
{  /* int a[]={3,2,56,45,78};
 void  * result=intMax(a,5);
 cout<<*((int *)result)<<endl;
    float a[]={3.34f,2.34f,56.45f,45.32f,78.3456f};
 void  * result=floatMax(a,5);
 cout<<*((float*)result)<<endl;*/

 /*double a[]={3.34,2.34,56.45,45.32,78.3456};
 void  * result=doubleMax(a,5);
 cout<<*((double*)result)<<endl;
 char  a1[]={'A','a','h','f','B'};
 void  * result1=charMax(a1,5);
 cout<<*((char*)result1)<<endl;*/

 pFun fun=NULL;
 fun=search_fun('c');//可以看做是为找到真正的函数搭的一座桥
 char  a1[]={'A','a','h','f','B'};
 void  * result1=(*fun)(a1,5);//这才是真正的函数调用
 cout<<*((char*)result1)<<endl;
 }

 

 

<think>好的,我需要用C语言编写一个泛最大值计算函数,支持自定义数据类型ElementType。首先,我得回顾一下C语言中的泛处理方式,因为C不像C++那样有模板,但可以通过void指针和函数指针来实现类似泛的功能。 用户的问题是要处理自定义类型的数组,所以关键在于如何比较这些自定义类型的元素。在C语言中,通常的做法是让用户提供一个比较函数,这个函数知道如何比较两个ElementType类型的对象。例如,qsort函数就使用了这样的方法,它接受一个比较函数作为参数。 接下来,我需要定义函数的参数。函数需要接收数组的指针、数组的元素个数、每个元素的大小,以及比较函数的指针。函数原可能类似于:void* max_element(void *array, size_t count, size_t element_size, int (*compare)(const void*, const void*))。 然后,函数内部需要遍历数组中的每个元素。由于使用的是void指针,需要通过指针算术来访问每个元素。不过,C语言中直接对void指针进行算术运算是不允许的,所以需要将void指针转换为char*,因为char的大小是1字节,这样可以正确计算偏移量。 初始化时,将第一个元素设为当前最大值。然后从第二个元素开始,依次与当前最大值比较。每次比较都需要调用用户提供的比较函数。如果比较函数返回正值,说明当前元素比最大值大,于是更新最大值的位置。 需要注意的是,函数应该返回指向最大元素的指针,这样用户可以直接使用这个指针,或者通过解引用获取值。返回类型是void*,这样无论ElementType是什么类型,都能适应。 还需要考虑空指针和元素个数为0的情况,这时候函数应该返回NULL,避免未定义行为。 另外,比较函数的实现需要用户根据自定义类型定义。例如,如果ElementType是一个结构体,包含某个需要比较的字段,用户需要在比较函数中提取该字段并进行比较,返回相应的整数值。 最后,测试这个函数时,可以分别用基本类型(如intdouble)和自定义结构体来验证其正确性。比如,对于int数组,比较函数可以直接比较两个int值;对于结构体,则比较特定字段。 总结一下,步骤大致如下: 1. 定义max_element函数,参数包括数组、元素数量、元素大小、比较函数。 2. 使用char*指针遍历数组元素。 3. 调用比较函数确定元素大小关系。 4. 返回最大元素的指针。 过程中需要注意类型转换的正确性和边界条件的处理,比如空数组或无效指针的情况。同时,确保用户提供的比较函数逻辑正确,这样才能保证max_element函数的正确性。</think>### 解决方案 在C语言中实现泛最大值计算函数需要结合`void*`指针和函数指针机制,具体步骤如下: #### 1. 定义比较函数接口 自定义数据类型的比较逻辑需由调用者提供,函数原为: ```c typedef int (*CompareFunc)(const void*, const void*); ``` #### 2. 实现泛最大值函数 ```c void* max_element(void* array, size_t count, size_t element_size, CompareFunc compare) { if (array == NULL || count == 0 || compare == NULL) return NULL; char* current = (char*)array; char* max_ptr = current; for (size_t i = 1; i < count; i++) { current += element_size; if (compare(current, max_ptr) > 0) { max_ptr = current; } } return max_ptr; } ``` #### 3. 自定义类型的比较实现 例如处理包含分数的结构体: ```c typedef struct { char name[20]; int score; } Student; int compare_student(const void* a, const void* b) { const Student* s1 = (const Student*)a; const Student* s2 = (const Student*)b; return s1->score - s2->score; } ``` #### 4. 使用示例 ```c Student students[] = {{"Alice", 85}, {"Bob", 92}, {"Charlie", 78}}; size_t count = sizeof(students)/sizeof(students[0]); Student* max_student = (Student*)max_element(students, count, sizeof(Student), compare_student); printf("最高分学生: %s (%d分)\n", max_student->name, max_student->score); ``` ### 关键点说明 - **泛实现原理**:通过`void*`接收任意类型数组,使用`element_size`控制元素访问步长[^3] - **类型安全**:比较函数需正确处理类型转换,避免未定义行为 - **边界处理**:函数返回NULL应对空输入,保证鲁棒性[^1] - **性能优化**:时间复杂度$O(n)$,空间复杂度$O(1)$
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值