zoukankan      html  css  js  c++  java
  • 我只负责转换![C/C++]

    我只负责转换![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 << "User name: " << *data << std::endl;
    }


    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 << "User ID: " << data << std::endl;
    }

    留意这段代码有两次转换,如果我们分别把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:


  • 相关阅读:
    leetcode231 2的幂 leetcode342 4的幂 leetcode326 3的幂
    leetcode300. Longest Increasing Subsequence 最长递增子序列 、674. Longest Continuous Increasing Subsequence
    leetcode64. Minimum Path Sum
    leetcode 20 括号匹配
    算法题待做
    leetcode 121. Best Time to Buy and Sell Stock 、122.Best Time to Buy and Sell Stock II 、309. Best Time to Buy and Sell Stock with Cooldown 、714. Best Time to Buy and Sell Stock with Transaction Fee
    rand7生成rand10,rand1生成rand6,rand2生成rand5(包含了rand2生成rand3)
    依图
    leetcode 1.Two Sum 、167. Two Sum II
    从分类,排序,top-k多个方面对推荐算法稳定性的评价
  • 原文地址:https://www.cnblogs.com/allenlooplee/p/113801.html
Copyright © 2011-2022 走看看