【问题标题】:How to create a byte array in C++?如何在 C++ 中创建字节数组?
【发布时间】:2013-05-10 19:21:20
【问题描述】:

请看下面的头文件

#pragma once

class MissileLauncher
{
public:
    MissileLauncher(void);

private:
    byte abc[3];
};

这产生了错误

Error   1   error C2143: syntax error : missing ';' before '*'  

我尝试过这样做

byte *abc;

但它也失败了,同样的错误。但是,我注意到我可以以这种方式调用其他内置的 tyes 数组,例如 int 数组。为什么字节数组会发生这种情况?如何解决这个问题?我想在 cpp 文件中分配值。有什么想法吗?

【问题讨论】:

  • 您提供的代码中没有*,因此它不可能生成该错误消息。请准确。
  • 另外,byte 来自哪里?它不是标准类型。

标签: c++ arrays visual-studio-2010 byte


【解决方案1】:

试试

class MissileLauncher
{
public:
    MissileLauncher(void);

private:
    unsigned char abc[3];
};

using byte = unsigned char;

class MissileLauncher
{
public:
    MissileLauncher(void);

private:
    byte abc[3];
};

**注意:在较旧的编译器(非 C++11)中,将 using 行替换为 typedef unsigned char byte;

【讨论】:

  • char 不必是一个字节
  • char 保证为一个字节; sizeof(char) == 1,总是。但“字节”不保证是 8 位。
  • @Nicolás sizeof 返回 chars 中的大小。标准做出的唯一保证是 sizeof(char) 为 1。其余的都是未定义的行为。一个字节不保证是 1 个字符。 POSIX 1-2001 似乎将 CHAR_BIT 宏定义为 8。请参阅:gnu.org/software/libc/manual/html_node/Width-of-Type.html
  • @Dragas sizeof 返回一个字节数,一个字节可能超过8位en.cppreference.com/w/c/language/sizeof
【解决方案2】:

如果你只想要一个字节,在 cstdint 中定义的 uint8_t 将是最有表现力的。

http://www.cplusplus.com/reference/cstdint/

【讨论】:

  • 另外,似乎只有 C++11。
  • @MichaelPrice,不,它在以前的 C++ 中也可用。使用 而不是 。我今天在我们说话的一些代码中使用它。 :-)
  • @KellyBeard - 仅在 C++11 发布后可用(作为标准的可移植方法)。 并不完全相同。
【解决方案3】:

也许您可以利用 C++11 中提供的 std::bitset 类型。它可以用来表示一个固定的N位序列,可以通过常规逻辑来操作。

#include<iostream>
#include<bitset>

class MissileLauncher {
 public:
  MissileLauncher() {}
  void show_bits() const {
    std::cout<<m_abc[2]<<", "<<m_abc[1]<<", "<<m_abc[0]<<std::endl;
  }

  bool toggle_a() {
    // toggles (i.e., flips) the value of `a` bit and returns the
    // resulting logical value
    m_abc[0].flip();
    return m_abc[0];
  }

  bool toggle_c() {
    // toggles (i.e., flips) the value of `c` bit and returns the
    // resulting logical value
    m_abc[2].flip();
    return m_abc[2];
  }

  bool matches(const std::bitset<3>& mask) {
    // tests whether all the bits specified in `mask` are turned on in
    // this instance's bitfield
    return ((m_abc & mask) == mask);
  }

 private:
  std::bitset<3> m_abc;
};

typedef std::bitset<3> Mask;
int main() {
  MissileLauncher ml;

  // notice that the bitset can be "built" from a string - this masks
  // can be made available as constants to test whether certain bits
  // or bit combinations are "on" or "off"
  Mask has_a("001");       // the zeroth bit
  Mask has_b("010");       // the first bit
  Mask has_c("100");       // the second bit
  Mask has_a_and_c("101"); // zeroth and second bits
  Mask has_all_on("111");  // all on!
  Mask has_all_off("000"); // all off!

  // I can even create masks using standard logic (in this case I use
  // the or "|" operator)
  Mask has_a_and_b = has_a | has_b;
  std::cout<<"This should be 011: "<<has_a_and_b<<std::endl;

  // print "true" and "false" instead of "1" and "0"
  std::cout<<std::boolalpha;

  std::cout<<"Bits, as created"<<std::endl;
  ml.show_bits();
  std::cout<<"is a turned on? "<<ml.matches(has_a)<<std::endl;
  std::cout<<"I will toggle a"<<std::endl;
  ml.toggle_a();
  std::cout<<"Resulting bits:"<<std::endl;
  ml.show_bits();  
  std::cout<<"is a turned on now? "<<ml.matches(has_a)<<std::endl;
  std::cout<<"are both a and c on? "<<ml.matches(has_a_and_c)<<std::endl;
  std::cout<<"Toggle c"<<std::endl;
  ml.toggle_c();
  std::cout<<"Resulting bits:"<<std::endl;
  ml.show_bits();    
  std::cout<<"are both a and c on now? "<<ml.matches(has_a_and_c)<<std::endl;  
  std::cout<<"but, are all bits on? "<<ml.matches(has_all_on)<<std::endl;
  return 0;
}

使用 gcc 4.7.2 编译

g++ example.cpp -std=c++11

我明白了:

This should be 011: 011
Bits, as created
false, false, false
is a turned on? false
I will toggle a
Resulting bits:
false, false, true
is a turned on now? true
are both a and c on? false
Toggle c
Resulting bits:
true, false, true
are both a and c on now? true
but, are all bits on? false

【讨论】:

  • 问题是字节数​​组,而不是位数组
【解决方案4】:

字节不是 C 或 C++ 中的标准类型。试试 char,它通常至少 8 位长。

【讨论】:

  • 感谢您的回复。那么,使用 char 数组?它可以像字节一样将值发送到 USB 端口吗?\
  • 当你使用 char 时,它正好是一个字节;因此,在 C/C++ 中将“char”发送到 USB 端口,您实际上是在发送一个字节。
【解决方案5】:

字节不是 C/C++ 中的标准数据类型,但它仍然可以按照我想你想要的方式使用。方法如下:回想一下,一个字节是一个 8 位内存大小,它可以表示 -128 和 127 之间的任何整数,包括 128 和 127。 (该范围内有 256 个整数;8 位可以表示 256——2 位的 8 次方——不同的值。)。还记得 C/C++ 中的 char 是一个字节(八位)。因此,在 C/C++ 中拥有字节数据类型所需要做的就是将此代码放在源文件的顶部: #定义字节字符 所以你现在可以声明 字节 abc[3];

【讨论】:

    【解决方案6】:

    您可以使用 Qt,如果您不知道,它是 C++,带有一堆额外的库和类等等。 Qt 有一个非常方便的 QByteArray 类,我确信它会满足您的需求。

    http://qt-project.org/

    【讨论】:

    • 这就像 javascript 的“只使用 jquery”,但对于 c++。
    【解决方案7】:

    字节在C/C++中不是标准类型,所以用char表示。

    这样做的一个优点是您可以将basic_string 视为一个字节数组,以实现安全存储和函数传递。这将帮助您避免在使用char[]char* 的各种形式时可能遇到的内存泄漏和分段错误。

    例如,这将创建一个字符串作为空值的字节数组:

    typedef basic_string<unsigned char> u_string;
    
    u_string bytes = u_string(16,'\0');
    

    这允许对其他char 值进行标准按位运算,包括存储在其他string 变量中的值。例如,将另一个u_stringchar 值与bytes 进行异或:

    u_string otherBytes = "some more chars, which are just bytes";
    for(int i = 0; i < otherBytes.length(); i++)
        bytes[i%16] ^= (int)otherBytes[i];
    

    【讨论】:

    • 想解释否决票?我们每天都在多个生产级系统中使用这种模式,内存泄漏为零。
    • 我不是反对者,但使用字符串存储二进制数据是一种非常糟糕的做法。您依靠字符串实现来使用 8 字节字符。在实践中,尤其是在现代系统上,许多字符串实现在内部将其字符串编码为 UTF-8 或 UTF-16(可变长度编码)。这意味着您的 .length 调用将指的是字形的数量,而不是字节数。如果您在生产系统上使用它,您应该担心。字符串和字节数组有非常不同的用途。
    • @Chris 你是说应该使用char 数组来保证8 字节字符吗?该解决方案的可悲之处在于引入了char* 的手动内存管理,根据我的经验,这是在 C/C++ 代码中看到的大约一半内存泄漏的原因。
    • 不一定。 char 在技术上不能保证为 8 位(但通常是这样)。如果您想要更强的保证,请使用stdint.h 中的uint8_t。就您关于手动内存管理的观点而言,是的,从技术上讲,您所说的是正确的。然而,较新版本的 C++ 有 std::array 可以为您抽象内存管理。如果你不能使用更新的标准,我认为有一个 boost 等价物(有一个 boost array 和一个 boost buffer 两者都处理字节序列)。但是,如果我们谈论的是 C,是的,手动内存管理确实是您唯一的选择。
    • @Chris 好的,那么以这种方式声明它怎么样:basic_string&lt;uint8_t&gt; bytes。还是有比 uint8_t 更好的字节基类型?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-14
    • 1970-01-01
    相关资源
    最近更新 更多