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

news2025/1/9 16:26:03

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

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

面向过程编程(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;
}

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2021年电工杯数学建模B题光伏建筑一体化板块指数发展趋势分析及预测求解全过程论文及程序

2021年电工杯数学建模 B题 光伏建筑一体化板块指数发展趋势分析及预测 原题再现&#xff1a; 国家《第十四个五年规划和 2035 年远景目标纲要》中提出&#xff0c;将 2030 年实现“碳达峰”与 2060 年实现“碳中和”作为我国应对全球气候变暖的一个重要远景目标。光伏建筑一体…

七月论文审稿GPT第二版:从Meta Nougat、GPT4审稿到LongLora版LLaMA、Mistral

前言 如此前这篇文章《学术论文GPT的源码解读与微调&#xff1a;从chatpaper、gpt_academic到七月论文审稿GPT》中的第三部分所述&#xff0c;对于论文的摘要/总结、对话、翻译、语法检查而言&#xff0c;市面上的学术论文GPT的效果虽暂未有多好&#xff0c;可至少还过得去&am…

1.Netty概述

原生NIO存在的问题(Netty要解决的问题) 虽然JAVA NIO 和 JAVA AIO框架提供了多路复用IO/异步IO的支持&#xff0c;但是并没有提供给上层“信息格式”的良好封装。JAVA NIO 的 API 使用麻烦,需要熟练掌握 ByteBuffer、Channel、Selector等 , 所以用这些API实现一款真正的网络应…

题解:轮转数组及复杂度分析

文章目录 &#x1f349;前言&#x1f349;题目&#x1f34c;解法一&#x1f34c;解法二&#xff1a;以空间换时间&#x1f95d;补充&#xff1a;memmove &#x1f34c;解法三&#xff08;选看&#xff09; &#x1f349;前言 本文侧重对于复杂度的分析&#xff0c;题解为辅。 …

02-React组件与模块

组件与模块 前期准备 安装React官方浏览器调试工具&#xff0c;浏览器扩展搜索即可 比如红色的React就是本地开发模式 开启一个用React写的网站&#xff0c;比如美团 此时开发状态就变成了蓝色 组件也能解析出来 何为组件&模块 模块&#xff0c;简单来说就是JS代…

亚马逊云科技大语言模型下的六大创新应用功能

目录 前言 亚马逊云科技的AI创新应用 ​编辑 Amazon CodeWhisperer Amazon CodeWhisperer产品的优势 更快地完成更多工作 自信地进行编码 增强代码安全性 使用收藏夹工具 自定义 CodeWhisperer 以获得更好的建议 如何使用Amazon CodeWhisperer 步骤 1 步骤 2 具体…

php7.4.32如何快速正确的开启OpenSSL扩展库,最简单的办法在这里!

&#x1f680; 个人主页 极客小俊 ✍&#x1f3fb; 作者简介&#xff1a;web开发者、设计师、技术分享博主 &#x1f40b; 希望大家多多支持一下, 我们一起进步&#xff01;&#x1f604; &#x1f3c5; 如果文章对你有帮助的话&#xff0c;欢迎评论 &#x1f4ac;点赞&#x1…

GNU ld链接器 lang_process()(二)

一、ldemul_create_output_section_statements() 位于lang_process()中11行 。 该函数用于创建与目标有关的输出段的语句。这些语句将用于描述输出段的属性和分配。 void ldemul_create_output_section_statements (void) {if (ld_emulation->create_output_section_sta…

PS Raw中文增效工具Camera Raw 16

Camera Raw 16 for mac&#xff08;PS Raw增效工具&#xff09;的功能特色包括强大的图像调整工具。例如&#xff0c;它提供白平衡、曝光、对比度、饱和度等调整选项&#xff0c;帮助用户优化图像的色彩和细节。此外&#xff0c;Camera Raw 16的界面简洁易用&#xff0c;用户可…

每日一题 187. 重复的DNA序列(中等)

由于今天做了周赛&#xff0c;每日一题就简单点直接暴力哈希 class Solution:def findRepeatedDnaSequences(self, s: str) -> List[str]:d defaultdict(int)ans []for i in range(len(s) - 9):t s[i: i 10]d[t] 1if d[t] 2:ans.append(t)return ans

CCC数字钥匙设计【NFC】 --通过NFC进行车主配对Phase4

1、车主配对流程介绍 车主配对可以通过车内NFC进行&#xff0c;若支持UWB测距&#xff0c;也可以通过蓝牙/UWB进行。通过NFC进行车主配对总共有5个Phase。本文档主要对Phase4进行介绍。 1) Phase0&#xff1a;准备阶段&#xff1b; 2) Phase1&#xff1a;启动流程&#xff1…

凸优化问题(最简单)

一、凸优化问题 1.1 概念 凸优化问题minf(x)&#xff1a;需要同时满足两个条件&#xff1a;变量可行域时凸的(convex)&#xff1b;目标函数也是凸函数(convex)。 &#xff08;1&#xff09;变量x的可行域Ω为凸集&#xff0c;即对于集合Ω中任意两点x1、x2∈Ω&#xff0c;他…

使用阿里云服务器,httplib库在listen过程中,出现Cannot assign requested address错误???

今天&#xff0c;在做一个小项目的时候&#xff0c;使用httplib库进行建立tcp连接&#xff0c;但是一旦程序开始&#xff0c;并没有等待tcp连接的到来&#xff0c;而是直接结束了。 打印一下strerror(errno) 根本就没有进行客户端的连接。 找了一下午&#xff0c;检测是否…

SEO优化的好帮手,5个必备的好工具

做海外市场的企业&#xff0c;谷歌SEO是一个非常重要的方式&#xff0c;帮助提高自己企业的网站曝光&#xff0c;起着至关重要的作用&#xff0c;因为人们普遍会通过网上搜索来找到那些适合的商品&#xff0c;与排名靠后的公司相比&#xff0c;出现在搜索结果顶部的公司往往能吸…

有人物联网模块连接阿里云物联网平台的方法

摘要&#xff1a;本文介绍有人物联网模块M100连接阿里云的参数设置&#xff0c;作为说明书的补充。 没有阿里云功能需求的请略过本文&#xff0c;不要浪费您宝贵的时间。 网络选择LTE&#xff0c;请先确保插入的SIM卡有流量。 接下来配置阿里云云服务。如下图所示&#xff0c;…

802.11 CSMA/CA协议

《计算机网络自顶向下》P351的总结提炼

Linux应用开发基础知识——交叉编译与gcc编译(一)

前言&#xff1a; 源文件需要经过编译才能生成可执行文件。在 Windows 下进行开发时&#xff0c;只需 要点几个按钮即可编译&#xff0c;集成开发环境(比如 Visual studio)已经将各种编译 工具的使用封装好了。Linux 下也有很优秀的集成开发工具&#xff0c;但是更多的时候是 直…

x264交叉编译(ubuntu+arm)

1.下载源码 https://code.videolan.org/videolan/x264 在windows下解压&#xff1b;复制到ubuntu&#xff1b; 2.进入源码文件夹-新建脚本文件 touch sp_run.sh 3.在sp_run.sh文件中输入 #!/bin/sh./configure --prefix/home/alientek/sp_test/x264/sp_install --enable-…

Gradle中的依赖Dependencies说明与使用总结

【1】依赖的方式 Gradle 中的依赖分别为直接依赖&#xff0c;项目依赖&#xff0c;本地jar 依赖。 dependencies {//①.依赖当前项目下的某个模块[子工程]implementation project(:subject01)//②.直接依赖本地的某个jar文件implementation files(libs/foo.jar, libs/bar.jar…

Vue3.0 路由

简介 Vue Router 是 Vue.js 的官方路由。它与 Vue.js 核心深度集成&#xff0c;让用 Vue.js 构建单页应用变得轻而易举。功能包括&#xff1a; 嵌套路由映射动态路由选择模块化、基于组件的路由配置路由参数、查询、通配符展示由 Vue.js 的过渡系统提供的过渡效果细致的导航控…