函数指针与C的面向对象

我们都知道C语言是一门面向过程的语言,那么C语言如何实现“面向对象”的编程方式呢?今天我们就来一探究竟

一、C实现面向对象的基石—-函数指针:

1、什么是函数指针:

我们也许听过一级指针(指向普通变量的指针)、二级指针(指向指针的指针)、数组指针(指向数组的指针)、指针数组(数组元素是指针)等概念,那么函数指针是什么呢?顾名思义,从表象上来说:函数指针就是指向函数的指针,但终究它也只是一个指针。怎么说是指向函数的指针呢?请看下例:

void (*test)(void);
/*
格式如此:定义分为三部分,返回值类型、指针名、参数类型。
该语句定义了一个指向“无参数无返回值的函数”指针。
注意:中间(*test)的括号不能省略
*/

2、那么函数指针到底该怎么用呢?举个简单的例子:

# include<stdio.h>

int test_one(int num1, int num2)
{
    return num1 + num2;
}

int test_two(int num1, int num2)
{
    return (num1 - num2);
}
int main(void)
{
    int (*test[5])(int,int);/*定义一个有五个函数指针的数组*/
    test[0] = test_one;/*让数组中第一个元素(函数指针)指向test_one函数*/
    test[1] = test_two;/*让数组中第二个元素(函数指针)指向test_two函数*/

    printf("test_one return value = %d\n",test_one(10,5));
    printf("test_two return value = %d\n",test_two(10,5));

    printf("test[0] return value = %d\n",test[0](10,5));
    printf("test[1] return value = %d\n",test[1](10,5));
}

3、测试结果如下所示:

这里写图片描述

由于函数名本来就是一个指针,而将函数名赋给一个与其类型的相同的指针(函数指针),使用函数指针也就和使用函数名效果一样了。

二、使用函数指针实现C的面向对象:

1、思路:

面向对象,在C++中用的类来实现,而我们都知道在C++中结构体是一种特殊的类(类(class)其默认成员是私有的,而结构体默认成员是公有的),那么我们就在C中就可以使用结构体来实现统一封装与调用。

2、基本实现代码:

这里我将几种对数组的排序函数封装成一类方法,代码如下:

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

struct Sort_Arr{
    int * arr;
    void (*print_arr)(int *,int);//遍历
    void (*sort_bubble)(int *,int);//冒泡排序
    void (*sort_insert)(int *, int);//插入排序
    void (*sort_choose)(int *, int);//选择排序
    void (*sort_quickly)(int *, int, int);//快速排序
    int (*find_pos)(int *, int, int);//快排找pos
    int * (*rand_arr)(int);//生成随机数数组
};


void Print(int *a,int len)
{
    if(0 == len)
    {
        printf("数组为空!\n");
        return;
    }
    int i=0;
    for(i=0;i<len;++i)
        printf("%d  ",a[i]);
    printf("\n");
}

void SortBubble(int *a,int len)
{
    int i, j, temp;
    for(i=0;i<len;i++)
        for(j=0;j<len-i-1;j++)
            if(a[j] > a[j+1])
            {
                temp = a[j];
                a[j] = a[j+1];
                a[j+1] = temp;
            }
}
void SortChoose(int *a,int len)
{
//每次寻找剩余区间最小值,将最小值与区间首元素互换后,区间大小减1(区间首元素后一个元素开始继续循环找最小值)
    int i,j,tmp,min;

    for(i=0;i<len;i++){
        min = a[i];
        tmp = i;
        for(j=i+1; j<len; j++){
            if(a[j] < min){
                min = a[j];
                tmp = j;
            }
        }
        if(tmp != i){
            a[tmp] = a[i];
            a[i] = min;
        }
    }
}
void SortInsert(int *a,int len)
{
//在原有有序的基础上,将紧邻的无序区间首元素插入有序区间,之后有序区间长度加1,无序区间长度减1
    int i,j,k,temp;
    for(i=1;i<len;++i)
    {
        temp = a[i];
        j = i-1;
        while(j >= 0 && a[j] > temp){
            a[j+1] = a[j];//后移
            j--;
        }
        a[j+1] = temp;
    }
}

void SortQuickly(int *a, int low, int high)
{
    int pos;
    if(low < high)
    {
        pos = FindPos(a, low, high);
        SortQuickly(a, low, pos-1);
        SortQuickly(a, pos+1, high);
    }
}

int FindPos(int *a,int low,int high)
{
    int key = a[low];
    while(low < high)
    {
        while(low < high && (a[high] >= key))
            high--;
        a[low] = a[high];

        while(low < high && (a[low] <= key))
            low++;
        a[high] = a[low];
    }
    a[low] = key;
    return low;
}
int * RandArr(int n)
{
    int i;
    int * a = (int *)malloc(sizeof(int) * n);
    if(NULL == a)
    {
        printf("内存分配失败导致数组创建失败!");
        exit(EXIT_FAILURE); 
    }
    srand(time(NULL));
    for(i=0; i<n; i++)
        a[i] = rand()%51-25;//生成-25~45之间的随机数数组      
    return a;
}
int main (void)
{   
    struct Sort_Arr SORTARR = { 
        .print_arr = Print,
        .sort_bubble = SortBubble,
        .sort_insert = SortInsert,
        .sort_choose = SortChoose,
        .sort_quickly = SortQuickly,
        .rand_arr = RandArr
    };
    int len;
    int choose;
    printf("请输入要生成的数组元素个数:\n");

    scanf("%d",&len);
    SORTARR.arr = SORTARR.rand_arr(len);
    printf("生成的数组为:\n");
    SORTARR.print_arr(SORTARR.arr,len);

    printf("(1)冒泡排序\t(2)插入排序\t(3)选择排序\t(4)快速排序\n");
    printf("请输入你要选择的排序方式序号,回车结束:\n");
    scanf("%d",&choose);

    switch(choose)
    {
    case 1:SORTARR.sort_bubble(SORTARR.arr,len);
        break;
    case 2:SORTARR.sort_insert(SORTARR.arr,len);
        break;
    case 3:SORTARR.sort_choose(SORTARR.arr,len);
        break;
    case 4:SORTARR.sort_quickly(SORTARR.arr,0,len);
        break;
    default:printf("其他排序方式正在研制中,请稍候...");
        break;
    }

    printf("排序后的数组为:\n");
    SORTARR.print_arr(SORTARR.arr,len);

    return 0;
}

将此代码稍作修改,制作成静态库或动态库,以后就可以直接使用写好的排序函数了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值