Chinaunix首页 | 论坛 | 博客
  • 博客访问: 29270
  • 博文数量: 9
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 80
  • 用 户 组: 普通用户
  • 注册时间: 2015-11-09 17:27
个人简介

python技术爱好者,涉猎广泛,主攻大型网站架构与大数据。

文章分类
文章存档

2017年(3)

2015年(6)

我的朋友
最近访客

分类: C/C++

2015-12-04 01:01:29

c语言入门容易,精通难,没个六七年的工作是不行的,所以我会把自己开发中认为精髓的东西,记录下来,以备后需。c语言作为我的本命语言,我觉着其中有很多有趣儿的地方。
c语言是典型的面向过程的语言,没有后来面向对象(OOP)中类,对象,继承,的概念,也就没有数据隐藏机制,但是聪明的人们总会想办法的,于是就有了黑盒模型。黑盒模型故名思议,盒子内部的实现细节对用户来说是不可见的,用户只能通过盒子提供的一个句柄(可以为void *或者int类型,具体实现比较灵活)来访问或者设置盒子内部的数据。
微软的windows操作系统,虽然是用c实现的,但是也采用了面向对象的设计思想,其中一部分就是通过黑盒来实现的。windows平台编程有个非常重要的概念——内核对象句柄(HANDLE),就是黑盒模型的典型代表。无论任何类型的内核对象(进程、文件、事件等等)都通过HANDLE句柄,获取或者设置对象的属性。不过不同windows版本,HANDLE的类型也不一致,有的时void *指针,有的是int类型(进程空间句柄表的索引)。
linux下的文件描述符FD(FileDescriptor)也是类似的实现。
为了演示黑盒模型,特意写了一个demo,linux平台下使用gcc -I./ -o demo -DLINUX demo.c 编译链接生成二进制可执行文件demo

头文件demo.h

点击(此处)折叠或打开

  1. #ifndef __DEMO_H
  2. #define __DEMO_H

  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>

  6. #if defined(WIN32) || defined(_WIN32)
  7. #define STDCALL __stdcall
  8. #elif defined(LINUX)
  9. #define STDCALL
  10. #else
  11. #error "unspported platform"
  12. #endif

  13. typedef void * HOBJECT;

  14. /* create an instance */
  15. HOBJECT STDCALL create_object();

  16. /* set value of specified field */
  17. int STDCALL set_data(HOBJECT obj, int value);

  18. /* get value of specified field, return default value def on error */
  19. int STDCALL get_data(HOBJECT obj, int def);

  20. /* delete object */
  21. void STDCALL delete_object(HOBJECT obj);

  22. #endif


函数、数据结构的定义demo.c
特别注意,设置对象数据成员值并返回旧数据成员值的函数int set_data(HOBJECT obj, int value);采用的是连续三次异或运算,完成ptr->data与value的值交换,而非采用的第三方变量作为交换媒介的方式,这样做的优点,请参阅鄙人接下的博文。


点击(此处)折叠或打开

  1. include "demo.h"
  2.   
  3.   typedef struct
  4.   {
  5.       int obj_id;
  6.       int data;
  7.       /* other data fields */
  8.       /* ... */
  9.   }object;
  10.   
  11.   HOBJECT STDCALL create_object()
  12.   {
  13.       object *obj = (object *)malloc(sizeof(object));
  14.       if(obj != NULL)
  15.       {
  16.           memset((void *)obj, sizeof(object), 0);
  17.           /* object's id */
  18.           obj->obj_id = (int)obj;
  19.           return (HOBJECT)obj;
  20.       }
  21.       return NULL;
  22.   }
  23.   
  24.   int set_data(HOBJECT obj, int value)
  25.   {
  26.       object *ptr=(object *)obj;
  27.       ptr->data ^= value;
  28.       value = ptr->data ^ value;
  29.       ptr->data ^= value;
  30.       return value;
  31.   }

  32.   int get_data(HOBJECT obj, int def)
  33.   {
  34.       return obj != NULL ? ((object *)obj)->data : def;
  35.   }
  36.   
  37.   void delete_object(HOBJECT obj)
  38.   {
  39.       if(obj != NULL)
  40.       {
  41.           free(obj);
  42.           obj=NULL;
  43.       }
  44.   }
  45.   
  46.   int main(int argc, char **argv)
  47.   {
  48.       /* entry point */
  49.       HOBJECT obj = create_object();
  50.       printf("old value:%d\n", set_data(obj, 1000));
  51.       printf("old value:%d\n", set_data(obj, 2000));
  52.       printf("attr:%d\n", get_data(obj, 100));
  53.       delete_object(obj);
  54.   
  55.       return 0;
  56.   }



当然真正的项目中,实现也会相对比较复杂,相对于java这类语言(很多底层的东东对程序猿都是透明的),对象的内存管理就得自己考虑。生产环境对象分配是不可以用malloc的,这样会产生大量的内存碎片,比较推荐的是linux内核的slab内存分配机制,或者使用开源的内存管理库,当然有特殊需求,也可以自己设计内存管理算法。
阅读(1035) | 评论(0) | 转发(0) |
0

上一篇:没有了

下一篇:gcc内联汇编语言(一)

给主人留下些什么吧!~~