c 语言是面向对象程序设计,C 语言面向对象编程 - 封装

news/2024/7/5 20:20:14

回复: 126

e5a73b6a7586c690ae7a720f72a4e733.png

ccfb3c64a5000ccc1971125e1fdae7b2.png

20f7beba86b4a360a2108c8a34a4ebf3.png

C 语言面向对象编程 - 封装

2ea3b4ed82cf9d3f3b6bf536024f3243.png

(46263843)

出0入0汤圆

电梯直达

ac34f29e61779188a50d361fdeae2c1f.png

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-29 08:53:31

|

只看该作者

8d1228179cec554492e4b5a60a447513.gif

|倒序浏览

|阅读模式

本帖最后由 广轻电气091 于 2019-11-29 17:01 编辑

大部分使用 C 语言进行开发的工程师,在接触更高级的编程语言之前,都认为 C 语言是面向过程的。

确实,对于一些小规模的应用程序,C 语言一般都被用作面向过程编程。例如:单片机应用程序开发。

但是,如果是使用 C 语言开发一些规模较大的软件时,就必须用面向对象的思想去考虑和设计整个软件框架了。例如:嵌入式Linux操作系统。

嵌入式Linux操作系统虽然是使用 C 语言作为主要的编写语言,但里面的设计大部分都使用了面向对象的编程思想。

很多单片机工程师或者嵌入式Linux驱动初学者,觉得入门困难,很大一部分原因就是,他们还停留在单片机那种面向过程的思维模式上面。

编程语言只是一种工具,编程思想才是用好这个工具的关键。C 语言只是工具,而面向对象是一种编程思想,用来指导我们如何用好 C 语言。

接下来,我们将尝试使用 C 语言进行面向对象程序开发,务求使用 C 语言实现面向对象的一些基本特性。

首先,我们先来说说封装。

封装就是把一个抽象事物的属性和属性的操作函数打包在一起,外界的模块只能通过这个抽象事物对外提供的函数接口,对其属性进行访问。

在C++或其他高级语言中,封装通常被称作“类”。而 C 语言一般使用结构体对事物进行封装。

接下来,我们先看两段代码,这两段代码主要声明和定义了一个坐标类对象,以及其坐标属性,还提供坐标属性的操作函数。

头文件 coordinate.h

源文件 coordinate.c

代码比较简单,在头文件 coordinate.h里面,通过结构体封装了一个coordinate类,里面有两个坐标属性 x 和 y 。

coordinate_create 函数主要用于创建一个 P_COORDINATE_T 类型的对象,并为其分配内存空间,内存分配成功后,设置两个坐标属性的初始值,最后返回申请成功的对象指针。

coordinate_destroy  主要是释放对象之前申请的内存空间,然后把对象指针重置为NULL。

其他的操作函数,主要是对类对象的属性进行操作,比如获取 x 和 y 的属性值,重置坐标的属性值。

以下是测试函数,在主函数中调用,即可测试类coordinate对外提供的接口。

测试代码比较简单,主要是创建了两个 P_COORDINATE_T 类型的对象,然后打印其坐标初始值,再通过对外提供的函数修改其坐标值,然后再打印出来。

测试函数运行后,结果如下所示:

从上述代码可以看出,使用结构体可以很好地对数据进行封装,并且需要通过指定的操作函数对结构体内的数据进行访问。

每个操作函数的第一个参数是对象本身的指针,通过这个指针去访问具体对象里面的属性。

这是因为在 C 语言中不存在像 C++ 语言那样的 this 指针,所以我们只能显式地通过函数传参的方式,让函数内部可以访问对象实例的其他成员。

对于对象属性的各种操作函数,还可以使用函数指针的方式,放入结构体内进行封装。但为了便于理解,本文并没有采用这种方法。

源码下载地址:https://github.com/embediot/my_program_test

欢迎关注我的技术公众号

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-29 09:11:39

|

只看该作者

没有对象的人只能面壁编程了

eddc9a0618bc3b57b955bf9d8fb61c71.gif

b14d91619ed6ba98b5f91c8184fe6b8c.png

(46262402)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-29 09:17:32

来自手机

|

只看该作者

留个记号

b14d91619ed6ba98b5f91c8184fe6b8c.png

(46262402)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-29 09:17:32

来自手机

|

只看该作者

留个记号

4f78fc9649fa51053e603faeb4f1ec88.png

(46261529)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-29 09:32:05

|

只看该作者

想问一下 为什么结构体指针引用成员时,不用加(*),而一般的单个变量指针取值时要加(*)?

书上这么规定的吗?

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-29 09:35:03

|

只看该作者

楼主讲得真好,我就是总搞不清楚结构体

2ea3b4ed82cf9d3f3b6bf536024f3243.png

(46260471)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2019-11-29 09:49:43

|

只看该作者

很抱歉,我不是很能理解你的问题呢。 *是表示取值符,表示取某个地址存储的值。

2ea3b4ed82cf9d3f3b6bf536024f3243.png

(46260449)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2019-11-29 09:50:05

|

只看该作者

2ea3b4ed82cf9d3f3b6bf536024f3243.png

(46260349)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2019-11-29 09:51:45

|

只看该作者

4f78fc9649fa51053e603faeb4f1ec88.png

(46260181)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-29 09:54:33

|

只看该作者

不好意思,问得太挫了。

p_coordinate->x  取x的值,我有限的知识认为应该这么写: *(p_coordinate->x)

2ea3b4ed82cf9d3f3b6bf536024f3243.png

(46259638)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2019-11-29 10:03:36

|

只看该作者

如果 x 是被定义为指针变量,那写成 *(p_coordinate->x) 是正确的。但代码里, x 是 short int 类型的变量,因此,直接引用就可以了

195f233e89a7c0ddcc2cf974edd956ca.png

(46259203)

出0入8汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-29 10:10:51

|

只看该作者

有机会也用这种方法试试,

试过某高人的类似高焕堂那种方法--把函数也写到结构体里面,感觉在构造环境时,相对楼主的方法,有点繁琐。楼主的方法几乎没有在C上强加多少绕弯的东西(比如,宏)。用C就是想要那种明明白白的感觉。

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-29 10:14:06

|

只看该作者

本帖最后由 chen849928055 于 2019-11-29 10:20 编辑

当前离线

精华汤圆VIP++

{*}

417ed852d27e8c159716eac4e3779f56.gif

1b4a4fd8fd1273de6c0eef5aed7b827d.png

(46258818)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-29 10:17:16

|

只看该作者

标记一下,学习了

2ea3b4ed82cf9d3f3b6bf536024f3243.png

(46257943)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2019-11-29 10:31:51

|

只看该作者

是的,你的理解是正确的

2ea3b4ed82cf9d3f3b6bf536024f3243.png

(46257887)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2019-11-29 10:32:47

|

只看该作者

下一篇文章,会把函数通过函数指针的方式,封装在结构体内,进一步模块化和提高封装性

2ea3b4ed82cf9d3f3b6bf536024f3243.png

(46257826)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2019-11-29 10:33:48

|

只看该作者

bfbf3afe30d3513d68895b3acb123164.png

(46257610)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-29 10:37:24

|

只看该作者

p_coordinate->x并不是指针,*(p_coordinate->x)这么用肯定不对,这里p_coordinate才是指针(也就是个地址),后面跟着连续的内存空间,存储着x,y两个值。

如果你一定要用*取值也是可以的,像下面这样就行了

X = *(short int *)pp_coordiante;

Y = *((short int *)pp_coordiante + 1);复制代码

c03dc33140dfa8f0d1b6a8207082fd05.png

(46257603)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-29 10:37:31

|

只看该作者

感谢楼主分享,学习一下楼主的思想!

当前离线

精华汤圆VIP++

{*}

417ed852d27e8c159716eac4e3779f56.gif

8866e748091bd35ceb38959c6a061aee.png

(46257583)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-29 10:37:51

|

只看该作者

结构体里包含函数指针,应该挺常见的吧

228a55fc9300d0ffb3930abf4542a0ac.png

(46257482)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-29 10:39:32

|

只看该作者

LZ的字体看着难受。

bfbf3afe30d3513d68895b3acb123164.png

(46257410)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-29 10:40:44

|

只看该作者

理解了结构体是连续的内存空间,会方便你更深刻的理解指针的含义。假如有一个结构体内部很多参数需要存储到flash,很多人会单独一个一个参数的存储,而用结构体指针可以直接引用指针,然后按照结构体的长度连续读取N个字节存到flash上可以了,读取一样的(反过来就行)。

d2012824655351e2aa695b5d04188f09.png

(46257186)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-29 10:44:28

|

只看该作者

本帖最后由 FireBrain 于 2019-11-29 10:54 编辑

从来就不推荐用c模拟面向对象的写法,代码可读性简直不忍直视。我没看过linux内核代码,即使它用到了某些OO思想,比如模拟实现了继承、多态等的特性,也绝不会是你的style来写的,那样还不如直接c++

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-29 10:45:26

|

只看该作者

(short int *)这样是先把p_coordiante转换为short int型  再对short intp_coordiante取值吗?

bfbf3afe30d3513d68895b3acb123164.png

(46256703)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-29 10:52:31

|

只看该作者

是的,指针实际上就是个地址,你认为它是什么就强制转化成什么就可以了,再利用结构体空间上连续的特性。有个经典的float转hex,也是利用的指针的特性,float是4个字节,强制转换成char或者int都可以。

2ea3b4ed82cf9d3f3b6bf536024f3243.png

(46256679)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2019-11-29 10:52:55

|

只看该作者

是的,使用指针,不妨记住这几点:1、指针的本质是变量。2、*表示取值符,取地址里面的值。3、&表示取址符,取某个变量的地址

2ea3b4ed82cf9d3f3b6bf536024f3243.png

(46256644)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2019-11-29 10:53:30

|

只看该作者

2ea3b4ed82cf9d3f3b6bf536024f3243.png

(46256614)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2019-11-29 10:54:00

|

只看该作者

2ea3b4ed82cf9d3f3b6bf536024f3243.png

(46256556)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2019-11-29 10:54:58

|

只看该作者

534c105238064587ab10d3eaa81eef02.png

(46256510)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-29 10:55:44

|

只看该作者

p_coordinate是结构体指针

p_coordinate->x

等价于

(*p_coordinate).x

2ea3b4ed82cf9d3f3b6bf536024f3243.png

(46256437)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2019-11-29 10:56:57

|

只看该作者

为什么 Linux kernel 不用 C++ 进行编写?本文所表达的意思是,C 语言使用面向对象的思想,可以让代码的模块化程度更高,耦合度更低,方便以后维护和迭代

d2012824655351e2aa695b5d04188f09.png

(46256417)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-29 10:57:17

|

只看该作者

我只能说你的品味很独特

2ea3b4ed82cf9d3f3b6bf536024f3243.png

(46256302)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2019-11-29 10:59:12

|

只看该作者

d2012824655351e2aa695b5d04188f09.png

(46256279)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-29 10:59:35

|

只看该作者

不要曲解,我是说c语言OO代码的风格,linux内核不会有这么明显的创建对象,销毁对象的代码

bfbf3afe30d3513d68895b3acb123164.png

(46256090)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-29 11:02:44

|

只看该作者

说的很对,很多时候感觉难懂是应该自身修为还不够,有机会多去玩玩java C#这种高级语言学习下他们的思维方式很重要。

58cf14b251491909eebb37e09ed3b699.png

(46255834)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-29 11:07:00

|

只看该作者

感谢楼主分享,学习一下楼主的思想!

ac667b4087bc157975d217bf521833d2.png

(46253921)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-29 11:38:53

|

只看该作者

本帖最后由 WM_CH 于 2019-11-29 11:39 编辑

别人不调用你的接口函数,直接修改变量值也可以。应该加上访问控制把结构体内部的实现隐藏起来

结构体实现放在.c中,.h直接写结构体声明

2ea3b4ed82cf9d3f3b6bf536024f3243.png

(46253237)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2019-11-29 11:50:17

|

只看该作者

感谢指导。从语法层面来说,是可以无限制访问的,毕竟 C 结构体不是真的面向对象特性,没有private, public, protect

4f78fc9649fa51053e603faeb4f1ec88.png

(46253125)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-29 11:52:09

|

只看该作者

感谢楼上几位指导,懂了谢谢,还是水平太差。

当前离线

精华汤圆VIP

{*}

417ed852d27e8c159716eac4e3779f56.gif

27e7cbd20bcf08d2eaddb0e0e2d3fd11.png

(46252730)

出0入4汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-29 11:58:44

|

只看该作者

把函数也封装进去

精华汤圆VIP

{*}

417ed852d27e8c159716eac4e3779f56.gif

c99d2c039ef7a2dc740990f7810a1f42.png

(46252669)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-29 11:59:45

|

只看该作者

这个层面暴露接构体,用户直接在接口里面改变量.... 只能说是层面上的封装. ooc不怎么适合c.

虽然有一定的方面作一定层面细节上的屏蔽,

比如这样:

//! 消息邮箱结构体

typedef struct {

uint16_t dumy0;

uint16_t dumy1;

void *pdumy2;

} MsgBox_t;复制代码

内部真实是这样:

// 消息队列结构体

typedef struct {

uint16_t count;

uint16_t capacity;

MsgQ_t qHead;

} msgBoxInner_t;复制代码

但最终都改变不了暴露的指针对实体操作的问题, 你永远无法想像各类程序员的脑洞有多大, 什么操作都有

ce73c5bdae8d310f67f8caa083397262.png

(46251046)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-29 12:26:48

|

只看该作者

留个记号

2ea3b4ed82cf9d3f3b6bf536024f3243.png

(46249863)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2019-11-29 12:46:31

|

只看该作者

是的,因为C语言是除了汇编之外最接近硬件底层的编程语言,理论上,C可以做任何事。这种做法,是思维上的面向对象,不是真正从语法层面上的面向对象

2ea3b4ed82cf9d3f3b6bf536024f3243.png

(46249815)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2019-11-29 12:47:19

|

只看该作者

a5d2ca5f33a989e25ecbcc84eb6b7d35.png

(46243067)

出0入4汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-29 14:39:47

|

只看该作者

刚才到github你的主页下载了 smartlight_system-master 源码, 编译了一下竟然可以运行

eddc9a0618bc3b57b955bf9d8fb61c71.gif

a5d2ca5f33a989e25ecbcc84eb6b7d35.png

(46242589)

出0入4汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-29 14:47:45

|

只看该作者

编译运行如图

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

5c188826d536ec0714ea80e8d147c64f.png

(46242008)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-29 14:57:26

|

只看该作者

封装可以只暴露接口,不暴露数据。

比如头文件:

typedef struct interface1_struct {

void (*func1) (int a, int b);

bool (*func1) (int a);

void* priv;

} interface1_t;

static inline void interface1_func1(interface1_t *me, int a, int b) {

me->func1(a,b);

}

static inline bool interface1_func2(interface1_t *me, int a) {

return me->func2(a);

}

interface1_t* create_interface1_type1();

interface1_t* create_interface1_type2();

所有的具体实现,都可以在C文件里面实现。而且可以有若干种不同的实现。

2ea3b4ed82cf9d3f3b6bf536024f3243.png

(46241803)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2019-11-29 15:00:51

|

只看该作者

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-29 15:01:02

来自手机

|

只看该作者

mark一下

2ea3b4ed82cf9d3f3b6bf536024f3243.png

(46241769)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2019-11-29 15:01:25

|

只看该作者

是的,这是一种封装程度更高的思路,感谢指导

a5d2ca5f33a989e25ecbcc84eb6b7d35.png

(46241528)

出0入4汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-29 15:05:26

|

只看该作者

2ea3b4ed82cf9d3f3b6bf536024f3243.png

(46239540)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2019-11-29 15:38:34

|

只看该作者

a5d2ca5f33a989e25ecbcc84eb6b7d35.png

(46237150)

出0入4汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-29 16:18:24

|

只看该作者

2ea3b4ed82cf9d3f3b6bf536024f3243.png

(46234605)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2019-11-29 17:00:49

|

只看该作者

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

195f233e89a7c0ddcc2cf974edd956ca.png

(46234495)

出0入8汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-29 17:02:39

|

只看该作者

封装进去以后,还得多一步----给它赋值,感觉麻烦。每个实例都要留一套相同的指向相同函数的指针,又浪费空间又浪费时间,浪费感情。

2ea3b4ed82cf9d3f3b6bf536024f3243.png

(46234359)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2019-11-29 17:04:55

|

只看该作者

感谢指导,对于模块化,降低耦合度,请问有何高见?愿闻其详

842fba350f2c7d57f06b70dbbd41c6a4.gif

195f233e89a7c0ddcc2cf974edd956ca.png

(46233228)

出0入8汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-29 17:23:46

|

只看该作者

太抬举了,我是一直在在对象和“光棍”之间徘徊(不论编程上还是生活中,呵呵)。

有时觉得对象好,有时觉得没有对象更清楚。看环境了,在C环境下面,看楼主1楼的帖子,觉得---心中有对象.实际没对象---这种方式,也是挺好的。

就是对C的面向过程的一根筋编程方式有点意见:我觉得用“ptThread”的方式,变换一下就好了。

也期望楼主有更好的方法。

当前离线

精华汤圆高级会员

{*}

417ed852d27e8c159716eac4e3779f56.gif

f865c29b4e360c5331c90aa8a95abc69.png

(46232255)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-29 17:39:59

|

只看该作者

其实然而没有太大意义。

特别是嵌入式领域,c的优点,c++不可替代。同样,c++的优点也很明显。

但用c模拟c++是比较奇怪的存在,我觉得研究这个有点浪费时间。

b6f62345c778b931d8796ca9d16f5e2e.png

(46232158)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-29 17:41:36

来自手机

|

只看该作者

广轻电气091 发表于 2019-11-29 10:03

如果 x 是被定义为指针变量,那写成 *(p_coordinate->x) 是正确的。但代码里, x 是 short int 类型的变 ...

这是用的什么编辑器,字体配色很好看。

2ea3b4ed82cf9d3f3b6bf536024f3243.png

(46231890)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2019-11-29 17:46:04

|

只看该作者

文中所表达的意思是,用面向对象的思想去使用 C 语言,可以降低代码的耦合度,让代码框架更模块化,便于后期的维护和迭代呢。

每种语言都有其优劣,本文不是片面地表达谁劣谁优,而是在我们开发的过程中,可以借鉴其他优秀的思想。

Linux内核和RTT等操作系统,都是 C 语言编写,但思想都是面向对象的。

2ea3b4ed82cf9d3f3b6bf536024f3243.png

(46231867)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2019-11-29 17:46:27

|

只看该作者

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-29 17:53:49

|

只看该作者

赞一个 ,感觉现在写代码确实需要这样封装,条理清晰

要不然就是 全局变量很多,可读性不好,

2ea3b4ed82cf9d3f3b6bf536024f3243.png

(46230460)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2019-11-29 18:09:54

|

只看该作者

尽量少用或不用全局变量,特别是跨 .c 调用的全局变量

当前离线

精华汤圆高级会员

{*}

417ed852d27e8c159716eac4e3779f56.gif

f865c29b4e360c5331c90aa8a95abc69.png

(46225182)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-29 19:37:52

|

只看该作者

大多嵌入式代码已经按功能分类了。最后调功能引出的接口中就可以了。

如果仿c++,再引入函数指针,那么这个类就必须全部参与编译,增加程序大小,对于嵌入式一般都是资源紧张的,不太适合。

对于比较高级的片子,esp32或linux,空间比较多,直接c++倒是更好的选择。

我在十年前曾经在几个项目中大量应用OOPC,封装的极其漂亮。实际在出货时还要人工根据有没有引用到这个函数去注释掉以减下代码量,感觉好麻烦。

后面就直接不再使用这种方法了。

由于时代情况,比如向主流看,向钱看等。所以我不是很建议楼主去做这方面的研究,反倒搞些little-shell, easyflash, cjson,littlefs倒是很实用。

不过现在嵌入式工程师整体思想不如互联网工程师。从这个角度来讲,强制通过形式的方式教育一下(比如10年前对OOPC对我的教育),这是很好的,这方面的意义很大。

精华汤圆VIP

{*}

417ed852d27e8c159716eac4e3779f56.gif

c99d2c039ef7a2dc740990f7810a1f42.png

(46215975)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-29 22:11:19

来自手机

|

只看该作者

相由心生 发表于 2019-11-29 19:37

大多嵌入式代码已经按功能分类了。最后调功能引出的接口中就可以了。

如果仿c++,再引入函数指针,那么这 ...

这位哥们戳到关键处了。。。你干的事我都干过,最后在单片机上为了减少编译代码量,而在封装中用大量宏。导致时间久翻出来用时会有点懵逼裁剪的事。 linux上我直接上golang或python,解决我在用c时的所有痛点。 在单片机上我现在只是相应的简单封装,够用就行。  如果要真oo思想,python,c++一系列面向对象随便搞,linux不差一点空间。

2ea3b4ed82cf9d3f3b6bf536024f3243.png

(46167856)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2019-11-30 11:33:18

|

只看该作者

是的,感谢建议!你说得很有道理,OOPC并不是所有场合都适用。使用 OOPC,对于锻炼面向对象思维和学习 C 指针,有积极意义,所以才花了一两周的时间去仔细琢磨一下。

2ea3b4ed82cf9d3f3b6bf536024f3243.png

(46167790)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2019-11-30 11:34:24

|

只看该作者

是的,你说的是应用层的高级语言编程,为了加快开发效率,确实是需要使用面向对象语言进行开发。但对于系统底层的结构框架,OOPC也占有一席之地

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-30 16:27:29

|

只看该作者

eddc9a0618bc3b57b955bf9d8fb61c71.gif高手过招点到为止已彼此心领神会,看几位的讨论非常精彩。我也不建议单片机或小型嵌入式应用场合过度封装。一段代码如果有必要在多个项目应用,把接口适当封装写漂亮点无可厚非,但太多类似应用后反而觉得浪费时间写封装的时间也浪费接手开发人员的时间,同时对于硬件资源也会有所浪费。

eddc9a0618bc3b57b955bf9d8fb61c71.gif

c9855b11766800f758528d1981533e71.png

(46148193)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-30 17:01:01

来自手机

|

只看该作者

NanceMichael 发表于 2019-11-30 16:27

高手过招点到为止已彼此心领神会,看几位的讨论非常精彩。我也不建议单片机或小型嵌入式应用场合过 ...

又要封装得好,又要节约资源

只有上C++模板实现的编译时多态技术

比如st收购的TouchGFX就是一个例子

缺点就是会用的人太少

2ea3b4ed82cf9d3f3b6bf536024f3243.png

(46143078)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2019-11-30 18:26:16

|

只看该作者

是的,具体问题具体分析

2ea3b4ed82cf9d3f3b6bf536024f3243.png

(46143055)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2019-11-30 18:26:39

|

只看该作者

高级语言貌似还有运行时多态

eddc9a0618bc3b57b955bf9d8fb61c71.gif

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-30 18:39:09

来自手机

|

只看该作者

运行时多态配合虚函数才叫牛逼

842dea009ec5e4edbe47facf88c41629.png

(46138943)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-30 19:35:11

|

只看该作者

那就是类了吧

842dea009ec5e4edbe47facf88c41629.png

(46138889)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-30 19:36:05

|

只看该作者

2ea3b4ed82cf9d3f3b6bf536024f3243.png

(46129639)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2019-11-30 22:10:15

|

只看该作者

精华汤圆中级会员

{*}

417ed852d27e8c159716eac4e3779f56.gif

6ec44a3d23fb8b11512d198e7ca0c282.png

(46128499)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-11-30 22:29:15

|

只看该作者

C语言的特点是小 精,  干核心函数用的,有些技巧和方法自己学习,理解语言都没啥问题, 但是真不适合实际应用.

当前离线

精华汤圆VIP

{*}

417ed852d27e8c159716eac4e3779f56.gif

3559f2069e058c7d451f5963000e57bc.png

(46118902)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-12-1 01:09:12

|

只看该作者

用C语言去实现面向对象的编程是一件吃力不讨好的事!但了解一下还是可以增强自己的编程能力的。

精华汤圆VIP

{*}

417ed852d27e8c159716eac4e3779f56.gif

b0f4db2e843f1fa60b59e6f37b710843.png

(46073328)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-12-1 13:48:46

|

只看该作者

期待楼主的下一篇文章

a4306ded652b54a0fd1ce8f9b54602d3.png

(46055766)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-12-1 18:41:28

来自手机

|

只看该作者

c++的 “++” 部分确实抽象难以理解,最好用dos下的 turbo c++学习,写一些简单的例子程序,编译时选择输出汇编代码,看看存储结构和调用,这样的话我想应该更加一目了然。

2ea3b4ed82cf9d3f3b6bf536024f3243.png

(46049188)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2019-12-1 20:31:06

|

只看该作者

不是呢,Linux kernel里面全是复杂的面向对象思想和设计模式

2ea3b4ed82cf9d3f3b6bf536024f3243.png

(46049121)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2019-12-1 20:32:13

|

只看该作者

用这种思想去编写程序,程序的模块化会更好,耦合度会更低

2ea3b4ed82cf9d3f3b6bf536024f3243.png

(46049104)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2019-12-1 20:32:30

|

只看该作者

2ea3b4ed82cf9d3f3b6bf536024f3243.png

(46049081)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2019-12-1 20:32:53

|

只看该作者

是的,多练多写

2ea3b4ed82cf9d3f3b6bf536024f3243.png

(46004792)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2019-12-2 08:51:02

|

只看该作者

本文PDF下载:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

24a20dc1d00f43b4284cceea3bb76839.png

(45955194)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-12-2 22:37:40

|

只看该作者

多谢大神回复。倒是解决了我近期的疑惑。之前的代码,大都是按照模块封装,觉得也还好。后面先“规范”团队代码。接触了很多进一步封装的内容。

但是看到诸如ZLG的Ametal的时候,一边羡慕封装的“完美”,一边感叹是否需要这样。一直在打转转~看来是时候做减法了。再次感谢!!!

4e3a061a6cee689711774664b8e32641.png

发表于 2019-12-3 20:11:11

|

只看该作者

标记一下

b05050051b3fa22a7df34f7cdc3406b5.png

(45871681)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-12-3 21:49:33

|

只看该作者

留个记号!!!

74e03519d72dd33e77e8e8812e36a2ff.png

(45870933)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-12-3 22:02:01

|

只看该作者

加油,为啥不直接上c++

2ea3b4ed82cf9d3f3b6bf536024f3243.png

(45827265)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2019-12-4 10:09:49

|

只看该作者

2ea3b4ed82cf9d3f3b6bf536024f3243.png

(45827237)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2019-12-4 10:10:17

|

只看该作者

b9d254a6db7b2526d12bc1b61bc292c5.png

(45266722)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-12-10 21:52:12

|

只看该作者

先留个记号,回头看看

edc2ab94de1e0c8f3d2637f069e237ab.png

(45224507)

出0入4汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-12-11 09:35:47

|

只看该作者

学习了。

2ea3b4ed82cf9d3f3b6bf536024f3243.png

(45222856)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2019-12-11 10:03:18

|

只看该作者

2ea3b4ed82cf9d3f3b6bf536024f3243.png

(45222790)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2019-12-11 10:04:24

|

只看该作者

4e3a061a6cee689711774664b8e32641.png

发表于 2019-12-25 08:41:22

|

只看该作者

写得太经典了,谢谢楼主的分享,已关注!

d2971dac98d6682691b0dd4046b52e23.png

(44017755)

出0入10汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-12-25 08:48:19

|

只看该作者

c用了很多年了   实在不想改了  要改也改行 呵呵

定楼主的分享

2ea3b4ed82cf9d3f3b6bf536024f3243.png

(44017429)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2019-12-25 08:53:45

|

只看该作者

2ea3b4ed82cf9d3f3b6bf536024f3243.png

(44017407)

出0入0汤圆

3ed6c70162101cdc4cfc0ceaf175c8cd.png

楼主|

发表于 2019-12-25 08:54:07

|

只看该作者

感谢支持!

01100bab6bcee30eb89adfb74eb3e182.png

(44015341)

出0入0汤圆

4e3a061a6cee689711774664b8e32641.png

发表于 2019-12-25 09:28:33

|

只看该作者

其实不是,最简单的就是c++只是把c语言的数据跟方法放在一个叫class的东西去了,在c语言里分成2个部分:一个struct以及一系列围绕这个struct进行操作的函数。


http://www.niftyadmin.cn/n/3660210.html

相关文章

Vista 是真正意义操作系统的回归吗?

Vista 是被微软寄予厚望的新一代桌面操作系统。它会给我们的生活工作带来什么?无数人带着这个问题来关注它的一举一动。微软却因为种种原因推迟Vista发布,在吊足了大家的胃口的同时也让许多用户感到失望。相信许多耐不住性子的人已经参加了微软的CPP计划…

c语言编译undeclared,C语言中,为什么这样的代码编译时出错a undeclared(first use in this function),...

局部变量的作用域在花括号里面。全局变量的作用域&#xff0c;在程序整个运行期间。建议将变量a的定义放到do while 外面。例如&#xff1a;#include#include void onetype(char ddd,char t);int main(){std::ifstream one("two.txt");std::cout<char two,three,f…

【MVP】罗江华

目前就职于某全球十大电子商务公司之一,.Net产品开发组成员, 微软MVP, 成都.Net俱乐部会长, 常撰写和翻译一些技术文章和组织一些俱乐部的交流活动。2006年毕业于西华大学软件学院&#xff0c;擅长C#、Remoting,Web Service,MSMQ等技术&#xff0c;常用SQL Server及.NET进行软件…

led version 2.0 摇摇棒编程软件c 语言,基于单片机控制LED摇摇棒的解决方案 - 全文...

摇摇棒本为开发套件&#xff0c;全部采用直插的器件。显示的LED采用了5mm超高亮30度聚光发光二极管&#xff0c;共 32只。控制芯片采用宏晶单片机STC11F03E&#xff0c;其内部有3K的程序存储空间&#xff0c;256字节的数据存储空间&#xff0c;另外其内部还有2K的EEPROM空间。设…

[CSDN 视频--新闻分析第一期]:vista操作系统 电子商务 浏览器之争

视频链接&#xff1a; http://live.csdn.net/Issue18/livePlay.aspx [CSDN视频--新闻分析]本期话题&#xff1a;Vista 是真正意义操作系统的回归吗&#xff1f;http://blog.csdn.net/EricLee00/archive/2006/07/10/900312.aspx微软应该是技术圈里&#xff0c;被关注的一个焦点。…

c语言程序设计实验报告 实验2 数据类型,C语言程序设计实验报告——实验2数据类型、运算符和表达式...

《C语言程序设计实验报告——实验2数据类型、运算符和表达式》由会员分享&#xff0c;可在线阅读&#xff0c;更多相关《C语言程序设计实验报告——实验2数据类型、运算符和表达式(6页珍藏版)》请在人人文库网上搜索。1、装订线装订线凯里学院 C语言程序设计 实验报告专业 年级…

CSDN 未来网站内容Tag架构猜想

大概是上周吧&#xff0c;写了一篇blog主观的分析了一下CSDN目前的内容架构&#xff0c;收到许多朋友好的意见和建议&#xff0c;在此首先对他们表示感谢。网络变化真的很快&#xff0c;现在的网站内容架构较2&#xff0c;3年前已经有翻天覆地的变化。很多人也提出了“如今的网…

[技术指针]今日关键词:企业搜索

最近&#xff0c;Baidu一定是网上最热的的新闻关键词之一。围绕Baidu裁掉整个软件事业部的新闻在网上被炒得沸沸扬扬。我们姑且不讨论员工解散的事事非非&#xff0c;因为目前下结论还为时过早。从另一个角度看这个事情&#xff0c;Baidu 裁掉的软件事业部&#xff0c;其中一块…