更改char数组的一个成员会更改另一个成员

时间:2016-08-04 22:05:49

标签: c++ arrays

我编写了一些代码作为练习,它基本上只使用(循环除外)逐位操作对任何大小的数据执行数学运算。它主要是功能性的,但有一个我无法理解的问题,我无法在上下文中重新创建它,并且有一些代码随之而来,但这里的代码片段给我带来了麻烦

const __rint<size> _leftshiftto(__rint<size>arg)
{
    if (arg.val[0] & 0x80)//negative arg
    {
        return _rightshiftto(arg._negto());
    }
    uint32_t byte = (arg._int32() / 8);
    uint32_t carbyte = size - byte;
    byte = byte;
    uint8_t bit = (arg._int8() % 8);
    uint8_t carbit = 8 - bit;


    for (uint32_t n = 0; n<carbyte; ++n)
    {
        puts("iter");
        printf("%02hhx <- %02hhx\n",val[n],val[n+byte]);
        val[n] = val[n + byte];
    }
    for (uint32_t n = carbyte; n < size; ++n)
    {
        puts("iter2");
        val[n] = 0x00;
    }

    for (uint32_t n = 0; n<size-1; ++n)
    {
        val[n] <<= bit;
        val[n] &= val[n + 1] >> carbit;
    }
    val[size - 1] <<= bit;

    return *this;
}

完整代码位于https://github.com/rtpax/rmath/blob/master/rint.h

正在发生的事情是它适用于足够小的值,但对于输入8或更高的值评估为零(所以如果它移动整个字节)。

__rint<4> a(5);
//evaluates to 0x00000005
a._leftshiftto(4);
//evaluates to 0x00000050
__rint<4> b(5);
//evaluates to 0x00000005
b._leftshiftto(8);
//evaluates to 0x00000000

如果更改线路

,更奇怪的是
val[n] = 0x00;

val[n] = 0xff;//or anything 0x80 and above

它确实有效,除了最右边的字节将填充你放在那里的任何数字(因此上面的b将评估为0x000005ff) 我对此感到茫然,如果有人能提供解释我很感激。

其他一些说明:

我正在使用Windows 10上的g ++进行编译

似乎相关的东西是,当我打印出我的六角形时,如果它们至少为0x80(打印为0xff80),则显示为4位数而不是2位数

从1到7的反转也不适用于较大的数字,但我认为这些失败的原因与整个字节转换失败的原因相同。

1 个答案:

答案 0 :(得分:0)

&是逻辑和运算符:它在两个源中都需要1才能在目标中产生1。 0101 & 0011会产生0001

val[n] &= val[n + 1] >> carbit;

这会将val[n]设置为零,因为我们知道val[n]的低位为零,我们移位val[n + 1]位,因此相应的高位将为零:

11111000 &
00000111 =
00000000

您需要|运算符:

11011000 |
00000010 =
11011010

另请注意,您的代码会修改此对象,但您可以按值返回,制作副本。

您的返回类型可能应为

const __rint<size>&

返回const 在这里没什么意义。