解释区分一下C语言和OOP

       我们经常说C语言是面向过程的,而C++是面向对象的,然而何为面向对象,什么又是面向过程呢?不管怎么样,我们最原始的目标只有一个就是实现我们所需要的功能,从这一点说它们是殊途同归的。过程与对象只是侧重点不同而已。

       举个例子吧,我现在有个计划,要去北京,OOP语言是直接给你一个车,然后你自己设定路线去北京就好,而C语言是需要你自己制造零件,自己组装好车,然后再自己设定路线,最后到达北京。C语言比较费劲,但是程序的效率很高。

 

过程&对象?

       一个对象就是由或多或少的针对这个对象的过程构成的,当然其中是少不了必要的属性。

       一个过程是针对一个或者是多个对象所进行的操作。两者是可以互相转换的,关键是哪一种方式更能适合你现在的需求,更能让你的软件开发锦上添花。

       我个人认为一般情况下,一个更容易扩展、维护的软件通常采用的是OOP的思想,添加一个原本不存在的相对无关单独的个体,总比在一个已经存在的过程内硬塞进去一个对象要简单;而且面向过程更容易导致混乱的维护。

       举个例子,同样是一条河与一个湖泊,哪一个更容管理维护呢?我想答案是显而易见的。当然不管怎么样,软件本身设计架构的好坏也是非常重要的。

 

C语言的特性,实现OOP

       C是一门面向过程的语言,但它依旧可以实现大多数面向对象所能完成的工作。比如面向对象的三大特性:封装、继承、多态。我们以下图来写代码举例子。

 

封装

       由于面象向对象是将数据与方法封装到一个类里。使用者无需关心类是怎么实现的。在 C_OOP 中贯彻了这一思想,C中有一种复杂的数据结构叫做struct。struct是C里面的结构体。

       如上图假如我们要对鸟bird进行封装,bird可能包括姓名、颜色、栖息地、重量、属性等信息。我们就可以对它封装如下:

struct Bird{

    char name[20];//姓名 

    char color;    //颜色   

    char addr[30];    //栖息地 

    int weight;        //体重 

    int other;      //属性 

};

       当我们要像OOP那样新建一个对象时,我们就可以:

struct Bird p;

       我们就可以直接对p进行赋值:

p.name = "bird";

p.color = 'b';  //'b' = black; 'g' = green 

p.addr = 'w';   

p.weight = 175; 

p.other = 1;

 

继承

       在常见用C语言实现继承的机制中,多半是用结构体组合实现的,同样利用struct,我们来创建一个Bird结构,同时继承结构体Bird,如下:

struct fBird{

    struct Bird p; 

    char fly[20]; //飞翔 

    int scream;        //鸣叫 

};

       对Bird进行创建对象,并赋值:

struct fBird s;

s.p.name = "bird"; 

s.p.color = 'b'; 

s.p.other = 25; 

s.p.weight = 65; 

s.fly = "0618"; 

s.scream = 90;

 

多态

       C_OOP中的一个核心就是多态,C中对于多态的实现可以借助函数指针来实现。为了简单起见,我们假设Bird这个结构体中,只有一个函数指针。

struct Bird{

    void (*print)(void *p); 

}; 

struct fBird{ 

    struct Bird p; 

};

       而Bird和fBird这两个结构体的print函数实现如下:

void printBird(void *Bird){

    if(NULL == Bird) 

        return ; 

    struct Bird *p = (struct Bird *)Bird; 

    printf("run in the Bird!!\n"); 

} 

void printfBird(void *Bird){ 

    if(NULL == Bird) 

        return ; 

    struct Bird *p = (struct Bird *)Bird; 

    printf("run in the fBird!!\n"); 

}

       我们写一个函数来调用他们:

void print(void *Bird){

    if(NULL == Bird) 

        return ; 

    struct Bird *p = (struct Bird *)Bird; 

    p->print(Bird); 

} 

int main(){ 

    struct Bird bird; 

    struct fBird fbird; 

    Bird.print = printBird; 

    fBird.p.print = printfBird; 

    print(&bird);    //实参为Bird的对象 

    print(&fbird);  //实参为fBird的对象 

    return 0; 

}

       他们的输出为:

run in the Bird!!

run in the fBird!!

       其实这个也不难理解,无论是fBird还是Bird,他们在内存中只有一个变量,就是那个函数指针,而void表示任何类型的指针,当我们将它强制转换成struct Bird类型时,p->print指向的自然就是传入实参的print地址。


学计算机不易,此路应携手前行。

如果你也想学计算机编程的话!

可以来我的C/C++编程学习基地,【点击进入】

还有免费(零基础教程,项目实战教学视频)!   

涉及:游戏开发、课程设计、常用软件开发、编程基础知识、黑客等等...

和志同道合的小伙伴们一起学编程吧!

 

OOP真的那么重要?

       从大学到工作至今,在嵌入式领域中一直是使用C语言,而我在学习C++的过程中,看的代码越多,代码量越大,越来越觉得C++对于大型软件架构的良好可控性,和对以后程序员维护代码时良好的可读性;

       个人认为:C语言中最大的成功在于它的指针,但是也是最容易出错的,想要理解C,必须要掌握指针。虽然说,语言只是一门工具,但是这是基础.

       或者你可以说C太底层,现在都是OOP的时代了,谁还会用面向过程的,你们不要忘了操作系统是用什么写的?是C;C实现的nginx的并发量是C++实现的apache的几十倍,关键是要理解语言背后的思想。

       当然这不是为了OOP而OOP,实在是OOP的一些特征,例如封装,多态其实是软件工程思想,这些思想不分语言,遵循了这些思想可以使得程序更有弹性,更易修改和维护,避免僵化,脆弱的性质。

 

嵌入式C语言使用OOP的一些思考

       然而就目前来说,在嵌入式领域广泛的使用C++显然是不现实的事情。在一个到处是OOP的年代,为何面向过程的C语言依然可以如此活跃?

       我们可以用它来开发一系列的小工具,Unix/Linux就是由这些小工具组成的操作系统;同时用C语言可以开发高性能的应用程序。

       C语言良好的可移植性,小巧灵活,而且还有一个直接与硬件打交道的指针的存在,对内存等良好的操作性以及执行之速度快,是嵌入式开发唯有的高级语言,均是一般嵌入式产品的不二首选。

 

总结

       语言只是一种工具,任何语言之间都是相通的,一通则百通,关键是要理解语言背后的思想,理解其思想,任何语言,拿来用就行了。语言没有好坏之分,任何语言既然存在自然有它存在的价值。

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐