bloggerads

2013年11月29日 星期五

C 巨集用法經驗談

1. 可用來設定Memory address的value。 巨集的參數記得括弧,整個巨集也要括弧以免別人引用時因為C priority問題產生bug

#include <stdio.h>

typedef unsigned int DWORD;

#define SET_MEM_32( addr, val) \
( *(DWORD* )(addr) = (val) )

#define GET_MEM_32( addr)    (*(DWORD* )(addr))

#define MODIFY_MEM_32( addr, mask, val) \
( *(DWORD* )(addr) = GET_MEM_32(addr) & ~(mask) | (val) & (mask) ) 

int 
main()
{
    unsigned char arr[10]={0,1,2,3,4,5,6,7,8,9};

    SET_MEM_32(arr, 0x22334455);
    printf("%x\n",GET_MEM_32(arr));

    MODIFY_MEM_32(arr, 0xff0000, 0x770000);
    printf("%x\n",GET_MEM_32(arr));
    
    return 0;
}

--------------執行結果--------------
22334455
22774455

Internet Overview (網路概論)


https://en.wikipedia.org/wiki/OSI_model
第4層 傳輸層(Transport Layer): Segments = Data +控制資料
  • 把傳輸表頭(TH)加至資料以形成資料報。傳輸表頭包含了所使用的協定等傳送資訊。例如:傳輸控制協定義(TCP) 等。 (TCP將資料封包化並組成區段)
第3層 網路層(Network Layer): Packet = Segments +控制資料
  • 決定資料的路徑選擇和轉寄,它網路表頭(NH)加至資料報,以形成封包。網路表頭包含了網路資料。例如:網際網路協定(IP) 等。(透過路由(router)找到主機位置(邏輯位址)並決定傳送的路徑), IP分享器也在這層
第2層 資料連結層(Data Link Layer): Frame =  Packet +控制資料
  • 負責網路尋址、錯誤偵測和改錯。(交換器(Switch)分析Frame,並讀取目的端和傳送端的Mac address然後傳送到所對應的連接port)
第1層 實體層(Physical Layer) 
  • 定義一些電器的規格,如電壓,Pin腳等等。 (集線器(Hub)就是一個中繼器(repeater), 忠實的把信號傳到每個port上)
----------------------------------------------------------------
NIC (Network Interface Card): 網路介面卡
MAC address: 實體位址,每張網卡都有獨一無二的Mac address,由6個Byte組成
IP address: 邏輯位址,軟體/伺服器assign的, 透過遮罩大概知道這台電腦是透過哪個主機連過來的
IP 位址: 電腦主機在 Internet 上的位址。
IP 位址=網路位址(Network ID)+主機位址(Host ID)
IP分成class A~E各種等級, A 類、B 類和 C 類是商業類使用之位址,可指定給主機

子網路遮罩: 用來判定來源IP和目的IP是否在同一網域的一個判斷位址。
預設閘道位址: 傳送到不同網域時用以決定封包的傳輸途徑。

DNS伺服器位址: DNS 伺服器的用途在於將主機名稱(Host Name)轉成IP 位址。 

TCP和UDP的差異: ﹐TCP 提供的是可靠傳輸﹐傳輸(送)層檢測手續﹐都會在 TCP 中實現而 UDP 不是可靠傳輸,因此相較於 TCP 來說,一大堆必需佔據封包表頭的都可省略來換取更大的 payload。UDP只是一個單方向的網路協定,如果要作可靠傳輸,那麼,其確認機制將從傳輸層退為應用層進行了 (也就是程式本身要提供可靠傳輸機制)。詳細請參考:TCP 與 UDP



(待續)

2013年11月26日 星期二

C# : Class inherits and virtual (override) example


    public class Father
    {
        public Father() { Console.WriteLine("Father Constructor!"); }
        public virtual void WifeAge() { Console.WriteLine("Age is 50, father's wife!"); }
        public void FamilyName() { Console.WriteLine("Family name: Lee"); }
        ~Father() { Console.WriteLine("Father De-Constructor!"); }
        
    }
    public class Son : Father
    {
        public Son() { Console.WriteLine("Son Constructor!"); }
        public virtual void WifeAge() { Console.WriteLine("Age is 30, son's wife!"); }
        ~Son() { Console.WriteLine("Son De-Constructor!"); }
        
    }
    public class Program
    {
        public static void Main(string[] args)
        {
            Father obj = new Father();
            obj.WifeAge();
            Son obj2 = new Son();
            obj2.WifeAge();
            obj.FamilyName();
            obj2.FamilyName();
        }
    }
_/_/_/_/_/_/ _/  OUTPUT  _/_/_/_/_/_/_/_/

Father Constructor!
Age is 50, father's wife!
Father Constructor!
Son Constructor!
Age is 30, son's wife!
Family name: Lee
Family name: Lee
Son De-Constructor!
Father De-Constructor!
Father De-Constructor!

2013年11月11日 星期一

C++的Container: stack使用範例

// stack.cpp
#include <iostream>
#include <stack>
#include <string>

int main()
{
    std::stack<int> ss;
    std::cout<<"size="<<ss.size()<<std::endl;
    for (int i=0; i<20; i++)
        ss.push(i);
    std::cout<<"size="<<ss.size()<<std::endl;
    while (!ss.empty()){
        std::cout << ' ' << ss.top();
        ss.pop(); //pop() has no return value, use top() to check value
    }
    std::cout<<std::endl;
    return 0;
}

輸出:


martin@martin-K42Jc:~/Code$ g++ -o stack stack.cpp

martin@martin-K42Jc:~/Code$ ./stack
size=0
size=20
 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

2013年11月2日 星期六

C++的Container: Map使用範例

C++提供map容器, [key]=value. 使用key來找尋找、插入、刪除.

map容器的排列會根據key來自動排列. (是一種平衡二元素的實現)


以下是範例:


#include <iostream>
#include <string>
#include <map>
using namespace std;
int find_and_erase(map<string, string> &mm, string ss)
{
    map<string, string>::iterator it;
    //find and erase the element
    if ( mm.end() != ( it = mm.find(ss)) ) {
        mm.erase(it); cout << ">Erase " << ss << endl;
    }else  cout << ">Cannot find " << ss << endl;
}
int show_all(string ss, map<string, string> mm)
{
    map<string, string>::iterator it;
    for(it = mm.begin(); it != mm.end(); it++)
                cout<<it->first<<" "<<it->second<<endl;
    cout << "****Finish job: "<< ss << endl;    
}

int main()
{  
    map<string, string> mm;
 
    mm["John"] = "John_data";
    mm["May"]  = "May_data";
    show_all("add John & May", mm);
    if ( false == mm.insert(pair<string, string>("Martin", "Martin_data")).second )
        cout << "(insert failed)" << endl;
    show_all("insert Martin", mm);
    // Insert same key twice, should get failed return
    if ( false == mm.insert(pair<string, string>("Martin", "Martin_data")).second )
        cout << "(insert failed)" << endl;
    show_all("insert Martin", mm);    
   
    cout << "total size: " << mm.size() << endl;
   
    find_and_erase(mm, "John");
    show_all("erase John", mm);
       
    // Reverse iterator
    for (map<string, string>::reverse_iterator itr = mm.rbegin(); itr != mm.rend(); itr++)
        cout<<itr->first<<" "<<itr->second<<endl;
    cout << "****Reverse Traversal" << endl;
    return 0;
}

Output:

John John_data
May May_data
****Finish job: add John & May
John John_data
Martin Martin_data
May May_data
****Finish job: insert Martin
(insert failed)
John John_data
Martin Martin_data
May May_data
****Finish job: insert Martin
total size: 3
>Erase John
Martin Martin_data
May May_data
****Finish job: erase John
May May_data
Martin Martin_data
****Reverse Traversal