为什么 0x82 比 0x80 小?

Why is 0x82 smaller than 0x80?

我正在尝试为大学 class 练习优化字符串 class。 普通字符串存储为 char* 和 size_t 长度。 sizeof(String) 是 8,它应该保持这样。然而,如果我只有 7 个或更少字符的字符串(如果考虑空终止符,则为 6 个),而不是使用指针,我想将它们直接存储在 pointer/size_t 字节中。

为此,我有两个结构,一个用于 char* 和 size_t,另一个用于 8 个字符(字节)的数组。我都放在一个联合中,并给字符串 class 一个所述联合的成员。

为了确定一个字符串是普通字符串还是短字符串,我使用长度的最高有效位 size_t 或 byte[7]。如果 byte[7] 大于或等于 128(或 0x80),则它是一个短字符串,字符直接存储在字节中。然后将长度存储在 byte[7].

的剩余位中

这就是目前的理论。普通字符串位已经实现,我现在正在尝试实现短字符串位。我现在遇到的问题是以下代码:

inline const char* c_str(void) const
    {
        if (compound.bytes.bytes[7] >= 0x80)
            return compound.bytes.bytes;
        return compound.string.m_string;
    }

从 Visual Studio 观察者那里我知道 compound.bytes.bytes[7] 是 0x82(字符串是 "hi")。所以它应该是 0x82 >= 0x80,如 true 和 return 字节,但由于某种原因,这个比较得到 false 并且 returns 是普通字符串的 char*,这当然是一个伪指针(准确地说是 0xcc006968)。

另外值得指出的是,这段代码对于普通字符串仍然可以正常工作。

我错过了什么,我做错了什么?

char* 有符号 0x80 及以上为负数

当使用有符号 8 位整数时,值 0x80 是一个负数。 因此 0x82 会更少,因为它也是负数。 值 0x82 转换为 -126,0x80 转换为 -128,这意味着 0x80 小于 0x82 补充有符号整数

将您的数据类型切换为 uint8_t

您正在使用有符号值 (char)。因此,0x80 表示 -128,而 0x82 表示 -126。此代码可能会根据您的需要工作:

inline const char* c_str(void) const
{
    if (static_cast<unsigned char>(compound.bytes.bytes[7]) >= 0x80u)
        return compound.bytes.bytes;
    return compound.string.m_string;
}

您正在比较 signed char (0x82 = -126) 和 signed int (0x00000080 = 128)。 Signed char 可以是 -128 到 127 之间的数字,因此它总是小于 128。