C语言中的函数指针以及模拟面向对象

函数指针的概念

顾名思义,函数指针就是指向函数的指针,该指针的值是函数的入口。下面的代码时函数指针的一个基本实例。

#include <stdio.h>
int max_(int a, int b);
int max1_(int (*func_p)(int, int), int a, int b);

int main() {
    int a = 10, b = 20;
    // 定义一个函数指针p,并且p指向函数max_
    int (*p)(int, int) = max_;
    int ret = p(a, b);
    printf("ret = %d\n", ret);

    // 函数作为实参,函数指针作为形参
    int ret1 = max1_(max_, a, b);
    printf("ret1 = %d\n", ret1);

    return 0;
}

int max_(int a, int b) {
    // 返回两个整数中的较大值
    return a>b?a:b;
}

int max1_(int (*func_p)(int, int), int a, int b) {
    // func_p是函数指针,指向函数max_
    return func_p(a, b);
}

将函数指针封装到结构体中,体现了面向对象编程的三大思想

  • 1.封装:结构体内的函数指针成员作为结构体对象的行为,结构体内的非函数指针成员作为结构体对象的属性。
  • 2.继承:Animal是一个结构体,Dog也是一个结构体,同时Dog有一个成员是Animal,这样Dog就继承了Animal的所有“属性”和“方法”(对于结构体来说,属性和方法都是结构体成员)
  • 3.多态:Dog和Cat都继承了Animal。Animal有一个函数指针定义了Animal的叫声speak,Dog的叫声就是wang wang, 猫的叫声就是miao miao
    更具体地,Animal.speak = speak(); Dog.animal.speak() = wang(); Cat.animal.speak() = miao();
    wang()函数和miao()函数自己实现
#include <stdio.h>
#include <stdlib.h>
typedef struct Animal {
    // 将函数指针封装在结构体中,当作类的方法成员
    char* name;
    void (*speak)(struct Animal *animal);
}Animal;
typedef struct Dog {
    // 将父结构体封装在自己内部,实现继承
    // Dog继承了Animal的所有属性和方法
    Animal animal;
    char sex;  // 狗是公的还是母的;用'm', 'f'表示
}Dog;
typedef struct Cat {
    // Cat继承了Animal类,并且有自己的属性color和方法sleep
    Animal animal;
    char* color;
    void (*sleep)(struct Cat *cat);  // 表示Cat对象在睡觉
}Cat;

void animal_speak(Animal* animal);
Animal* create_animal(char* name);

void dog_speak(Animal* animal);
Dog* create_dog(char* name, char sex);

void cat_speak(Animal* animal);
Cat* create_cat(char* name, char* color);
void cat_sleep(Cat* cat);


int main() {
    // 创建一个Animal对象
    Animal* animal = create_animal("BuGu");
    animal->speak(animal);

    // 创建一个Dog对象
    Dog* dog = create_dog("Puppy", 'm');
    dog->animal.speak(&(dog->animal));
    printf("The sex of %s is %c\n", dog->animal.name, dog->sex);

    // 创建一个Cat对象
    Cat* cat = create_cat("Alice", "yellow");
    cat->animal.speak(&(cat->animal));
    printf("The color of %s is %s\n", cat->animal.name, cat->color);
    cat->sleep(cat);

    return 0;
}

void animal_speak(Animal* animal) {
    // animal_speak函数传递给Animal对象的”函数指针“成员
    printf("I am an animal and %s is speaking!\n", animal->name);
}

Animal* create_animal(char* name) {
    // 创建一个Animal对象,返回指向此对象的指针
    Animal* animal = (Animal*) malloc(sizeof(Animal));
    animal->name = name;
    animal->speak = animal_speak;
    return animal;
}

void dog_speak(Animal* animal) {
    // dog_speak函数传递给Dog对象的Animal成员的”函数指针“成员
    printf("I am a dog and %s is wang wang wang!\n", animal->name);
}

Dog* create_dog(char* name, char sex) {
    // 创建一个Dog对象,返回指向此对象的指针
    Dog* dog = (Dog*)(malloc(sizeof(Dog)));
    dog->animal.name = name;
    dog->animal.speak = dog_speak;
    dog->sex = sex;
    return dog;
}

void cat_speak(Animal* animal) {
    // cat_speak函数传递给Cat对象的Animal成员的”函数指针“成员
    printf("I am a cat and %s is miao miao miao!\n", animal->name);
}

void cat_sleep(Cat* cat) {
    // cat_sleep函数传递给Cat对象的”函数指针“成员sleep
    printf("%s is sleeping!\n", cat->animal.name);
}

Cat* create_cat(char* name, char* color) {
    // 创建一个Cat对象,返回指向此对象的指针
    Cat* cat = (Cat*)(malloc(sizeof(Cat)));
    cat->animal.name = name;
    cat->animal.speak = cat_speak;
    cat->color = color;
    cat->sleep = cat_sleep;
    return cat;
}

posted @ 2023-09-22 23:13  Guanjie255  阅读(78)  评论(0编辑  收藏  举报