前言

封装与抽象

https://m.toutiao.com/is/J92HgV9/

(建立一个rect.h的头文件声明对外提供的几个接口获取长方形对象)

封装性是面向对象编程的三大特性(封装性、继承性、多态性)之一,但也是最重要的特性。封装+抽象相结合就可以对外提供一个低耦合的模块。

数据封装是一种把数据和操作数据的函数捆绑在一起的机制,数据抽象是一种仅向用户暴露接口而把具体的实现细节隐藏起来的机制。

在C语言中,数据封装可以从结构体入手,结构体里可以放数据成员和操作数据的函数指针成员。当然,结构体里也可以只包含着要操作的数据。

下面以一个简单的实例作为演示。

设计一个软件模块,模块中要操作的对象是长方形,需要对外提供的接口有:1、创建长方形对象;

2、设置长、宽;

3、获取长方形面积;

4、打印长方形的信息(长、宽、高);

5、删除长方形对象。

下面我们来一起完成这个demo代码。首先,我们思考一下,我们的接口命名大概是怎样的?其实这是有规律可循的,我们看RT-Thread的面向对象接口是怎么设计的:

我们也模仿这样子的命名形式来给我们这个demo的几个接口命名:

1、rect_create2、rect_set3、rect_getArea4、rect_display5、rect_delete

我们建立一个rect.h的头文件,在这里声明我们对外提供的几个接口。这时候我们头文件可以设计为:

这样做是没有什么问题的。可是数据隐藏得不够好,我们提供给外部用的东西要尽量简单。我们可以思考一下,对于C语言的文件操作,C语言库给我们提供怎么样的文件操作接口?如:FILE *fopen(const char *pathname, const char *mode);size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

我们会创建一个文件句柄(描述符),然后之后只要操作这个文件句柄就可以,我们不用关心FILE具体是怎么实现的。

什么是句柄?看一下百度百科的解释:

我们也可以创建我们的对象句柄,对外提供的头文件中只需暴露我们的对象句柄,不用暴露具体的实现。以上头文件rect.h代码可以修改为:

这里用到了void*,其为无类型指针,void *可以指向任何类型的数据。然后具体要操作怎么样的结构体可以在.c中实现:

下面我们依次实现上述五个函数:

1、rect_create函数

/* 创建长方形对象 */HandleRect rect_create(const char *object_name){ printf('>>>>>>>>>> %s: %s (line: %d) <<<<<<<<<object_name字符串申请内存 */ rect->object_name = (char*)malloc(strlen(object_name) + 1); if (NULL == rect->object_name) { printf('rect->object_name memory malloc failed!\n'); abort(); }​ /* 给结构体各成员进行初始化 */ strncpy(rect->object_name, object_name, strlen(object_name) + 1); rect->length = 0; rect->width = 0; return ((HandleRect)rect);}

rect对象创建函数:首先分配内存,然后对rect结构体各个成员进行赋值操作,最后返回的是rect对象句柄。rect的object_name成员是个字符串,因此要单独分配内存。

2、rect_set函数/* 设置长方形对象长、宽 */void rect_set(HandleRect rect, int length, int width){ printf('>>>>>>>>>> %s: %s (line: %d) <<<<<<<<<length = length; ((pRect)rect)->width = width; }}

3、rect_getArea函数

/* 获取长方形对象面积 */int rect_getArea(HandleRect rect){ return ( ((pRect)rect)->length * ((pRect)rect)->width );}

4、rect_display函数/* 打印显示长方形对象信息 */void rect_display(HandleRect rect){ printf('>>>>>>>>>> %s: %s (line: %d) <<<<<<<<<object_name); printf('length = %d\n', ((pRect)rect)->length); printf('width = %d\n', ((pRect)rect)->width); printf('area = %d\n', rect_getArea(rect)); }}

5、rect_delete函数

void rect_delete(HandleRect rect){ printf('>>>>>>>>>> %s: %s (line: %d) <<<<<<<<<object_name); free(rect); ((pRect)rect)->object_name = NULL; rect = NULL; }}

rect对象删除函数:主要是对创建函数中的malloc申请的内存做释放操作。

可以看到这五个对象接口主要包含三类:创建对象函数、操作函数、删除对象函数。这里的操作函数就是rect_set函数、rect_getArea函数与rect_display函数,当然还可以有其它更多的操作函数。操作函数的特点是至少需要传入一个表示对象的句柄,在函数的内部再做实际数据结构的转换,然后再进行相应的操作。

6、测试程序:#include #include #include 'rect.h'​int main(void){ HandleRect rect = rect_create('rect_obj');  // 创建Rect对象句柄 rect_set(rect, 20, 5);        // 设置     rect_display(rect);        // 打印显示 rect_delete(rect);        // 删除Rect对象句柄 return 0;}

运行结果:

在基于对象的编程中,封装性是最基础也最重要的内容。其对象主要包含两方面内容:属性与方法。在基于C语言的对象编程中,可以使用句柄来表示对象,即句柄指向的数据结构的成员代表对象的属性,实际操作句柄的函数则表示对象的方法。

以上就是本次的分享,如有错误,欢迎指出!谢谢

c语言如何编辑一个长方形,C语言对象编程第一弹封装与抽象(建立长方形对象)...相关推荐

  1. 大学c语言基本程序,一个大学C语言试题的简单实现--员工信息管理程序

    一个大学C语言试题的简单实现,供参考. 题目: 员工信息管理程序 主要用结构体数组实现,用结构体表示每项记录,数据为:员工编号.姓名.性别.年龄.工龄.职务.部门.住址. 设计各个函数,分别实现以下功 ...

  2. c语言编辑密码程序,想程序高手求助--用C语言来编辑一个输入密码的程序

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 /*--------实现密码的隐式输入-----------------*/ inputpw(char *password,int len) /*len为 ...

  3. 用c语言编辑一个通讯录,C语言实现一个通讯录

    实现一个通讯录,通讯录可以用来存储1000个人的信息,每个人的信息包括: 姓名.性别.年龄.电话.住址 提供方法: 1. 添加联系人信息 2. 删除指定联系人信息 3. 查找指定联系人信息 4. 修改 ...

  4. c语言用数组写密码程序,想程序高手求助--用C语言来编辑一个输入密码的程序...

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 /*--------实现密码的隐式输入-----------------*/ inputpw(char *password,int len) /*len为 ...

  5. c语言一个循环重新输入密码,想程序高手求助--用C语言来编辑一个输入密码的程序...

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 /*--------实现密码的隐式输入-----------------*/ inputpw(char *password,int len) /*len为 ...

  6. c语言密码程序返回,想程序高手求助--用C语言来编辑一个输入密码的程序

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 /*--------实现密码的隐式输入-----------------*/ inputpw(char *password,int len) /*len为 ...

  7. c语言编程请输入密码,想程序高手求助--用C语言来编辑一个输入密码的程序

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 /*--------实现密码的隐式输入-----------------*/ inputpw(char *password,int len) /*len为 ...

  8. C语言程序密码输入退回,想程序高手求助--用C语言来编辑一个输入密码的程序...

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 /*--------实现密码的隐式输入-----------------*/ inputpw(char *password,int len) /*len为 ...

  9. c语言:编辑一个有趣的死循环程序并对其修改,仅仅是一个“=”号的差别

    死循环程序: 1 #include<stdio.h> int main() { int  i,arr[10]; for(i=0;i<=10;i++) { printf("你 ...

最新文章

  1. JSP实现小区物业管理系统
  2. logback Appender详解
  3. bfs——练习demo2(20届周新杰提供)
  4. 只显示隐藏文件 显示指定目录下的目录
  5. 走进缓存的世界(一) - 开篇
  6. BugkuCTF-MISC题贝斯手
  7. ai合成迪丽热巴下海_丽热巴被富家哥求婚,男方坚持示爱九个月,当众下跪赠女方豪车...
  8. 产品经理之深度学习促进产品(二)
  9. esp32 io速度_乐鑫科技发布 ESP32-S3 芯片,精准聚焦 AIoT 市场
  10. JAV虚拟机下载 JDK1.6下载大全
  11. Hadoop集群搭建(六):hadoop配置namenode服务
  12. C语言算法-求两直线夹角计算公式
  13. Python:利用python语言实现18位身份证号码和15位身份证号码相互转换
  14. segue 分析小结
  15. 深圳大学计算机研究生调剂,深圳大学2020年硕士研究生招生调剂办法
  16. 实战:淘宝新品想抢占市场流量 分三步进行
  17. Gif动态图片怎么做?如何快速生成gif动图?
  18. 使用TCP/IP协议栈指纹进行远程操作系统辨识
  19. 如何建立一个自己的网站?不懂代码搭建自己网站详细教程
  20. 做外贸有套路,这几招“技巧组合拳“,让你轻松变高手

热门文章

  1. 穆大叔:18年生涯让我抬头挺胸 我是像士兵般离开
  2. 晕LIVEnbsp;WRITER设置教程是网易…
  3. jacob实现ppt转图片时存在的问题
  4. BigNumber.js数值计算-解决精度问题
  5. css圣杯布局与双飞翼布局_CSS布局研讨会已于2018年更新
  6. Rust 正则表达式 Regex
  7. 手机免流量,还会是天方夜谭吗?
  8. FreeRTOS笔记篇:第七章 -- 资源管理(互斥锁、二进制信号量、死锁)
  9. 蓝桥耐摔指数 JAVA暴解(摔手机)
  10. 组件、Prop属性的基本用法