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


shape.h 该文件定义的是图形接口,所有具体图形都必须实现自己计算面积,周长等API

#ifndef SHAPE_H
#define SHAPE_H typedef struct shape_t
{
void *shapeData;
void (*area)(void *);
void (*release)(void *);
}Shape; #endif

circle.h 圆形接口

#ifndef CIRCLE_H
#define CIRCLE_H typedef struct
{
double r;
}CircleData; typedef struct
{
void *shapeData;
void (*area)(void *);
void (*release)(void *);
}Circle; Circle *makeCircle(double r); #endif

circle.c 圆形的实现代码,static修饰的函数其实相当于private函数

#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include "circle.h" const double PI = 3.14159; static void area(void *shape)
{
Circle *_circle = (Circle *)shape;
CircleData* data = (CircleData*)_circle->shapeData;
printf("the circle area is %f \n", data->r * data->r * PI);
} static void release(void *shape)
{
Circle *_circle = (Circle *)shape;
CircleData* data = (CircleData*)_circle->shapeData;
free(data);
free(_circle);
} Circle *makeCircle(double r)
{
CircleData* circleData = (CircleData*)malloc(sizeof(CircleData));
Circle* circle = (Circle*)malloc(sizeof(Circle));
assert(circleData != NULL);
assert(circle != NULL);
assert(r > ); circleData->r = r;
circle->shapeData = circleData;
circle->area = &area;
circle->release = &release; return circle;
}

square.h

#ifndef SQUARE_H
#define SQUARE_H typedef struct
{
double x;
double y;
}SquareData; typedef struct
{
void *shapeData;
void (*area)(void *);
void (*release)(void *);
}Square; Square *makeSquare(double x, double y); #endif

square.c

#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include "square.h" static void area(void *shape)
{
Square *square = (Square *)shape;
SquareData* data = (SquareData*)square->shapeData;
printf("the square area is %f \n", data->x * data->y);
} static void release(void *shape)
{
Square *square = (Square *)shape;
SquareData* data = (SquareData*)square->shapeData;
free(data);
free(square);
} Square *makeSquare(double x, double y)
{
SquareData* squareData = (SquareData*)malloc(sizeof(SquareData));
Square* square = (Square*)malloc(sizeof(Square));
assert(squareData != NULL);
assert(square != NULL);
assert(x > && y > ); squareData->x = x;
squareData->y = y;
square->shapeData = squareData;
square->area = &area;
square->release = &release; return square;
}

main.c 所有的工作,都为了它,是为了让它的代码稳定

#include <stdio.h>
#include "shape.h"
#include "circle.h"
#include "square.h" void printShapeArea(Shape **shape,int length)
{
int i=;
for(i=;i<length;i++)
{
shape[i]->area(shape[i]);
shape[i]->release(shape[i]);
}
} int main()
{
Shape *p[] = {(Shape*)makeCircle(3.2),(Shape*)makeCircle(3.2),(Shape*)makeSquare(3.1,)};
printShapeArea(p,);
return ;
}

总结:

printShapeArea 函数并不知道传入的图形列表分别都是哪些图形,这些图形又都怎么计算面积和周长,它唯一知道的是,这些图形计算面积和周长的接口是什么,通过这个接口计算就好了

C语言实现的OOP的更多相关文章

  1. 【百度文库课程】Java语言基础与OOP入门学习笔记一

    一. Java的历史与由来 原名Oak,针对嵌入式系统开发设计,语法与C/C++基本一致 二. Java语言特点 Java由四方面组成:Java编程语言.Java类文件格式.Java虚拟机和Java应 ...

  2. C++语言-05-三大特性

    概述 C++ 是面向对象的语言,具备 OOP 的基本特性. 封装 概念 将数据和操作数据的函数绑定在一起 作用 避免受到外界的干扰和误用,确保了安全 与封装相关的概念 数据抽象 仅向用户暴露接口而把具 ...

  3. Go语言中结构体的使用-第1部分结构体

    1 概述 结构体是由成员构成的复合类型.Go 语言使用结构体和结构体成员来描述真实世界的实体和实体对应的各种属性.结构体成员,也可称之为成员变量,字段,属性.属性要满足唯一性.结构体的概念在软件工程上 ...

  4. 简单易懂的Dart》 - Dart语言中文简明教程

    转自:https://www.blackglory.me/straightforward-dart/ Dart是Google公司发布的网络编程语言,其诞生的目的是为了让广大C类OOP程序员们克服Jav ...

  5. Atitit.go语言golang语言的新的特性  attilax总结

    Atitit.go语言golang语言的新的特性  attilax总结 1. 继承树less  动态接口1 1.1. 按照书中说的,Go语言具有以下的特征,下面我们分别来进行介绍.  q 自动垃圾回收 ...

  6. 用C实现OOP面向对象编程(1)

    如摘要所说,C语言不支持OOP(面向对象的编程).并这不意味着我们就不能对C进行面向对象的开发,只是过程要复杂许多.原来以C++的许多工作,在C语言中需我们手动去完成. 博主将与大家一起研究一下如下用 ...

  7. JavaScript:最烂与最火

    ============================================================================== 一.世无英雄,遂使竖子成名 1 Web客户 ...

  8. python 类属性和实例属性

    class AAA(): aaa = 10 # 情形1 obj1 = AAA() obj2 = AAA() print obj1.aaa, obj2.aaa, AAA.aaa # 情形2 obj1.a ...

  9. 一分钟了解PHP

    PHP5编辑 PHP5在长时间的开发及多个预发布版本后,2004年7月13日,PHP5.0发布.该版本以Zend引擎Ⅱ为引擎,并且加入了新功能如PHP Data Objects(PDO).PHP5.0 ...

随机推荐

  1. 继网易博客后搜狐博客也增加了nofollow标签

    继网易博客后搜狐博客也增加了nofollow标签 今天在搜狐博客发表了篇文章,在末端添加上我的版权,结果回头查看是发现,这个锚文本被加上了nofollow标签,也就是说这样的外链已经没有传递权重的作用 ...

  2. Netbeans 注释模板配置

    工具->模板->展开Java 选中Java类->在编辑器中打开 修改如下: <#if package?? && package != ""& ...

  3. Codeforces 543D Road Improvement

    http://codeforces.com/contest/543/problem/D 题意: 给定n个点的树 问: 一开始全是黑边,对于以i为根时,把树边白染色,使得任意点走到根的路径上不超过一条黑 ...

  4. leetcode_Search in Rotated Sorted Array II

    Follow up for "Search in Rotated Sorted Array": What if duplicates are allowed? Would this ...

  5. LIBRARY_PATH和LD_LIBRARY_PATH环境变量的区别

    LIBRARY_PATH和LD_LIBRARY_PATH是Linux下的两个环境变量,二者的含义和作用分别如下: LIBRARY_PATH环境变量用于在程序编译期间查找动态链接库时指定查找共享库的路径 ...

  6. jsDelivr - Free open source CDN for javascript libraries, jQuery plugins, CSS frameworks, Fonts and more

    jsDelivr - Free open source CDN for javascript libraries, jQuery plugins, CSS frameworks, Fonts and ...

  7. fdm_search_info_w_book_chain

    数据知识管理平台-元数据管理-fdm_search_info_w_book_chain-详细信息 fdm_search_info_w_book_chain

  8. spring简单入门示例

    1 控制反转IOC\依赖注入DI,因为翻译的不同,因此有两个名字.       控制反转意思就是说,当我们调用一个方法或者类时,不再有我们主动去创建这个类的对象,控制权交给别人(spring). 依赖 ...

  9. 使用sublime text2怎样新建文件高速生成HTML头部信息?

    前提须要安装Emmet插件.安装完毕后重新启动sublime. 输入下面简写,按Tab. html:4t <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML ...

  10. [2011山东省第二届ACM大学生程序设计竞赛]——Identifiers

    Identifiers Time Limit: 1000MS Memory limit: 65536K 题目:http://acm.sdut.edu.cn/sdutoj/problem.php?act ...