程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 【編程好習慣】借助隱式初始化簡化程序邏輯

【編程好習慣】借助隱式初始化簡化程序邏輯

編輯:關於C語言

在圖1中示例了三個API的原型,分別是mprotector_init()、mprotector_fini()和mprotector_section_add()。假設mprotector_section_add()將會被多個任務調用以用於初始化各任務相關的一些數據,但是在mprotector_section_add()被調用之前,必需保證mprotector_init()已經被執行過了且只能執行一次。此外,圖中也示例了任務A和B分別在其入口函數中調用mprotector_section_add()以進行相應的操作。那現在的問題是,mprotector_init()應當放在什麼地方被調用呢?顯然,放到任務A和B的入口函數內不太好,這會造成一旦任務的初始化順序或是優先級變了以後,結果就截然不同。很容易想到的另一種方法是,在創建任務A和B之前,先調用mprotector_init(),如此一來問題也就解決了。還有更好的方法嗎?

example.c
int mprotector_init ();
int mprotector_fini ();
int mprotector_section_add (section_id_t _id, maddr_t _start, msize_t _size);

void task_entry_A (void *_p_arg)
{
   maddr_t start;
   msize_t size;
   ...
   mprotector_section_add (SECTION_1, start, size);
   ...
}

void task_entry_B (void *_p_arg)
{
   maddr_t start;
   msize_t size;
   ...
   mprotector_section_add (SECTION_2, start, size);
   ...
}

圖1

更好的方法是采用隱式初始化的方法,這需要對mprotector_init()和mprotector_section_add()兩個函數做一些更改,如圖2所示。mprotector_init()中的更改是允許它被多次調用,但在其中新增一個靜態的局部變量用於記錄是否已經被真正地初始化過了,當mprotector_init()發現這一變量變成了true以後,就直接返回0表示成功,否則需要進行後續的初始化操作。最後,在mprotector_section_add()中則需要增加對mprotector_init()的調用。

example.c
int mprotector_init ()
{
   static bool initialized = false;

if (initialized) {
       return 0;
   }
   ...
initialized = true;
   return 0;
}

int mprotector_section_add (section_id_t _id, maddr_t _start, msize_t _size)
{
   if (0 != mprotector_init ()) {
       return -1;
   }
   ...
}
圖2

有了這些更改以後,使用mprotector_section_add()函數的用戶就根本不需要考慮在什麼地方調用mprotector_init()函數,而這,也就簡化了程序邏輯。

本文出自 “至簡李雲” 博客,請務必保留此出處http://yunli.blog.51cto.com/831344/271278

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved