Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 无符号字符的位运算_C++_C_Bit Manipulation - Fatal编程技术网

C++ 无符号字符的位运算

C++ 无符号字符的位运算,c++,c,bit-manipulation,C++,C,Bit Manipulation,我有一个示例函数,如下所示: int get_hash (unsigned char* str) { int hash = (str[3]^str[4]^str[5]) % MAX; int hashVal = arr[hash]; return hashVal; } 这里数组arr的大小为MAX.int arr[MAX] 我的静态代码检查器抱怨这里可能存在越界数组访问,因为散列可能在-255到-1之间 这是正确的吗?对无符号字符的按位操作能否产生负数?hash应该声

我有一个示例函数,如下所示:

int get_hash (unsigned char* str)
{
    int hash = (str[3]^str[4]^str[5]) % MAX;
    int hashVal =  arr[hash];
    return hashVal;
}
这里数组arr的大小为MAX.int arr[MAX]

我的静态代码检查器抱怨这里可能存在越界数组访问,因为散列可能在-255到-1之间


这是正确的吗?对无符号字符的按位操作能否产生负数?hash应该声明为unsigned int吗?

正如gx所正确指出的那样,该算法是在int中完成的。只需将hash变量声明为unsigned char,再次声明,以确保每个人都知道,在所有情况下,这都是正的


如果MAX实际上是UCHAR\u MAX,那么您应该使用它来提高可读性。

正如gx\u正确指出的那样,算术是用int完成的。只需将您的哈希变量声明为unsigned char,再次声明,以确保每个人都知道,您希望它在所有情况下都是正数

如果MAX实际上是UCHAR_MAX,那么您应该使用它来提高可读性

这是正确的吗

否,静态代码检查器处于错误1中

对无符号字符的按位操作能否产生负数

有些位运算可以(例如,位补码)但不能是异或运算

对于^,参数unsigned char(此处为unsigned char)需要进行通常的算术转换6.3.1.8,它们首先根据整数升迁进行升迁;关于这些,第6.3.1.1条第2款规定

如果整数可以表示受宽度限制的原始类型的所有值,则对于位字段,该值将转换为整数;否则,它将转换为无符号整数。这些称为整数

因此,有两种可能性:

int可以表示无符号字符的所有可能值。那么从整数提升中获得的所有值都是非负的,这些值的位异或也是非负的,余数也是模极大值。然后,哈希值在0(包括)到最大(排除)[MAX(如果MAX<0)]之间的范围内

int不能表示无符号字符的所有可能值。然后将值提升为unsigned int类型,并在该类型上执行逐位运算。结果当然是非负的,模极大的余数也是非负的。但是,在这种情况下,对int hash的赋值可能会将超出范围的值转换为负值[超出范围的整数转换为有符号整数类型由实现定义]。1但在这种情况下,可能的负值范围大于-255到-1,因此即使在这种情况下,静态代码检查器也有部分错误

散列应该声明为无符号整数吗

这取决于MAX的值。如果余数模MAX极有可能超出int的范围,那么这将更安全。否则,int同样安全

这是正确的吗

否,静态代码检查器处于错误1中

对无符号字符的按位操作能否产生负数

有些位运算可以(例如,位补码)但不能是异或运算

对于^,参数unsigned char(此处为unsigned char)需要进行通常的算术转换6.3.1.8,它们首先根据整数升迁进行升迁;关于这些,第6.3.1.1条第2款规定

如果整数可以表示受宽度限制的原始类型的所有值,则对于位字段,该值将转换为整数;否则,它将转换为无符号整数。这些称为整数

因此,有两种可能性:

int可以表示无符号字符的所有可能值。那么从整数提升中获得的所有值都是非负的,这些值的位异或也是非负的,余数也是模极大值。然后,哈希值在0(包括)到最大(排除)[MAX(如果MAX<0)]之间的范围内

int不能表示无符号字符的所有可能值。然后将值提升为unsigned int类型,并在该类型上执行逐位运算。结果当然是非负的,模极大的余数也是非负的。但是,在这种情况下,对int hash的赋值可能会将超出范围的值转换为负值[超出范围的整数转换为有符号整数类型由实现定义]。1但在这种情况下,可能的负值范围大于-255到-1,因此即使在这种情况下,静态代码检查器也有部分错误

散列应该声明为无符号整数吗


这取决于MAX的值。如果余数模MAX极有可能超出int的范围,那么这将更安全。否则,int同样安全。

当与算术/位运算一起使用时,无符号字符在计算前隐式转换为int yes,signed int
反倾销。现在,在[0255]范围内的两个整数之间的异或总是会产生一个相同范围内的整数,因此,永远不会是负数,但静态检查器不会那么深。假设在您的平台上,整数大于字符,这段代码看起来不错。@OliCharlesworth,很好。更正我之前的评论:在无符号字符和int大小相同的平台上(比如32位),无符号字符将被隐式转换为无符号int,无符号将被保留,因为转换为有符号整数可能会产生不同的负值。@gx_u但是代码会将模运算符的结果分配给有符号整数,因此根据我们尚未给出的MAX值,可能会产生一个负数组索引。与算术/位运算一起使用时,无符号字符在计算前隐式转换为int yes,signed int。现在,在[0255]范围内的两个整数之间的异或总是会产生一个相同范围内的整数,因此,永远不会是负数,但静态检查器不会那么深。假设在您的平台上,整数大于字符,这段代码看起来不错。@OliCharlesworth,很好。更正我之前的评论:在无符号字符和int大小相同的平台上(比如32位),无符号字符将被隐式转换为无符号int,无符号将被保留,因为转换为有符号整数可能会产生不同的负值。@gx_u但是代码会将模运算符的结果分配给有符号整数,因此根据我们没有得到的MAX值,可能会产生一个负数组索引。但即使哈希是无符号的,请注意str[3]、str[4]和str[5]分别隐式提升为int类型,因此对有符号int执行XOR。最后,unsigned int hash将解决这个问题,但理想情况下,整个表达式将写成unsigned int hash=unsigned intstr[3]^str[4]^str[5]%MAX@Lundin,不,我认为强制hash为unsigned char,而不是unsigned int应该让静态分析器相信hash的可能范围。rhs上表达式的任何值都将转换为正确的范围0…UCHAR_MAX。但是,即使哈希是无符号的,请注意str[3]、str[4]和str[5]分别被隐式提升为int类型,因此对有符号的int执行XOR。最后,unsigned int hash将解决这个问题,但理想情况下,整个表达式将写成unsigned int hash=unsigned intstr[3]^str[4]^str[5]%MAX@Lundin,不,我认为强制hash为unsigned char,而不是unsigned int应该让静态分析器相信hash的可能范围。rhs上表达式的任何值都将转换为正确的范围0…UCHAR_MAX。将索引设置为无符号int没有任何不利之处,因此我建议无论如何都这样做,只是为了避免任何深奥的可能性。将索引设置为无符号int没有任何不利之处,因此我建议无论如何都这样做,只是为了避免任何深奥的可能性