【问题标题】:How to store byte arrays in C?如何在C中存储字节数组?
【发布时间】:2014-03-07 02:26:43
【问题描述】:

这似乎是一个基本的问题,但我在 SO 上的任何地方都找不到答案。

我知道 C/C++ 没有 byte 数据类型。 我知道sizeof(char) == 1

我正在尝试在 Pebble 上存储 12 次传输,每个 96 字节,就像从我的 Android 应用程序传输的一样。

由于传输大小的限制,我一次发送一个。每个都应该“附加”到最后一个,因为它们最终应该在内存中形成顺序空间,以作为图像读取(每个像素一位)。

我正在尝试做这样的事情:

int transNum = 0;
uint8_t image[][] = new uint8t[12][12] //not sure about uint8_t, and I've forgotten how to do 'new' in C, I have to create just a pointer, and then malloc?

receivedHandler(DictionaryIterator *iter, void *context){
    Tuple *receivedImage = dict_find(iter, KEY_IMG);
    for (int i = 0; i < 12; i++) {
        image[transNum][i] =  receivedImage->value[i]->uint8_t;
    }
    transNum += 1; //this is in an implicit loop, since once done Pebble ACKs the transmission, and receivedHandler is called again by the next transmission
}

我是不是离得很近?

【问题讨论】:

    标签: c pebble-watch pebble-sdk


    【解决方案1】:

    您可以分配具有 12 行和 96 列的 12*96 字节的连续内存

    char*   image = (char*)malloc(sizeof(char)*12*96);
    

    另外,全局数组也可以

    char image[12][96];
    

    据我了解,您是按行接收数据,即一次 96 个字节:

    char rcvd_data[96]={0};
    

    并像这样访问/设置::

    for(row=0;row<12;row++) //to point to the row (0-11 rows)
    {
       rcvd_data= recv_function(); //whatever your recv function is
       for(col=0;col<96;col++) //to point to the col in that row (0-95 col)
       {
          *(image + row*96 + col)= rcvd_data[col]//whatever value you want to assign 
        }
    }
    

    一次性传输所有 96 个字节:

    for(row=0;row<12;row++) //to point to the row (0-11 rows)
    {
       rcvd_data= recv_function(); //whatever your recv function is
       memcopy((image + row*96), rcvd_data, 96);
    }
    

    【讨论】:

    • 当你说行/列时,内存是一维的。那么我认为这看起来像{r0c0, r0c1, ... , r0c95, r1c0, ... , r11c95} 是否正确?我假设i == col_no在那里?
    • 是的,没错。是的,上面代码中的i=col
    • 这两个声明之间有什么真正的区别吗?我假设如果我使用char image[12][96];,那么我在访问元素时不会取消引用。偏好的其他区别/原因?
    • 对于这两个声明,您引用元素的方式相同。基本上无论哪种方式,您都会得到一个 char* image,它指向一个 12*96 字节长的连续内存。
    • 并且您可以安全地不强制转换 malloc() stackoverflow.com/questions/605845/…的输出
    【解决方案2】:

    我要补充一点的是,只使用char 时要小心。在处理纯字节数据时,请使用 unsigned charsigned charuint8_t 之类的东西。虽然 char 是一个字节,但我已经看到由于它的使用而丢失了数据。

    【讨论】:

      【解决方案3】:

      分配您描述的数组的最简单解决方案是:

      uint8_t image[12][96];
      

      但是,根据您的描述“每个都应该'附加'到最后一个,因为它们最终应该在内存中形成顺序空间”,这表明您实际上想要:

      uint8_t image[12 * 96];
      

      然后您只需将 12 传输顺序写入该数组。

      你写的这段代码:

      for (int i = 0; i < 12; i++) {
          image[byteNum][i] =  receivedImage->value[i]->uint8_t;
      }
      

      不对,uint8_t 是数据类型,不是字段名。

      另外,您可能想用image[i] 做某事,而不是image[byteNum][i],尽管我无法更具体地知道TupleType 是什么以及您希望在每个@987654328 中找到多少@。

      【讨论】:

      • image[12][96];image[12 * 96]; 有什么区别?他们不是都分配连续的内存吗?
      • 它们都分配连续的内存,尽管如果您尝试将第一个视为一长串字节,则它是未定义的。 (根据 C 标准,即使您确切知道下一个内存位置中的内容,也不允许读取超出数组的边界)。
      • 来自 Python,我更喜欢 two_d[i][j]。我只是发现我在哪里更透明。它也使循环更容易 IMO。
      • @MattMcNabb - 你熟悉 Pebble SDK 吗?或许会在聊天中得到一些帮助。
      • 我不是很遗憾,我只是在阅读在线文档。使用一维数组非常简单,只需通过96 * i 对其进行索引。
      【解决方案4】:

      我认为你需要 malloc 两次。

      char** image = (char**)malloc(sizeof(char*)*12);
      int i = 0;
      for(; i < 12; ++i){
         image[i] = (char*)malloc(sizeof(char)*12);
      }
      

      然后您可以将图像视为二维数组。

      【讨论】:

      • 那不是连续记忆。
      • 是的,但这不影响它对问题的使用。
      • OP 已经明确提到`每个都应该'附加'到最后,因为它们最终应该在内存中形成顺序空间,以作为图像读取`。所以,这确实会影响问题。
      • 好的。我的错。那么我认为直接定义一个 image[][] 是最好的方法。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-04-03
      • 1970-01-01
      • 2020-07-16
      • 1970-01-01
      • 1970-01-01
      • 2023-01-31
      相关资源
      最近更新 更多