函数指针浅谈

1. 基本概念

首先,应该明确:

  • 程序运行期间,每个函数都会占用一段连续的内存空间。
  •  函数名就是该函数所占内存区域的起始地址(也 称“入口地址”)
  •  将函数的入口地址赋给一个指针变量,使该指 针变量指向该函数。然后通过指针变量就可以 调用这个函数。这种指向函数的指针变量称为 “函数指针”。

函数指针定义的一般形式为:

类型名 (* 指针变量名)(参数类型1, 参数类型2,…);

 “类型名”表示被指函数的返回值的类型。
 “(参数类型1, 参数类型2,……)”中则依次列出了被指函数的所有参数的类型。例如:

int (*pf)(int ,char);

表示pf是一个函数指针,它所指向的函数,返回值 类型应是int,该函数应有两个参数,第一个是int 类 型,第二个是char类型。

  • 可以用一个原型匹配的函数的名字给一个函数指针赋值。
  • 要通过函数指针调用它所指向的函数,写法为:

函数指针名(实参表);

下面的程序说明了函数指针的用法:

#include <stdio.h>
void PrintMin(int a, int b){
     if( a<b ) printf("%d",a);
     else
        printf("%d",b);
}
int main(){
     void (* pf)(int ,int);
     int x = 4, y = 5;
     pf = PrintMin; 
     pf(x,y);
     return 0; 
}

输出结果为:4

2. 函数指针应用:快速排序库函数qsort

看看qsort函数的定义:

void qsort(void *base, int nelem,
unsigned int width,
int ( * pfCompare)(const void *, const void *));
  • base是待排序数组的起始地址;
  •  nelem是待排序数组的元素个数;
  •  width是待排序数组的每个元素的大小(以字节单位;
  • 最后一个参数 pfCompare是一个函数指针,它指向一个“比较函 数”。

排序就是一个不断比较并交换位置的过程。  qsort如何在连元素的类型是什么都不知道的情 况下,比较两个元素并判断哪个应该在前呢?

 答案是,qsort函数在执行期间,会通过 pfCompare指针调用一个 “比较函数”,用以判断两个元素哪个更应该排在前面。
 这个“比较函数”不是C/C++的库函数,而是由使用 qsort的程序员编写的
 在调用qsort时,将“比较函数”的名字作为实参传递给 pfCompare。程序员当然清楚该按什么规则决定哪个元素应该在前,哪个元素应该在后,这个规则就体 现在“比较函数”中。

qsort函数的用法规定,“比较函数”的原型应是:

int 函数名(const void * elem1, const void * elem2);

该函数的两个参数,elem1和elem2,指向待比 较的两个元素。也就是说, * elem1和 * elem2 就是待比较的两个元素。该函数必须具有以下
行为:

  • 如果 * elem1应该排在 * elem2前面,则函数返回值是 负整数(任何负整数都行)。
  • 如果 * elem1和* elem2哪个排在前面都行,那么函数 返回0
  • 如果 * elem1应该排在 * elem2后面,则函数返回值是 正整数(任何正整数都行)

一个栗子:

下面的程序,功能是调用qsort库函数,将一个 unsigned int数组按照个位数从小到大进行排 序。比如 8,23,15三个数,按个位数从小到 大排序,就应该是 23,15,8。

#include <stdio.h>
#include <stdlib.h>
int MyCompare(const void * elem1, const void * elem2 ){

    unsigned int * p1, * p2;
    p1 = (unsigned int *) elem1;
    p2 = (unsigned int *) elem2; return (*p1%10) -(*p2%10);
}
#define NUM 5
int main(){
    unsigned int an[NUM] = { 8,123,11,10,4 }; 
    qsort(an, NUM, sizeof(unsigned int),MyCompare);
    for(int i = 0;i < NUM; i ++ )
    printf("%d ", an[i]); return 0;

输出结果:
10 11 123 4 8

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值