雜記,隨時更新

不管是顯示的類型轉換還是隱式的類型轉換,都有一個到轉換結果類型的臨時變量的產生
譬如:
       int i = 1.2;    //實際的賦值過程可能是 int temp = 1.2; int i = temp;

無符號變量和有符號變量之間的轉換是其對應的內存地址二進制表示不變

 

hook機制發送消息

 

如果你設置的超時時間大於75秒就沒有必要這樣做了,因爲內核中對connect有超時限制就是75秒
發送超時,接收超時,以及select超時(注: select函數並不是只用於套接口的,但是套接口編程中用的比較多)

40.int id[sizeof(unsigned long)];
    這個對嗎?爲什麼??

這個 sizeof是編譯時運算符,編譯時就確定了
可以看成和機器有關的常量。

 

--------------------------------------數據結構------------------------

 

算法的特點: 有窮性,確定性,可行性,輸入,輸出

算法設計要求:正確性,可讀性,健壯性,效率與低存儲量需求

算法的目的:時間和空間效率 (空間沒問題時,追求時間效率)

 

靜態存儲:

#define  LISTSIZE    100  //存儲空間最大容量,依需要而定

       typedef  struct {

              ElemType    elem[LISTSIZE] ; //用於存儲各個表元素

              int                length;   //當前長度

         }SqList

 

 動態分配:

#define  LIST_INIT_SIZE    100  //線性表存儲空間的初始分配量

        #define  LISTINCREMENT    10  //線性表存儲空間的分配增量

        typedef  struct {

              ElemType   * elem ; //存儲空間基址

              int  length;   //當前長度

              int  listsize; //當前分配的存儲容量(sizeof(ElemType)爲單位)

         }SqList

 

線性表順序存儲結構的優缺點

    

     1、優點

          1)結構簡單

          2)可直接定位到表中任意元素,並可隨機存取元素,連續存取速度快。

    

     2、缺點

          1)存儲空間難於準確靜態分配,分配大了浪費空間,分配小了又可能不夠用。

          2)插入、刪除操作不大方便,需要移動大量數據元素,效率較低。

 

 

線性表的鏈式存儲結構的優缺點

    1、優點

     1)存儲空間動態分配,可以按需要使用。

     2)插入、刪除結點操作通常只需要修改指針,不必移動數據元素。

    2、缺點

      1)每一個結點附加指針域(存儲密度小於1),空間利用率低。

      2)非隨機存儲結構,查找定位操作需從頭指針處順着鏈表掃描。

 

 

(Stack)  是限定僅在表尾進行插入或刪除操作的線性表。因此,對棧來說,表尾端有其特殊含義,稱爲棧頂(top),相應地,表頭端稱爲棧底(bottom)。不含元素的空表稱爲空棧

 

//棧的順序存儲表示

#define  STACK_INIT_SIZE  100

#define  STACKINCREMENT    10

typedef struct {

     SElemType  * base

     SElemType  * top

     int  stacksize

}SqStack

Status GetTop (SqStack SSElemType &e){ 

     //若棧不空,則用e返回s的棧頂元素,並返回OK

     //否則返回ERROR    

    if(S.top  = =  S.base)

        return ERROR    

    e=*(S.top-1)

    return OK   

} //GetTop

Status Push (SqStack &SSElemType e){ 

     //插入元素e爲新的棧頂元素 

     if(S.top S.base>=S.stacksize){

           //---棧滿,追加存儲空間--- 

          S.base  =  (SElemType  *)realloc(S.base(S.stacksize+STACKINCREMENT) *sizeof(SElemType))

         if(!S.base)exit(0VERFLOW)//存儲分配失敗

              S.top=S.base+S.stacksize

          S.stacksize+ =  STACKINCREMENT

      }    

     *S.top++ = e

     return OK

}//Push

Status  Pop( Sqstack &S , SElemType &e)

       //若棧不空,則刪除s的棧頂元素,

       //e返回其值,並返回OK      

      //否則返回ERROR      

      if(S.top == S.base) return ERROR

        e = * - - S.top

        return OK

} // Pop

//鏈棧的類型定義如下:

Typedef struct node

{   Elemtype   data;          //數據域;

     struct node  * next;     //指針域;

}ListNode;

Typedef  ListNode * LinkStack;

LinkStack  top;  //定義一個棧的棧頂指針變量

 

隊列(Queue)是一種先進先出(First in First Out,縮寫爲FIFO)的線性表。它只允許在表的一端進行插入,而在另一端刪除元素。這和我們日常生活中的排隊是一致的,最早進入隊列的元素最早離開。在隊列中,允許插入的一端叫做隊尾(rear),允許刪除的一端則稱爲隊頭(front) 

  

// 單鏈隊列——隊列的鏈式存儲結構 

typedef struct QNode{

      QElemType    data

      struct QNode  *next   

}QNode*QueuePtr 

typedef struct {

     QueuePtr      front  //隊頭指針

     QueuePtr      rear//隊尾指針

} LinkQueue

// 循環隊列——隊列的順序存儲結構  

#define MAXQSIZE  100    //最大隊列長度

typedef struct {

     QElemType  *base       //初始化的動態分配存儲空間

     int  front         //頭指針,若隊列不空,指向隊列頭元素

     int  rear    //尾指針,若隊列不空,指向隊列尾元素的下一個位置 

 }SqQueue   

   

隊空條件Q.front==Q.rear;

隊滿條件:爲避免在隊滿是隊頭指針和隊尾指針也是重合的情況,規定隊列中還有一個空的存儲單元時爲隊滿,即爲Q.front==(Q.rear+1)MOD maxsize(MOD爲取餘運算符)。因而,這種循環隊列不適合用動態數組作爲存儲結構。

 

理想的情況是希望不經過任何比較,一次存取便能得到所查記錄,那就必須在記錄的存儲位置和它的關鍵字之間建立一個確定的對應關係f,在查找時,只要根據這個對應關係f找到給定值K的像f(K)。若結構中存在關鍵字和K相等的記錄,則必定在f(K)的存儲位置上,可直接取得所查記錄。在此,我們稱這個對應關係f哈希(Hash)函數,按這個思想建立的表爲哈希表

 

哈希表的設計過程

1)明確哈希表的地址空間範圍,即確定哈希函數的值域。

2)選擇合理的哈希函數。該函數要保證所有可能的數據記錄的哈希地址均在制定的值域內,並使衝突可能性儘量少。

3)設定處理衝突的辦法。

哈希函數的基本構造方法

  1、直接定址法   2、數學分析法   3、平方取中法

  4、摺疊法       5、除留餘數法

 

哈希表中處理衝突的常用方法

            1、開放地址法

            2、再哈希法

            3、鏈地址法

            4、建立一個公共溢出區

 

一、順序存儲結構  

//———二叉樹的順序存儲表示————  

#define  MAX_TREE_SIZE  100         //二叉樹的最大結點數  

typedef  TElemType  SqBiTree[MAX_TREE_SIZE]; 

 //0號單元存儲根結點   SqBiTree  bt

 

最優二叉樹(赫夫曼樹)

有序表的查找

折半查找(Binary Search)的查找過程是:先確定待查記錄所在的範圍(區間),然後逐步縮小範圍直到找到或找不到該記錄爲止。

折半插入排序 時間複雜度仍爲O(n2)

void BInsertSort (SqList &L){     //對順序表L作折半插入排序。

     for(i=2i<L.length++i){

           L.r[0]=L.r[i]               //L.r[i]暫存到L.r[0]

           low=1; high=i-1; //r[low..high]中折半查找有序插入的位置 

         while(low<=high ){

                m=(low+high)/2     //折半

                if LT(L.r[0].key , L.r[m].key) high=m-1     //插入點在低半區 

                     else low=m+1;     //插入點在高半區  

          }//while

          for (j=i-1;  j>=high+1; --j) L.r[j+1]=L.r[j];  //記錄後移

          L.r[high+1]=L.r[0];        //插入

       }//for

}//BInsertSort    

快速排序,選擇排序。。。

 

-----------------------------------------

 

所以我們還需要可靠的信號處理方式,也就是說當執行某些不可被中斷的操作的時候屏蔽掉信號處理。直到這些關鍵操作完成,再對信號進行處理。以後我會給大家詳細的解釋可靠信號的操作。
signal的保留是因爲還要兼容以前,否則這個函數沒用了,新寫的代碼中不要再繼續使用此函數。

 

Linux在支持新版本的信號安裝函數sigation ()以及信號發送函數sigqueue()的同時,仍然支持早期的signal()信號安裝函數,支持信號發送函數kill()。 注:不要有這樣的誤解:由sigqueue()發送、sigaction安裝的信號就是可靠的。事實上,可靠信號是指後來添加的新信號(信號值位於 SIGRTMIN及SIGRTMAX之間);不可靠信號是信號值小於SIGRTMIN的信號。信號的可靠與不可靠只與信號值有關,與信號的發送及安裝函數無關。目前linux中的signal()是通過sigation()函數實現的,因此,即使通過signal()安裝的信號,在信號處理函數的結尾也不必再調用一次信號安裝函數。同時,由signal()安裝的實時信號支持排隊,同樣不會丟失。 對於目前linux的兩個信號安裝函數: signal()及sigaction()來說,它們都不能把SIGRTMIN以前的信號變成可靠信號(都不支持排隊,仍有可能丟失,仍然是不可靠信號),而且對SIGRTMIN以後的信號都支持排隊。這兩個函數的最大區別在於,經過sigaction安裝的信號都能傳遞信息給信號處理函數(對所有信號這一點都成立),而經過signal安裝的信號卻不能向信號處理函數傳遞信息。對於信號發送函數來說也是一樣的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章