【问题标题】:Method that returns uint16_t array properly in C++ [duplicate]在 C++ 中正确返回 uint16_t 数组的方法 [重复]
【发布时间】:2019-08-22 10:53:38
【问题描述】:

我的 C# 代码返回 uint 数组,但我想在 C++ 中执行。我看了其他帖子;他们使用 uint 指针数组,而我的数组不是。有谁知道如何正确返回 uint16_t 数组?

这是 C# 代码工作正常

  public static UInt16[] GetIntArrayFromByteArray(byte[] byteArray)
        {
            if ((byteArray.Length % 2) == 1)
                Array.Resize(ref byteArray, byteArray.Length + 1);


            UInt16[] intArray = new UInt16[byteArray.Length / 2];


            for (int i = 0; i < byteArray.Length; i += 2)
                intArray[i / 2] = (UInt16)((byteArray[i] << 8) | byteArray[i + 1]);


            return intArray;
        }

这是产生语法错误的 C++ 代码

uint16_t[] GetIntArrayFromByteArray(byte[] byteArray)
{
    //if ((byteArray.Length % 2) == 1)
        //Array.Resize(ref byteArray, byteArray.Length + 1);


    uint16_t[] intArray = new uint16_t[10];


    for (int i = 0; i < 10; i += 2)
        intArray[i / 2] = (uint16_t)((byteArray[i] << 8) | byteArray[i + 1]);


    return intArray;
}

【问题讨论】:

  • 什么是语法错误?
  • @πάνταῥεῖ 说;由于返回语法而需要
  • std::arraystd::vector怎么样
  • need to get a good C++ book。如图所示,从逻辑上讲,您不可能知道byteArray 有多大。数组在 C++ 中没有任何称为“长度”的东西。如果您不知道如何“集成”,那么这正是一本好的 C++ 书籍将教给您的内容。这就是它的用途。不幸的是,stackoverflow.com 并不是一个教你 C++ 的交互式网站。只有一本好书才能做到这一点。
  • 好吧,碰巧同一本 C++ 书也会回答您的主要问题。它会准确地告诉你 C++ 中的数组是什么(提示:C++ 中并没有真正意义上的数组,这是海市蜃楼,编译器看到你声明“uint16_t []”的请求,微笑,然后完全做其他事情),以及数组和指针之间的关系。如果不了解 C++ 的基本工作原理,这里的简单答案(返回指向 uint16_t 的指针)不会对您有太大帮助。

标签: c# c++ unsigned-integer


【解决方案1】:

永远不要使用Type[]。使用std::vector

std::vector<uint16_t> GetIntArrayFromByteArray(std::vector<byte> byteArray)
{
    // If the number of bytes is not even, put a zero at the end
    if ((byteArray.size() % 2) == 1)
        byteArray.push_back(0);


    std::vector<uint16_t> intArray;

    for (int i = 0; i < byteArray.size(); i += 2)
        intArray.push_back((uint16_t)((byteArray[i] << 8) | byteArray[i + 1]));

    return intArray;
}

如果数组是固定大小的,您也可以使用std::array&lt;Type, Size&gt;

更优化的版本(感谢@Aconcagua)(demo)

这是一个完整的代码,它具有更优化的版本,不会复制或更改输入。如果您有长输入数组,这会更好。可以写得更短,但我想让它保持冗长且对初学者友好。

#include <iostream>
#include <vector>

using byte = unsigned char;

std::vector<uint16_t> GetIntArrayFromByteArray(const std::vector<byte>& byteArray)
{
    const int inputSize = byteArray.size();
    const bool inputIsOddCount = inputSize % 2 != 0;
    const int finalSize = (int)(inputSize/2.0 + 0.5);
    // Ignore the last odd item in loop and handle it later
    const int loopLength = inputIsOddCount ? inputSize - 1 : inputSize;

    std::vector<uint16_t> intArray;
    // Reserve space for all items
    intArray.reserve(finalSize);
    for (int i = 0; i < loopLength; i += 2) 
    {
      intArray.push_back((uint16_t)((byteArray[i] << 8) | byteArray[i + 1]));
    }

    // If the input was odd-count, we still have one byte to add, along with a zero
    if(inputIsOddCount) 
    {
      // The zero in this expression is redundant but illustrative
      intArray.push_back((uint16_t)((byteArray[inputSize-1] << 8) | 0));
    }
    return intArray;
}

int main() {
    const std::vector<byte> numbers{2,0,0,0,1,0,0,1};
    const std::vector<uint16_t> result(GetIntArrayFromByteArray(numbers));

    for(uint16_t num: result) {
        std::cout << num << "\n";
    }

    return 0;
}

【讨论】:

  • byteArray.pushBack(0) 不正确,为什么不像 C# 代码那样使用 byteArray.size() 进行 for 循环
  • 为什么要按值接受?通过 const 引用也很好 - 只是你必须将最后一个零附加到新向量 after 循环......并且你应该reserve 有足够的容量来防止重新分配.
  • @Selen 我在 Aconcagua 上面提出的优点之后创建了一个更优化的版本。您可能应该将它用于更大的输入大小。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-03
  • 2021-04-12
  • 2013-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多