c面向对象编码风格(上)

面向对象和面向过程的基本概念

面向对象和面向过程是两种不同的编程范式,它们在软件开发中用于组织和设计代码的方式。

面向过程编程(Procedural Programming)是一种以过程(函数、方法)为核心的编程方式。在面向过程编程中,程序被划分为一系列的过程或函数,这些过程按照顺序逐步执行,每个过程都可以接受输入参数并返回输出结果。数据在过程中被操作,通过参数进行传递。面向过程编程关注的是解决问题的步骤和算法,通过将问题拆分为一系列的步骤来解决。

面向对象编程(Object-Oriented Programming,OOP)是一种以对象为核心的编程方式。在面向对象编程中,程序被组织成一系列的对象,每个对象都有自己的属性(数据)和行为(方法)。对象之间通过消息传递来进行通信和交互,对象可以通过继承、封装和多态等特性进行关联和扩展。面向对象编程关注的是将现实世界中的事物抽象成对象,通过对象之间的交互来解决问题。

面向过程和面向对象的主要区别如下:

  1. 抽象程度:面向过程编程更加关注解决问题的具体步骤和算法,将问题分解为一系列的过程。而面向对象编程更加关注问题的抽象,将问题抽象成对象及其相互关系。
  2. 数据和行为:在面向过程编程中,数据和行为是分离的,函数对数据进行操作。而在面向对象编程中,数据和行为紧密结合,对象包含了数据和对数据进行操作的方法。
  3. 封装和隐藏:面向对象编程通过封装将数据和相关方法组合在一起,隐藏了内部实现细节,提供了更好的模块化和抽象性。而面向过程编程没有明确的封装机制,数据和方法之间的关联性较弱。
  4. 继承和多态:面向对象编程通过继承和多态实现代码的重用和扩展,可以创建基于现有类的新类,并对方法进行覆盖或重写。而面向过程编程没有明确的继承和多态特性。

当我们具体分析面向过程和面向对象编程时,可以从以下几个方面进行比较:

  1. 效率:面向过程编程的执行效率通常比面向对象编程高,因为它直接按照步骤执行,没有额外的对象和方法调用开销。而面向对象编程需要创建对象和调用方法,会增加执行的开销。
  2. 可维护性:面向对象编程相较于面向过程编程具有更好的可维护性。面向对象编程利用封装、继承和多态等特性,能够更好地组织和管理代码,降低了代码的耦合性。这样在修改和扩展代码时更容易定位和处理,也减少了对现有代码的影响。
  3. 可复用性:面向对象编程具有更好的可复用性。通过继承和多态等特性,可以基于现有类创建新的类并重用已有的方法和属性。这样可以减少重复编写代码的工作量,提高代码的复用性和可维护性。
  4. 抽象性和扩展性:面向对象编程更加注重对问题的抽象和建模,能够更好地反映现实世界中事物之间的关系。通过类、对象和继承等特性,可以更容易地扩展和修改系统的功能。而面向过程编程则更加关注具体的算法和步骤,对于问题的抽象和扩展性较弱。

一下的代码是使用面向过程的思维进行编写的

#include <easyx.h>
#include <stdio.h>
#include <math.h>
/*
  面向过程和面向对象
  question1: 面向过程 1: 将问题的解法分解成若干步骤 2: 使用函数分别实现这些步骤 3: 依次调用这些函数 
  question2:  面向对象 1: 面向对象的编程逻辑使用c语言实现面向对象的过程
  面向对象编程风格的三大特性 1: 封装 2: 继承 3: 多态
*/

// 创建学生类型的结构体
struct student {
    int id;
    char name[20];
    int gender;
    int mark;

};

// 学生的学号
int makeStudentId(int year, int classNum, int serialNum) {
    char buffer[20];
    // sprintf的作用是字符拼接,将结构传入第一个参数buffer指示的字符当中
    sprintf(buffer, "%d%d%d", year, classNum, serialNum);
    // 函数atoi将指示的字符串转换为整型并返回结果
    int id = atoi(buffer);
    return id;
}
// 定义性别的结构体0表示为女生, 1 表示为男生,定义两个函数对性别进行处理将整型表示的性别转换为字符串表示的性别
const char* numGenderToStrGender(int numGender) {
    if (numGender == 0) {
        return "女";
    }
    else if (numGender == 1) {
        return "男";
    }
    return "佚名";
}
// 将字符串表示的性别转换为整型表示的性别进行处理
int strGenderToNumGender(const char* strGender) {
    int numGender;
    if (strcmp("男", strGender) == 0) {
        numGender = 1;
    }
    else if (strcmp("女", strGender) == 0) {
        numGender = 0;
    }
    else {
        numGender = -1;
    }
    return numGender;
}

int main(){
    // 结构体的声明
    struct student stu;
    // 给id赋值
    stu.id = makeStudentId(2022, 607, 12);
    // 给name赋值
    strcpy(stu.name, "小明");
    // 给gender赋值
    stu.gender = strGenderToNumGender("男");
    // 直接给mark赋值
    stu.mark = 98;

    // 使用printf打印输出相关数据,采用点的方式对函数进行调用
    printf("学号:%d\n", stu.id);
    printf("姓名:%d\n", stu.name);
    // 将数字1和0转换为字符串男和女
    const char* gender = numGenderToStrGender(stu.gender);
    printf("性别%d\n", gender);
    printf("分数%d\n", stu.mark);
    
    return 0;

}

面向对象代码的编写方式

#define _CRT_SECURE_NO_WARNINGS
#include <easyx.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
// 编写函数指针
struct student {
    void (*setStudentId)(struct student* s, int year, int classNum, int serialNum);
    const char* (*getGender)(struct student* s);
    void (*setGender)(struct student* s, const char* strGender);

    int id;
    char name[20];
    int gender;
    int mark;

};


// 学生的学号
void setStudentId(struct student *s,int year, int classNum, int serialNum) {
    char buffer[20];
    // sprintf的作用是字符拼接,将结构传入第一个参数buffer指示的字符当中
    sprintf(buffer, "%d%d%d", year, classNum, serialNum);
    // 函数atoi将指示的字符串转换为整型并返回结果
    int id = atoi(buffer);
    // 使用面向对象的方式直接给结构体中的成员id赋值
    s->id = id;
}

const char* getGender(struct student *s) {
    if (s->gender == 0) {
        return "女";
    }
    else if (s -> gender == 1) {
        return "男";

    }
    return "佚名";

}
// 将字符串表示的性别转换为整型表示的性别进行处理
void setGender(struct student* s, const char* strGender) {
    int numGender;
    if (strcmp("男", strGender) == 0) {
        numGender = 1;
    }
    else if (strcmp("女", strGender) == 0) {
        numGender = 0;
    }
    else {
        numGender = -1;
    }
     s ->gender =  numGender;
}
// 初始化方法
void initStudent(struct student* s)
{
    s->setStudentId = setStudentId;
    s->getGender = getGender;
    s->setGender = setGender;
}
int main(){
    // 结构体的声明
    struct student stu;
    // 函数体在使用过程中需要调用initStudent函数设置正确的指向
    initStudent(&stu);
    // 直接调用函数传入结构体指针
    setStudentId(&stu, 2023, 607, 12);
    strcpy(stu.name, "小明");
    setGender(&stu, "男");
    stu.mark = 98;

    // 使用printf打印输出相关数据,采用点的方式对函数进行调用
    printf("学号:%d\n", stu.id);
    printf("姓名:%s\n", stu.name);
    // 将数字1和0转换为字符串男和女
    const char* gender = stu.getGender(&stu);
    printf("性别%s\n", gender);
    printf("分数%d\n", stu.mark);
    
    return 0;

}

在这里插入图片描述面向对象继承方面的代码

#define _CRT_SECURE_NO_WARNINGS
#include <easyx.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
// 编写函数指针

// 继承
struct person {
    int id;
    char name[20];
    int gender;
    const char* (*getGender)(struct person* s);
    void (*setGender)(struct person* s, const char* strGender);
};
struct teacher {
    struct person super;
    char subject[20];

};
struct student {
    struct person super;
    int mark;
    void (*setStudentId)(struct student* s, int year, int classNum, int serialNum);


};

// 学生的学号
void setStudentId(struct student *s,int year, int classNum, int serialNum) {
    char buffer[20];
    // sprintf的作用是字符拼接,将结构传入第一个参数buffer指示的字符当中
    sprintf(buffer, "%d%d%d", year, classNum, serialNum);
    // 函数atoi将指示的字符串转换为整型并返回结果
    int id = atoi(buffer);
    // 使用面向对象的方式直接给结构体中的成员id赋值
    s->super.id = id;
}

const char* getGender(struct person *s) {
    if (s->gender == 0) {
        return "女";
    }
    else if (s -> gender == 1) {
        return "男";

    }
    return "佚名";

}
// 将字符串表示的性别转换为整型表示的性别进行处理
void setGender(struct person* s, const char* strGender) {
    int numGender;
    if (strcmp("男", strGender) == 0) {
        numGender = 1;
    }
    else if (strcmp("女", strGender) == 0) {
        numGender = 0;
    }
    else {
        numGender = -1;
    }
     s ->gender =  numGender;
}

// 初始化函数指针
void initPerson(struct person* p) {
    p->getGender = getGender;
    p->setGender = setGender;
}
// 初始化函数
void initStudent(struct student* s) {
    initPerson(&(s->super));
    s->setStudentId = setStudentId;
}
// 初始化函数
void initTeacher(struct teacher* t) {
    initPerson(&(t->super));
}

int main(){
    // 结构体的声明
    struct student stu;
    // 函数体在使用过程中需要调用initStudent函数设置正确的指向
    initStudent(&stu);
    // 直接调用函数传入结构体指针
    setStudentId(&stu, 2023, 607, 12);
    strcpy(stu.super.name, "小明");
    stu.super.setGender(&stu.super, "男");
    stu.mark = 98;

    // 使用printf打印输出相关数据,采用点的方式对函数进行调用
    printf("学号:%d\n", stu.super.id);
    printf("姓名:%s\n", stu.super.name);
    // 将数字1和0转换为字符串男和女
    const char* gender = stu.super.getGender(&stu.super);
    printf("性别%s\n", gender);
    printf("分数%d\n", stu.mark);
    putchar('\n');
    struct teacher t;
    
    //  初始化teacher
    initTeacher(&t);
    
    t.super.id = 12345;
    strcpy(t.super.name, "林老师");
    t.super.setGender(&t.super, "男");
    strcpy(t.subject, "C语言");
    
    //  打印这些数值
    printf("学号:%d\n", t.super.id);
    printf("姓名:%s\n", t.super.name);
    gender = t.super.getGender(&t.super);
    printf("性别:%s\n", gender);
    printf("科目:%s\n", t.subject);



    return 0;

}

在这里插入图片描述
面向对象之多态

#include <easyx.h>
#include <stdio.h>

struct Shape {
    void (*draw)(struct Shape*);
};

struct Rect {
    struct Shape super;

    int left;
    int top;
    int right;
    int bottom;
};

struct Circle {
    struct Shape super;

    int x;
    int y;
    int r;
};

struct Triangle {
    struct Shape super;

    POINT p1;
    POINT p2;
    POINT p3;
};

void drawRect(struct Rect* r)
{
    rectangle(r->left, r->top, r->right, r->bottom);
}

void drawCircle(struct Circle* c)
{
    circle(c->x, c->y, c->r);
}

void drawTriangle(struct Triangle* t)
{
    line(t->p1.x, t->p1.y, t->p2.x, t->p2.y);
    line(t->p2.x, t->p2.y, t->p3.x, t->p3.y);
    line(t->p3.x, t->p3.y, t->p1.x, t->p1.y);
}

void initRect(struct Rect* r)
{
    r->super.draw = (void (*)(struct Shape*))drawRect;
}

void initCircle(struct Circle* c)
{
    c->super.draw = (void (*)(struct Shape*))drawCircle;
}

void initTriangle(struct Triangle* t)
{
    t->super.draw = (void (*)(struct Shape*))drawTriangle;
}

int main()
{
    initgraph(800, 600);
    setaspectratio(1, -1);
    setorigin(400, 300);

    setbkcolor(WHITE);
    setlinecolor(BLACK);
    cleardevice();

    struct Rect r = { {}, -200, 200, 200, 0 };
    struct Circle c = { {}, 0, 0, 100 };
    struct Triangle t = { {},  {0, 200}, {-200, 0}, {200, 0} };

    initRect(&r);
    initCircle(&c);
    initTriangle(&t);

    struct Shape* arrShape[3] = {
    (struct Shape*)&r, (struct Shape*)&c, (struct Shape*)&t };

    for (int i = 0; i < 3; i++)
    {
        arrShape[i]->draw(arrShape[i]);
    }

    getchar();
    closegraph();

    return 0;
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/119216.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Docker 多阶段构建的原理及构建过程展示

Docker多阶段构建是一个优秀的技术&#xff0c;可以显著减少 Docker 镜像的大小&#xff0c;从而加快镜像的构建速度&#xff0c;并减少镜像的传输时间和存储空间。本文将详细介绍 Docker 多阶段构建的原理、用途以及示例。 Docker 多阶段构建的原理 在传统的 Docker 镜像构建…

软件设计模式的意义

软件设计模式的意义 所有开发人员都应该接触过软件设计模式这个概念&#xff0c;看过《设计模式-可复用的对象软件的基础》这本书&#xff0c;在面试中都被问过&#xff1a; 你用过哪些设计模式这种问题。但很大可能也就仅此而已了。 为什么好像只能从框架中找到设计模式的应用…

Springboot+vue的导师双选管理系统(有报告)。Javaee项目,springboot vue前后端分离项目。

演示视频&#xff1a; Springbootvue的导师双选管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot vue前后端分离项目。 项目介绍&#xff1a; 本文设计了一个基于Springbootvue的前后端分离的导师双选管理系统&#xff0c;采用M&#xff08;model&a…

11.4-GPT4AllTools版本已开始对小部分GPT3.5用户内测推送

OpenAI已经开始小规模推送GPT4 AllTools功能&#xff0c;部分GPT博主已经第一时间体验了此功能&#xff0c;此功能特色是整合目前的多模态功能以及文件上传和联网模块&#xff0c;无需切换&#xff0c;更要全面综合 可上传包括 PDF、数据文件在内的任意文档&#xff0c;并进行分…

nerdctl install【nerdctl 安装】

文章目录 1. 在线安装2. 离线安装 1. 在线安装 #!/bin/bashsource ./config.shENABLE_DOWNLOAD${ENABLE_DOWNLOAD:-true}if [ ! -e files ]; thenmkdir -p files fiFILES_DIR./files if $ENABLE_DOWNLOAD; thenFILES_DIR./tmp/filesmkdir -p $FILES_DIR fi# download files, i…

智能井盖生产商家,万宾科技井盖传感器产品详情

市政府管理水平决定城市人民幸福程度&#xff0c;所以在智慧城市推进过程中&#xff0c;市政府也在加快城市信息基础设施建设&#xff0c;希望提高公共服务水平&#xff0c;以此来满足城市居民的需求&#xff0c;进一步推进城市信息化智能化发展。作为城市生命线的一个组成部分…

python调用飞书机器人发送文件

当前飞书webhook机器人还不支持发送文件类型的群消息&#xff0c;可以申请创建一个机器人应用来实现群发送文件消息。 创建机器人后&#xff0c;需要开通一系列权限&#xff0c;然后发布。由管理员审核通过后&#xff0c;才可使用。 包括如下的权限&#xff0c;可以获取群的c…

逆向学习记录(4)adb

adb用于PC和手机端通讯。 常用命令如下&#xff1a; 如果不是模拟器&#xff08;模拟器一般都有自己的adb&#xff09;&#xff0c;adb会出现在Andirod的SDK中&#xff0c;路径为&#xff1a;Android/SDK/platform-tools。 最好加入环境变量中。

2、Sentinel基本应用限流规则(2)

2.2.1 是什么 Sentinel 是阿里中间件团队开源的&#xff0c;面向分布式服务架构的轻量级高可用流量控制组件&#xff0c;主要以流量为切入点&#xff0c;从流量控制、熔断降级、系统负载保护等多个维度来帮助用户保护服务的稳定性。 2.2.2 基本概念 • 资源 (需要被保护的东西…

ke9案例三:页面提交文件,我服务器端接收

案例三:页面提交文件,我服务器端接收 ProcessFile.java 1value "/process-file" 2获取邮件消息的所有部分part--Collection<Part> partsrequest.getParts(); 3遍历每一个part 4之后可以打印头文件等String headerpart.getHeader("content-disposition&q…

esxi 6.7下安装黑裙

esxi上创建一个黑裙系统的虚拟机&#xff0c;用来存资料 一、工具 硬件&#xff1a; 工控机&#xff1a;装有esxi6.7系统&#xff08;192.168.100.2&#xff09;&#xff0c;配置&#xff1a;3865U&#xff0c;16G内存&#xff0c;120Gmsata120sata硬盘&#xff0c;6个网口 主…

web前端——HTML+CSS实现九宫格

web前端——HTMLCSS实现九宫格 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title&…

基准测试详解

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;交流讨论&#xff1a;欢迎加入我们一起学习&#xff01;&#x1f4e2;资源分享&#xff1a;耗时200小时精选的「软件测试」资…

星辰天合受邀参加红帽2023中国区合作伙伴大会

近日&#xff0c;“共创成功” ——红帽 2023 中国区合作伙伴大会成功举行&#xff0c;包括 XSKY星辰天合在内的 100 多位合作伙伴受邀出席&#xff0c;分享开源时代的合作共赢之道&#xff0c;探讨新业态下的市场策略。 红帽2023中国区合作伙伴大会现场 红帽今年 30 岁了&…

《研发效能(DevOps)工程师》课程简介(四)丨IDCF

由国家工业和信息化部教育与考试中心颁发的职业技术证书&#xff0c;也是国内首个研发效能&#xff08;DevOps&#xff09;职业技术认证&#xff0c;内涵1000页学习教材2000分钟的课程内容讲解460多个技术知识点300多道练习题。涵盖【组织与协作】、【产品设计与运营】、【开发…

[Lingo编程极速入门]——基础01

目录索引 直接求解&#xff1a;基本约束条件书写&#xff1a;思考&#xff1a; 多段式编程&#xff1a;模板&#xff1a;问题引入&#xff1a;解法&#xff1a;第一句&#xff1a;第二、三句&#xff1a;第四句&#xff1a; 直接求解&#xff1a; 首先我们进行最简单的Lingo求解…

P02项目(学习)

★ P02项目 项目描述&#xff1a;安全操作项目旨在提高医疗设备的安全性&#xff0c;特别是在医生离开操作屏幕时&#xff0c;以减少非授权人员的误操作风险。为实现这一目标&#xff0c;我们采用多层次的保护措施&#xff0c;包括人脸识别、姿势检测以及二维码识别等技术。这些…

民宿酒店服务预约小程序的作用

民宿往往是旅游者们前往某个城市感受风情常住的地方&#xff0c;也因此在景区或特定地方&#xff0c;总是不乏大小民宿品牌&#xff0c;但除了市场高需求外&#xff0c;商家们所遇的痛点也不少&#xff1a; 1、获客引流难 民宿生意虽然需求量高&#xff0c;但各家品牌众多&am…

索引和事务

文章目录 一、索引1.1 概念1.2 作用1.3 使用场景1.4 使用 二、事务2.1 为什么要使用事务2.2 事务的概念2.3 事务的使用 三、内容重点总结 一、索引 1.1 概念 索引是一种特殊的文件&#xff0c;包含对数据表所有记录的引用指针。在MySQL中&#xff0c;索引是基于一个或多个列的…

如何在word文档中批量插入二维码

合同系统中&#xff0c;一般流程是线上拟稿、审批、定稿&#xff0c;然后线下打印定稿的合同并且存档。当拿到一个纸质合同&#xff0c;需要去线上系统查询当时的合同拟制过程&#xff0c;那如何快速定位到这个文档&#xff0c;是一个问题。通用的做法是&#xff0c;将该文档的…