【问题标题】:C++ unsigned char array lengthC++ 无符号字符数组长度
【发布时间】:2016-12-29 09:04:07
【问题描述】:

我的 C++ 程序中有十六进制值的 unsigned char 数组:

unsigned char buff[] = {0x03, 0x35, 0x6B};

我想计算这个数组的大小,以便我可以使用这个函数在 UART 端口 linux 上发送它:

if ((count = write(file,buff,length))<0)
{
    perror("FAIL to write on exit\n"); 
}

我可以看到长度是 int 数,而 buff 是一个可以在程序执行期间改变大小的数组。 谁能帮我写一下。谢谢

【问题讨论】:

  • buff 在程序执行期间不能改变它的大小。它用文字初始化,长度始终为 3
  • 不是十六进制的,您只用十六进制表示法编写了它们。 {3, 53, 107} 完全等价,{03, 065, 0153} 也是如此。
  • @Story Teller 这只是一个例子,buff可以有不同数量的值存储在他里面。
  • 所以它是一个裸指针? unsigned char *buff?
  • 不,是数组。感谢您的帮助。

标签: c++ linux uart


【解决方案1】:

作为获取元素数量的选项之一,您可以使用这样的模板:

template<typename T, size_t s>
size_t arrSize(T(&)[s])
{
    return s;
}

然后调用:

auto length = arrSize(buff);

这可以用于各种数组类型的代码。

如果数组大小是指它的总字节大小,则可以使用sizeof(buff)。或者正如其他人建议的那样,您可以使用std::arraystd::vector 或任何其他容器代替,并编写这样的帮助程序:

template<typename T>
size_t byteSize(const T& data)
{
    typename T::value_type type;
    return data.size() * sizeof(type);
}

然后要获取数据的实际字节大小,您可以简单地调用:

std::vector<unsigned char> buff{0x03, 0x35, 0x6B};
auto bSize = byteSize(buff);

【讨论】:

  • 感谢您的帮助。
  • 注意:这比sizeof array / sizeof *array 方法要好,因为如果您使用具有运算符* 但不是数组的东西调用它,它将始终无法编译。另一种方法将编译并默默地给出错误的结果。
  • @Stargateur 感谢您的注意,已修复
【解决方案2】:

你可以用数组来做到这一点:

size_t size = sizeof array;

用你的例子给出:

ssize_t count = write(file, buff, sizeof buff);
if (count < 0 || (size_t)count != sizeof buff) {
  perror("FAIL to write on exit\n");
}

注意:我使用 C 语义,因为 write 来自 lib C。


在 C++ 中,您可以使用模板来确保将 sizeof 与数组一起使用。

template<typename T, size_t s>
size_t array_sizeof(T (&array)[s]) {
    return sizeof array;
}

用你的例子给出:

ssize_t count = write(file, buff, array_sizeof(buff));
if (count < 0 || static_cast<size_t>(count) != array_sizeof(buff)) {
  perror("FAIL to write on exit\n");
}

【讨论】:

  • @jww 我清楚地说“使用数组”。当然,使用指针没有必要这样做!不,指针不会“失败”。这导致了不同的结果。目的不同。我只是回答问题的上下文
【解决方案3】:

如果您使用的是 C++11,您可能会考虑切换到

#include <array>
std::array<char, 3> buff{ {0x03, 0x35, 0x6B} }; 

这为固定数组提供了类似std::vector(包括sizedata)的接口。 使用array 可以防止一些常见错误并提供&lt;algorithm&gt; 涵盖的一些功能。

write 的调用将是:

write(file,buff.data(),buf.size())

【讨论】:

  • 很好的建议,但请注意&lt;algorithm&gt; 也适用于 C 样式数组。
  • 不回答 OP,这给出了 op 想要的元素的数量,以字节为单位。
  • 字节大小和字符大小相等。使用其他类型,您可以使用 size_type 的乘法
【解决方案4】:

我想计算这个数组的大小,以便我可以使用这个函数在 UART 端口 linux 上发送它......

您需要一个COUNTOF 宏或函数。在所有情况下,它们都很难正确处理。例如,下面显示的接受答案在使用指针时会静默失败:

size_t size = sizeof array;
size_t number_element = sizeof array / sizeof *array;

Microsoft Visual Studio 2005 有一个名为_countof 的内置宏或模板类。它正确处理所有情况。另请参阅 MSDN 上的 _countof Macro 文档。

在非 Microsoft 系统上,我相信您可以使用以下内容。它将正确处理指针(来自making COUNTOF suck less):

template <typename T, size_t N>
char (&ArraySizeHelper( T (&arr)[N] ))[N];
#define COUNTOF(arr) ( sizeof(ArraySizeHelper(arr)) )

void foo(int primes[]) {
   // compiler error: primes is not an array
   std::cout << COUNTOF(primes) << std::endl;
}

另一个很好的参考是Better array 'countof' implementation with C++ 11。它讨论了错误地做事的方法,以及如何在不同的编译器(如 Clang、ICC、GCC 和 MSVC)下正确地做事。它包括 Visual Studio 技巧。


buff是一个可以在程序执行过程中改变大小的数组

只要您在编译时有数据,countof 宏或函数就应该可以工作。如果您正在动态构建数据,那么它可能无法正常工作。


这密切相关:Common array length macro for C?。它甚至可能是重复的。

【讨论】:

  • 不回答 OP,这给出了 op 想要的元素的数量,以字节为单位。
猜你喜欢
  • 2020-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-11
  • 2014-01-21
  • 1970-01-01
  • 2013-03-15
相关资源
最近更新 更多