我正在尝试为大学课堂练习优化String课程。 普通字符串存储为char *,size_t存储长度。 sizeof(String)是8,它应该保持这样。然而,如果我只有7个或更少字符的字符串(如果考虑空终止符,则为6),而不是使用指针,我想直接将它们存储在指针/ size_t字节中。
为此,我有两个结构,一个用于char *和size_t,另一个用于8个字符(字节)的数组。我把它放在一个联合中,并给String类一个所说的union的成员。
要确定字符串是普通字符串还是短字符串,我使用长度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中并返回字节,但由于某种原因,此比较变为false并返回正常字符串的char *,这当然是伪指针(准确地说是0xcc006968)。 / p>
另外值得指出的是,这段代码仍能正常用于普通字符串。
我错过了什么,我做错了什么?
答案 0 :(得分:7)
使用带符号的8位整数时,值0x80为负数。 因此0x82会更少,因为它也是负的。值0x82转换为-126,0x80转换为-128,这意味着0x80小于0x82 二进制补码有符号整数。
将您的数据类型切换为uint8_t
。
答案 1 :(得分:2)
char *为0x80,超出为负
答案 2 :(得分:1)
您正在使用签名值(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;
}
答案 3 :(得分:0)
您正在将signed char(0x82 = -126)与signed int(0x00000080 = 128)进行比较。签名字符可以是-128到127之间的数字,因此它总是小于128。