我只負責轉換![C/C++]

來源:互聯網
上載者:User

我只負責轉換![C/C++]

 

Written by Allen Lee

 

前不久,lsp在這裡留下這樣一個問題:

說明:

1.定義了一個枚舉如下:

enum _jb_prog_mode
{
    PROGRAM_ONE = 0,
    PROGRAM_TWO
};

enum _jb_prog_mode e_prog_index;

2.疑惑:

e_prog_index = (enum _jb_prog_mode)-1;

e_prog_index等於-1?為什嗎?

你的疑惑隱藏著這樣一個結論:e_prog_index的值不應該等於-1。我相信你得出這個結論的理由是_jb_prog_mode枚舉中沒有哪個成員的值為-1,於是類型為_jb_prog_mode的變數e_prog_index的值也不應該為-1。

現在,我們轉換一下情境,假定註冊表中有如下的資訊:

[HKEY_LOCAL_MACHINE\SOFTWARE\Allen]
"Name"="Allen Lee"
"ID"=dword:00000584

我們如何通過編程擷取這些資訊呢?我們可以使用Win32 API的RegQueryValueEx()函數來讀取這些資訊(代碼片斷):

LPBYTE lpData;
DWORD dataBufLen;

if (RegQueryValueEx(hKey,        // hKey為指向HKEY_LOCAL_MACHINE\SOFTWARE\Allen的控制代碼
                    "Name",
                    NULL,
                    NULL,
                    lpData,
                    &dataBufLen) == ERROR_SUCCESS)
{
    // Convert_01:
    char* data = new char[dataBufLen];
    data = (char*)lpData;
    std::cout  "User name: "  data  std::endl;


    // Convert_02:
    // DWORD* data = (DWORD*)lpData;
    // std::cout 
}

if (RegQueryValueEx(hKey,
                    "ID",
                    NULL,
                    NULL,
                    lpData,
                    &dataBufLen) == ERROR_SUCCESS)
{
    // Convert_03:
    DWORD* data = (DWORD*)lpData;
    std::cout  "User ID: "  *data  std::endl;

    // Convert_04:
    // char* data = new char[dataBufLen];
    // char* data = (char*)lpData;
    // std::cout 
}

留意這段代碼有兩次轉換,如果我們分別把Convert_01和Convert_03替換為Convert_02和Convert_04的話會怎麼樣呢?編譯器不會為難你的,但運行效果可想而知。

回顧這兩個例子,我們可以得到什麼結論呢?正如本文的題目——

我只負責轉換!

當你強制把-1轉換為_jb_prog_mode類型並賦值予e_prog_index變數時,你只能說e_prog_index變數不包含_jb_prog_mode枚舉預定義的值,並不能說e_prog_index變數的值非法(其實枚舉類型和整數類型之間有著很深的淵源)。編譯器是不會妨礙你的這種轉換,而這種轉換是否有意義就是另外一回事了。當然,你應該採取某些措施來檢測枚舉變數是否包含預定義的值,否則你將可能不時收到意外驚喜。

在C/C++中,枚舉其實是整數常量的一種表現形式,它實質上只是協助程式員標識一組相關的整數常量。語義上,

enum _jb_prog_mode
{
    PROGRAM_ONE = 0,
    PROGRAM_TWO
};

等效於

static const int PROGRAM_ONE = 0;
static const int PROGRAM_TWO = 1;

C/C++給予程式員最大的自由來進行選擇,這也體現出C/C++對程式員的信任。然而,這種信任究竟是協助我們還是傷害我們,就要看程式員本身的做法了。

最後,我引用Robert B. Murray的一段話[1]結束本文:

寫出依賴於語言中定義含糊、意義微妙的規則的程式是不好的,即便作者本人清楚它的意義並保證它可以正確運行,下一個來維護這段代碼的人也可能未必能夠做到這點。比較好的做法是:堅持使用語言中那些被廣泛使用及理解的部分來寫程式。

 

See also:

  • Allen Lee;《關於枚舉的種種 (Enumeration FAQ) [C#, IL, BCL]》
  • Allen Lee;《我並不是不聞不問![C#]》

  • [1] [美]Robert B. Murray 著;王昕 譯;《C++ 編程慣用法——進階程式員常用方法和技巧》;中國電力出版社,2004

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.