【问题标题】:C - Is there a more efficient way to "convert" items of an unsigned char array to an 32bit integer value? (Shared memory?)C - 有没有更有效的方法将 unsigned char 数组的项“转换”为 32 位整数值? (共享内存?)
【发布时间】:2017-04-21 22:32:51
【问题描述】:

最近我开始学习 C/C++,目前正在研究低级编程。我发现“联合”非常有趣,因为我以前从未见过这样的行为,可以直接用我学过的任何语言共享记忆。现在我想知道是否可以通过使用 Union 之类的东西或通过 以某种方式 将整数指向数组的特定索引以获得与以下相同的结果来提高这个简单例程的性能.

// An Union struct which holds a 32bit integer where every of the 4 bytes can be accessed.
typedef union
{
    struct
    {
        unsigned char BYTE1;
        unsigned char BYTE2;
        unsigned char BYTE3;
        unsigned char BYTE4;
    } BYTES;
    unsigned long VALUE;
} UnionDWORD;

// An array of unsigned chars - representing memory
unsigned char memory[1024]; // reserving 1024 bytes of memory

// Here is where I'm wondering if the "putting together" of the 4 bytes can be improved. (Maybe a pointer to the array?)
// Return 4bytes from memory at the position "pos"
unsigned long getDWordFromMemory(unsigned long pos)
{
    // Making use of the Union struct to put the 4 bytes together
    UnionDWORD result;
    result.BYTES.BYTE4 = memory[pos];
    result.BYTES.BYTE3 = memory[pos+1];
    result.BYTES.BYTE2 = memory[pos+2];
    result.BYTES.BYTE1 = memory[pos+3];

    return result.VALUE;
}

非常感谢,我真的很抱歉我的英语。不幸的是,这不是我的母语。

【问题讨论】:

  • 我不确定,但也许你可以用 *int 指向数组,然后编译器将读取 4 个字节作为数字而不是 1。因此,如果您执行newPtr[0],则它的前 4 个字节为整数。
  • 这已经非常高效了(假设是 C,而不是 C++,所以没有严格的别名问题)。我怀疑你能写出比这更好的东西;编译器应该能够识别正在发生的事情
  • C 或 C++,选择一个。它们不是同一种语言。
  • 顺便说一句:unsigned long 可能不是 4 unsigned char,即使这很常见。考虑uint32_t

标签: c arrays shared-memory unions


【解决方案1】:

当你有一把锤子时,一切看起来都像钉子。

假设 C++,这是一种更正确的做法,可能是个坏主意:

unsigned long getDWordFromMemory(size_t pos)
{
    unsigned char* mem = &memory[pos];
    return *reinterpret_cast<unsigned long*>(mem);
}

正如所指出的,上述内容存在对齐问题(您需要确保 pos 是 4 的倍数,因为 memory[0] 将正确对齐)。如果这是一个问题,那么你应该只使用这个方法:

unsigned long getDWordFromMemory(size_t pos)
{
    unsigned long value;
    memcpy(&value, &memory[pos], sizeof(value));
    return value;
}

联合可能很有用,但它通常只是用于将不相交的信息打包到更少量的内存中。

【讨论】:

  • unsigned long* 的饮食要求可能比unsigned char* 更严格。
  • 这是一个公平的观点。它通常可以在未对齐的现代处理器上正常工作,但它会(显着)慢。如果需要,可以很容易地检查和断言或返回哨兵。
  • 可能在一些现代处理器上工作,但今天的大多数处理器都是嵌入式小型处理器——每年数十亿——其中一大类会因未对齐而出现总线故障。
猜你喜欢
  • 2011-04-09
  • 2013-12-21
  • 2020-04-12
  • 2013-07-29
  • 1970-01-01
  • 1970-01-01
  • 2011-06-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多