c - 如何在内存中顺序存储可变长度代码?

标签 c arrays embedded

假设我有一个二维数组,其中每个条目都包含一个长度和一个值:

int array[4][2] =  { /* {length, value}, */
                   {5, 3},
                   {6, 7},
                   {1, 0},
                   {8, 15},
                   };

我想将它们按顺序存储到内存中并带有前导零,以使每个字段具有适当的长度。上面的例子是:

    00011 000111 0 00001111

第一个 block 长 5 位,存储十进制 3。第二个 block 长 6 位,存储十进制 7。第三个 block 长 1 位,存储十进制 0,最后一个 block 长 8 位,存储十进制 15。

我可以通过一些按位操作来做到这一点,但我想我会问是否有更简单的方法。

我正在为 Tensilica 32 位 RISC 处理器使用 C 语言进行编码。

目的是编写一系列指数哥伦布码。

编辑:解决方案:

int main(int argc, char *argv[])
{
    unsigned int i = 0, j = 0;
    unsigned char bit = 0;
    unsigned int bit_num = 0;
    unsigned int field_length_bits = 0;
    unsigned int field_length_bytes = 0;
    unsigned int field_array_length = 0;
    unsigned int field_list[NUM_FIELDS][2] = {
                                            /*{Length, Value},*/ 
                                            {4,  3},
                                            {5,  5},
                                            {6,  9},
                                            {7,  11},
                                            {8,  13},
                                            {9, 15},
                                            {10, 17},
                                         };

    unsigned char *seq_array;

    // Find total length of field list in bits
    for (i = 0; i < NUM_FIELDS; i++) 
        field_length_bits += field_list[i][LENGTH];

    // Number of bytes needed to store FIELD parameters
    for (i = 0; i < (field_length_bits + i) % 8 != 0; i++) ;

    field_length_bytes = (field_length_bits + i) / 8;

    // Size of array we need to allocate (multiple of 4 bytes)
    for (i = 0; (field_length_bytes + i) % 4 != 0; i++) ;

    field_array_length = (field_length_bytes + i);

    // Allocate memory
    seq_array = (unsigned char *) calloc(field_array_length, sizeof(unsigned char));

    // Traverse source and set destination
    for(i = 0; i < NUM_FIELDS; i++)
    {
        for(j = 0; j < field_list[i][LENGTH]; j++)
        {
            bit = 0x01 & (field_list[i][VALUE] >> (field_list[i][LENGTH] - j - 1));
            if (bit)
                setBit(seq_array, field_array_length, bit_num, 1);
            else
                setBit(seq_array, field_array_length, bit_num, 0);
            bit_num++;

        }
    }

    return 0;
}



void setBit(unsigned char *array, unsigned int array_len, unsigned int bit_num, unsigned int bit_value)
{
    unsigned int byte_location = 0;
    unsigned int bit_location = 0;

    byte_location = bit_num / 8;
    if(byte_location > array_len - 1)
    {
        printf("setBit(): Unauthorized memory access");
        return;
    }
    bit_location = bit_num % 8;

    if(bit_value)
        array[byte_location] |= (1 << (7-bit_location));
    else
        array[byte_location] &= ~(1 << (7-bit_location)); 

    return;
}

最佳答案

您可以使用比特流库:

强烈推荐的比特流库:

http://cpansearch.perl.org/src/KURIHARA/Imager-QRCode-0.033/src/bitstream.c

http://cpansearch.perl.org/src/KURIHARA/Imager-QRCode-0.033/src/bitstream.h

因为这个比特流库似乎非常独立,并且似乎不需要外部包含。

<小时/>

http://www.codeproject.com/Articles/32783/CBitStream-A-simple-C-class-for-reading-and-writin - C 库,但使用 Windows WORD、DWORD 类型(您仍然可以使用 typedef 来使用此库)

http://code.google.com/p/youtube-mobile-ffmpeg/source/browse/trunk/libavcodec/bitstream.c?r=8 - 包括相当多的其他包含文件以使用比特流库

<小时/>

如果您只想要指数哥伦布代码,可以使用开源 C 实现:

http://www.koders.com/c/fid8A317DF502A7D61CC96EC4DA07021850B6AD97ED.aspx?s=gcd

<小时/>

或者您可以使用位操作技术。

例如:

unsigned int array[4][2] = ???
unsigned int mem[100] = {};
int index=0,bit=0;
for (int i=0;i<4;i++) {
  int shift = (32 - array[i][0] - bit);
  if (shift>0) mem[index] &= array[i][1] << shift;
  else {
    mem[index] &= array[i][1] >> -shift;
    mem[index+1] &= array[i][1] << (32+shift);
  }

  bit += array[i][1];

  if (bit>=32) {
    bit-=32;
    index++;
  }
}

免责声明:

仅当您的计算机字节顺序为小端序时,该代码才有效,并且结果实际上在每个 4 字节边界内为小端序,而在 4 字节边界内为大端序。如果将 mem 从 int 类型转换为 char,并将常量 32 替换为 8,您将获得位数组的大端表示。

它还假设长度小于 32。显然,您实际想要的代码将取决于有效输入的范围以及您想要的字节排序。

关于c - 如何在内存中顺序存储可变长度代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12014402/

相关文章:

c - ISR 无法更改 C 嵌入式中的外部结构字段

c - bss段结束地址小于起始地址

c - 销毁当前窗口并创建一个新窗口

c - Arduino 模式阵列崩溃

Java 性能 - ArrayLists 与 Arrays 相比,可实现大量快速读取

PHP - 通过调用返回键和值的方法插入数组

c - C中不同文件的 union 变量

c - Vim 关键字补全

c - 打印出指针指向的值(C编程)

c++ - 如何使用 new 在 C++ 中创建数组并初始化每个元素?