首页 > 其他分享 >C语言中的函数指针以及模拟面向对象

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

时间:2023-09-22 23:22:54浏览次数:35  
标签:Cat animal int cat 面向对象 Animal 函数指针 C语言 speak

函数指针的概念

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

#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;
}

标签:Cat,animal,int,cat,面向对象,Animal,函数指针,C语言,speak
From: https://www.cnblogs.com/gjsun/p/17665696.html

相关文章

  • 七天学会C语言-第七天(结构体)
    1.定义结构体例1:把一个学生的信息(包括学号、姓名、性别、住址等4项信息)放在一个结构体变量中,然后输出这个学生的信息。#include<stdio.h>structStudent{intstudent_id;charname[30];chargender;charaddress[60];};intmain(){struc......
  • C语言学习-- ~ 按二进制取位 前置后置++ 关系操作符 逻辑操作符
    #include<stdio.h>//~按二进制取位intmain(){inta=10;intb=~a;/*~按二进制取位如101--~=010*/printf("%d\n%d\n",a,b);/*运行a=10b=-11在二进制里的最高位表示符号位,0为正1为负(3=000…………011)源码......
  • C语言学习-- ~ 按二进制取位 前置后置++ 关系操作符 逻辑操作符
    #include<stdio.h>//~按二进制取位intmain(){inta=10;intb=~a;/*~按二进制取位如101--~=010*/printf("%d\n%d\n",a,b);/*运行a=10b=-11在二进制里的最高位表示符号位,0为正1为负(3=000…………011)源码......
  • 【三子棋】——玩家VS电脑(C语言实现)
    (文章目录)前言三子棋是黑白棋的一种。三子棋是一种民间传统游戏,又叫九宫棋、圈圈叉叉、一条龙、井字棋等。将正方形对角线连起来,相对两边依次摆上三个双方棋子,只要将自己的三个棋子走成一条线,对方就算输了。但是,有很多时候会出现和棋的情况。:pig:好了话不多说,现在我就带大家......
  • c语言双指针法--原地删除数组中的元素
     27.移除元素-力扣(LeetCode) intremoveElement(int*nums,intnumsSize,intval){intleft=0;intright=0;while(right<numsSize){if(nums[right]!=val){nums[left]=nums[right];left++;}......
  • c语言-关键字static
    局部变量:运行周期=函数的运行周期全局变量:运行周期=整个程序的运行周期(程序可以是多个.c文件组成)static可以修饰:1、局部变量(函数内定义的)2、全局变量(函数外定义的) 3、函数1.修饰局部变量->静态局部变量:开辟存储空间。在编译的过程中,会在数据区为该变量开辟空间,并对其进行......
  • c语言 qsort函数的使用
    #include<iostream>#include<stdio.h>voidprinfArray(int*nums,intsize){for(inti=0;i<size;i++){printf("%d",nums[i]);}printf("\n");}intcompare(voidconst*a,voidconst*......
  • 七天学会C语言-第六天(指针)
    1.指针变量与普通变量指针变量与普通变量是C语言中的两种不同类型的变量,它们有一些重要的区别和联系。普通变量是一种存储数据的容器,可以直接存储和访问数据的值。:intnum=10;//定义一个整数型普通变量num,赋值为10在例子中,变量num是一个普通整数变量,它直接存储了值10。指针变......
  • JAVA基础 —— 面向对象内存图
    JAVA基础——面向对象内存图......
  • 学习C语言的第八天
    今天没有学新内容,把前两天的代码又回味了下,发现有几个还是算不上理解,只能说是背住了,不知道有没有大佬会看到我写的东西,如果看到了,能不能告诉我一下,像一些不容易理解的代码,我背住它有用吗?写一个代码让电脑关机#include<windows.h>#include<stdio.h>#include<string.h>intmain()......