博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
No!No!No! It's not fashion!
阅读量:6329 次
发布时间:2019-06-22

本文共 3925 字,大约阅读时间需要 13 分钟。

还记得搞怪的hold住姐Miss Lin么,对于人们常规的行为,Miss Lin会挑起夸张的眉毛说:"Oh my God, it's not fashion!"。如果程序员圈子里有位Miss Lin,对于一些功能的实现,她会认为哪些编码实现方法是not fashion的,哪些是fashion的呢?

下面示例中,循规蹈矩先生编码但求功能实现,喜好使用常规方法,hold住姐实现功能的同时,不忘fashion一把。

问题一:事件触发库函数支持三种事件类型:IO事件(包括读/写)、信号和超时事件,请编码定义以上事件类型并说明使用方法。

循规蹈矩先生

1.事件类型定义

#define EV_TIMEOUT 1                  #define EV_READ    2 #define EV_WRITE   3 #define EV_SIGNAL  4

2.使用方法

有效性判断:

if(ev_events >= EV_TIMEOUT && ev_events <= EV_SIGNAL){……}

根据事件类型进行事件处理:

if(ev_events == EV_READ){……}

No! No! No! it's not fashion!

**Miss Lin**

1.定义事件类型:

#define EV_TIMEOUT 0x01 #define EV_READ    0x02  #define EV_WRITE   0x04  #define EV_SIGNAL  0x08

有效性判断:

if (ev->ev_events & (EV_READ|EV_WRITE|EV_SIGNAL)){……}

根据事件类型进行事件处理:

if (ev->ev_events & EV_READ){……}

Miss Lin语:

Well,well,well.循规蹈矩先生的方法 is very sample,让人一看就明白,but it's not fashion!

假如一个事件既包含“读”,又包含“写”,是否还要添加一个EV_READ_WRITE宏?Think about that!

But 使用我的方法就不一样了,EV_READ|EV_WRITE 即可表示一个读写事件。该方法同样适用于其他事件组合,比如一个限时的读事件可以这样定义:EV_READ|EV_TIMEOUT,so easy!

另外,通过位运算,可以很方便地对事件类型进行操作:

//添加超时类型 ev_events |= EV_TIMEOUT; //删除超时类型 ev_events &= ~EV_TIMEOUT;

使用bit指示状态,通过位运算操作状态值——要知道,fashion也讲求节约!

问题二:定义链表数据结构并编写相关操作函数。

循规蹈矩先生

//结点结构定义 typedef struct _LIST_NODE{
     void* pdata;      struct _LIST_NODE* next; }LIST_NODE; //链表结构定义 typedef struct _LIST_HEAD{
     LIST_NODE* first; }LIST_HEAD; //头部插入结点函数 void list_insert_head(LIST_HEAD* head, LIST_NODE* node){
    node->next = head->first;     head->first = node; }

No! No! No! it's not fashion!

**Miss Lin**

//链表头定义宏 #define SLIST_HEAD(name, type)                      \ struct name {                               \ struct type *slh_first; /* first element */         \ } //链表元素定义宏 #define SLIST_ENTRY(type)                       \ struct {                                \     struct type *sle_next;  /* next element */          \ } //链表初始化 #define SLIST_INIT(head) do {                       \     (head)->slh_first = NULL;                   \ } while (/*CONSTCOND*/0) //头部插入结点宏 #define SLIST_INSERT_HEAD(head, elm, field) do {            \     (elm)->field.sle_next = (head)->slh_first;          \     (head)->slh_first = (elm);                  \ } while (/*CONSTCOND*/0)

Miss Lin语:

Fashion是什么?to be different! 提到宏的使用,很多程序员能列出一堆缺点,比如展开容易出错、不方便调试,但是恰当地使用宏可以带来很多好处,以上方法相比函数的实现,运行效率更高(哪怕只是一点点地提升)。最最关键的一点,it's cool!

以上关于链表的宏定义使用方法如下:

//定义链表结点 struct SLIST_ITEM{
int value; SLIST_ENTRY(SLIST_ITEM) entries; }; SLIST_HEAD(,SLIST_ITEM) slist_head;  //声明链表头结点 struct SLIST_ITEM* item; SLIST_INIT(&slist_head);  //初始化链表 item = malloc(sizeof(struct SLIST_ITEM)); item->value = 10; SLIST_INSERT_HEAD(&slist_head, item, entries);  //在头部插入元素

问题三:编写接口函数,分别实现动态数组和队列插入和删除。

循规蹈矩先生

//list.h struct _List; typedef struct _List List; //链表接口函数 void list_insert(void* thiz, size_t index, void* data); void list_delete(void* thiz, size_t index); //darray.h struct _DArray; typedef struct _DArray DArray; //动态数组接口函数 void darray_insert(void* thiz, size_t index, void* data); void darray_delete(void* thiz, size_t index);

No! No! No! it's not fashion!

**Miss Lin**

//container.h struct container{
  void (*insert) (void*, size_t index, void* data);   void (*delete) (void*, size_t index); }; //list.h static void list_insert(void* thiz, size_t index, void* data); static void list_delete(void* thiz, size_t index); struct container list_container = {list_insert, list_delete}; //darray.h static void darray_insert(void* thiz, size_t index, void* data); static void darray_delete(void* thiz, size_t index); struct container darray_container = {darray_insert, darray_delete};

Miss Lin语:

Fashion! Can you see that ?! 增加container结构、利用回调函数,实现了统一的接口,static关键字实现了隐藏,使用方法如下:

struct container* containerp = &list_container; containerp->insert(……); containerp->delete(……);

 

上文模仿Miss Lin的语气介绍了以下内容:

  1. 使用二进制和位运算定义类型;
  2. 使用宏定义结构和函数;
  3. 使用回调函数提供统一接口。

”循规蹈矩先生”们应向"Miss Lin"学习,学习她追求与众不同的精神。对于编程,除了常规的编码实现方法,我们还应多思考能同样达到目的的方法。通过不断思考与总结,逐渐提高编程技能。

 

转载地址:http://bxfoa.baihongyu.com/

你可能感兴趣的文章
HTML5之语义标签
查看>>
javascript下将字符类型转换成布尔值
查看>>
常用问题库(2)
查看>>
快速查询Python脚本语法
查看>>
POJ 1562:Oil Deposits
查看>>
JavaScript学习历程和心得
查看>>
FZU2177(dp)
查看>>
Castle ActiveRecord起步
查看>>
取消Windows server 2008关机提示备注的方法
查看>>
Linux+Apache+Mysql+PHP典型配置
查看>>
Ext框架基础
查看>>
逐行读取txt文件,使用Linq与StreamReader的Readline方法
查看>>
6.0字符串String
查看>>
【mysql学习笔记整理】
查看>>
11.30
查看>>
ExportGrid Aspose.Cells.dll
查看>>
Jmeter录制数据库脚本
查看>>
Python爬虫实例:糗百
查看>>
【转】iOS:堆(heap)和栈(stack)的理解--简介
查看>>
PDO的使用
查看>>