【问题标题】:C++ reference byte arrayC++ 参考字节数组
【发布时间】:2016-02-14 20:49:24
【问题描述】:

我对 C++ 和创建引用字节 [] 有疑问。

在 C# 中我的方法是:

public static void SetBitAt(ref byte[] Buffer, int Pos, int Bit, bool Value)
    {
        byte[] Mask = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
        if (Bit < 0) Bit = 0;
        if (Bit > 7) Bit = 7;

        if (Value)
            Buffer[Pos] = (byte)(Buffer[Pos] | Mask[Bit]);
        else
            Buffer[Pos] = (byte)(Buffer[Pos] & ~Mask[Bit]);
    }

我想将它翻译成 C++,但我无法获得 refworking for C++。我看到了一些关于 &amp; 符号的东西,我尝试了这样的事情:

void SetBitAt(byte& buffer[], int Pos, int Bit, bool Value)
{
    byte Mask[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
    if (Bit < 0) Bit = 0;
    if (Bit > 7) Bit = 7;

    if (Value)
    {
        buffer[Pos] = (byte)(buffer[Pos] | Mask[Bit]);
    }
    else
    {
        buffer[Pos] = (byte)(buffer[Pos] & ~Mask[Bit]);
    }
}

然后我得到错误:

'buffer':引用数组是非法的。

那么如何更改我的 C++ 代码以使用引用数组?

编辑: 我使用这种方法设置缓冲区,但是使用这种方法时它不会改变。

其他类:

buffer = ReadDB(2);          //Read the values in the DataBlock
SetBitAt(buffer, 0,0 true);  //Set bit 0,0 to 1(true)
WriteDB(2, buffer);          //Write the values to the Datablock

但缓冲区不会改变。它的值相同。

【问题讨论】:

  • "ref" 仅在 C++ CLR 中启用。这就是它在这里不起作用的原因。

标签: c++ ref


【解决方案1】:

如果你想通过引用传递数组,你应该

void SetBitAt(byte (buffer&)[10], int Pos, int Bit, bool Value)

但在你的情况下,你不需要那个,只是

void SetBitAt(byte buffer[], int Pos, int Bit, bool Value)

注意在这种情况下数组将衰减为指针(即byte*),这意味着数组的大小不会像按引用传递那样保留。

【讨论】:

  • 检查我的问题,我添加了一些我使用此方法的额外信息。
  • 巴特,这个答案是正确的。在 C 和 C++ 中,数组作为指针传递,因此可以引用元素。由于您的所有代码都在引用元素,因此不再需要。
  • @Bart:你现在已经从最初的问题进入调试帮助我模式,但是你错过了MCVE。我们已经正确回答了这个问题,您可能只需要进一步调试您的逻辑。
  • @ray 是的,你是对的,我将为我的下一个问题创建一个新问题
  • @Bart 你能提供一个MCVE 吗?我试过一个here,请检查一下。您可能需要检查SetBitAt() 是否正确设置了值。
【解决方案2】:

'buffer':引用数组是非法的。

这是由于运算符优先级。说byte &amp;buffer[] 是一个引用数组,而说byte (&amp;buffer)[size] 是一个数组引用。

更多详情请见C++ pass an array by reference。

那么如何更改我的 C++ 代码以使用引用数组?

将数组作为函数参数传递时,应删除&amp; 符号。您仍然可以修改数组的内容,因为改为传递数组的地址。

假设您有一个 typedef 或 char 到 byte,您的函数签名应如下所示:

void SetBitAt(byte buffer[], int Pos, int Bit, bool Value) { ... }

注意,上面相当于传递一个指针:

void SetBitAt(byte *buffer, int Pos, int Bit, bool Value) { ... }

修改你数组的内容还是说buffer[Pos] = // some value;

What is array decaying? 上的这个帖子应该很有用。

【讨论】:

    【解决方案3】:

    不应该是这样吗:

    void SetBitAt(byte buffer[], int Pos, int Bit, bool Value)
    {
        byte Mask[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
        if (Bit < 0) Bit = 0;
        if (Bit > 7) Bit = 7;
    
        if (Value)
        {
            buffer[Pos] = (byte)(buffer[Pos] | Mask[Bit]);
        }
        else
        {
            buffer[Pos] = (byte)(buffer[Pos] & ~Mask[Bit]);
        }
    }
    

    这样,buffer作为指针传递,buffer[Pos]引用buffer的Pos-th元素。它是普通的 C,但它应该可以工作。

    【讨论】:

    • 我这样做了,但它并没有改变我的缓冲区,有关更多信息,请参阅我编辑的问题。
    【解决方案4】:

    你可以简单地通过地址传递它:

    void SetBitAt(byte* buffer, int Pos, int Bit, bool Value) { ... }
    

    或者简单地说:

    void SetBitAt(byte buffer[], int Pos, int Bit, bool Value) { ... }
    

    任何一个都会告诉编译器字节指针被传递给函数,尽管在第二个头文件中你省略了指针算术;)

    【讨论】:

    • buffer 和 &amp;buffer 不一样。它们有不同的类型。
    • 我的错,@Peter 数组的名称是指向该数组的常量指针。谢谢!
    猜你喜欢
    • 2018-01-05
    • 1970-01-01
    • 2013-01-26
    • 1970-01-01
    • 2015-08-07
    • 2012-05-22
    • 1970-01-01
    • 1970-01-01
    • 2010-12-12
    相关资源
    最近更新 更多