代码之家  ›  专栏  ›  技术社区  ›  toto

哪个更可读(C++=)

c c++
  •  1
  • toto  · 技术社区  · 17 年前
    int valueToWrite = 0xFFFFFFFF;
    static char buffer2[256];
    int* writePosition = (int* ) &buffer2[5];
    *writePosition = valueToWrite;
    
    //OR
    * ((int*) &buffer2[10] ) = valueToWrite;
    

    不要担心优化,它们都优化到相同的东西,正如您在这里看到的。 告诉我哪一个更适合你。

    or  DWORD PTR ?buffer2@?1??main@@9@4PADA+5, -1
    or  DWORD PTR ?buffer2@?1??main@@9@4PADA+10, -1
    
    10 回复  |  直到 17 年前
        1
  •  19
  •   Constantin    17 年前
    int* writePosition = (int* ) &buffer2[5]
    

    *((int*) &buffer2[10] ) = valueToWrite;
    

    两者都是不正确的,因为在某些平台上访问未对齐的值(+5+10)可能需要数百个CPU周期,而在某些平台上(如较旧的ARM),这将导致非法操作。

    正确的方法是:

    memcpy( buffer+5, &valueToWrite, sizeof(valueToWrite));
    

    而且它更具可读性。

        2
  •  8
  •   Itay Maman    17 年前

    一旦将其封装到类中,使用哪种技术就无关紧要了。方法名称将提供代码正在执行的操作的描述。因此,在大多数情况下,您不必深入研究实际的impl。看看发生了什么。

    class Buffer
    {
        char buffer2[256];
    public:
        void write(int pos, int value) { 
           int* writePosition = (int*) &buffer2[pos];
           *writePosition = value;
        }
    }
    
        3
  •  4
  •   Todd Gardner    17 年前

    如果我被迫选择,我会说1。然而,我要指出的是,无论哪种方式,所呈现的代码都非常类似于C;我会避开其中一个,重新审视这个问题。这里有一个更简单的C++-y

    const char * begin = static_cast<char*>(static_cast<void*>(&valueToWrite));
    std::copy(begin, begin+sizeof(int), &buffer2[5]);
    
        4
  •  2
  •   Brian Gianforcaro    17 年前

    第一个例子更具可读性,完全是因为你的大脑不必破译全局指针操作。

        5
  •  1
  •   thomasrutter    17 年前

    我发现第二个较短的更容易阅读。

    然而,我怀疑,这取决于你是否是那种能轻易“得到”指针的人。

        6
  •  1
  •   rlbond    17 年前

    注意--由于对齐问题,此代码可能无法工作!为什么不直接使用 memset ?

    #include <string.h>
    memset(buffer2+10, 0xFF, 4);
    
        7
  •  1
  •   bdonlan    17 年前

    如果您可以将自己绑定到一个编译器(或者针对兼容性问题进行预处理器破解),那么可以使用压缩结构选项为您正在编写的值获取符号名。例如,关于GCC:

    struct __attribute__ ((__packed__)) packed_struct
    {
      char stuff_before[5]
      int some_value;
    }
    
    /* .... */
    
    static char buffer2[256];
    struct packed_struct *ps = buffer2;
    ps->some_value = valueToWrite;
    

    • 如果你能很好地命名你的字段,你的代码就能更清楚地反映你在做什么。
    • 由于编译器知道您所在的平台是否支持有效的未对齐访问,因此它可以自动在本机未对齐访问和不支持未对齐访问的平台上的适当解决方案之间进行选择。

    但是,它的主要缺点是没有任何标准化的语法。

        8
  •  0
  •   DevSolar    17 年前

    最具可读性的是任何一种变体,其中添加了对您在那里所做操作的注释。

        9
  •  0
  •   anon anon    17 年前

    一定地:

    * ((int*) &buffer2[10] ) = valueToWrite;
    

        10
  •  0
  •   autistic    7 年前

    非便携式 .

    除了对齐问题外,还有整数表示法(大小因系统而异,符号表示法、endianness和填充法也是如此)。因此,代码在系统之间的行为是 不规则的

    如果你想成为 清楚的 关于你的算法应该做什么,你应该 显式地将每个字节放入正确的位置

    void serialise_uint_lsb(unsigned char *destination, unsigned source) {
        destination[0] = source & 0xff; source >>= 8;
        destination[1] = source & 0xff; source >>= 8;
        assert(source == 0);
    }
    
    void deserialise_uint_lsb(unsigned *destination, unsigned char *source) {
        *destination = 0;
        *destination <<= 8; *destination += source[1];
        *destination <<= 8; *destination += source[0];
    }
    

    序列化和反序列化是程序员惯用的概念。。。 *printf *scanf 例如,是序列化/反序列化的形式,除非习惯性地灌输给你

    使用序列化/反序列化功能。程序员最能理解这一点。