在c++和c#中,对字符数组进行赋值和赋值时的值是不同的
Different values when ANDING and assigned uints to a char array in C++ and C#
我有一个非常简单的问题,这让我非常头疼,因为我从c++移植了一点代码到c#,对于一个非常简单的操作,我得到了完全不同的结果:-
c++char OutBuff[25];
int i;
unsigned int SumCheck = 46840;
OutBuff[i++] = SumCheck & 0xFF; //these 2 ANDED make 248
写入字符数组的值是-8
c#char[] OutBuff = new char[25];
int i;
uint SumCheck = 46840;
OutBuff[i++] = (char)(sumCheck & 0xFF); //these 2 ANDED also make 248
写入字符数组的值是248
有趣的是,它们都是相同的字符,所以这可能与c++和c#中字符数组的格式有关-但最终,如果有人能给我一个明确的答案,我会很感激。
提前感谢您的帮助。
大卫的溢出在c++和没有溢出在c#。
在c#中,char
是两个字节。在c++中,char
是一个字节!所以在c#中,没有溢出,值被保留。c++中存在整型溢出。
将数据类型从char
更改为uint16_t
或unsigned char
(c++中),您将看到相同的结果。注意,unsigned char
的值可以是248
,而不会溢出。事实上,它的值最高可达255
也许您应该使用字节或sbyte而不是char。(char仅用于存储文本字符,并且char的实际二进制序列化与c++中的不一样。Char允许我们存储字符而不用担心字符字节的宽度。
c# char
实际上是16位,而c++ char
通常是 8位(char
在visualc++上恰好是8位)。所以你实际上在c++代码中溢出了整数,但c#代码不会溢出,因为它保存了更多的位,因此有更大的整数范围。
注意248在有符号的char
(-128到127)的范围之外。这应该给你一个提示,c#的char
可能大于8位。
你可能打算使用c#的sbyte
,(最接近于Visual c++的char
)如果你想保留这种行为。尽管您可能想要重新检查代码代码,因为在c++实现中发生了溢出
正如大家所说,在c#中一个字符是16位,而在c++中通常是8位。
-8和248的二进制(本质上)都是这样的:
11111000
因为c++中的char通常是8位(这实际上是你的情况),所以结果是-8。在c#中,值看起来像这样:
00000000 11111000
16位,变成248
2的-8的补码表示形式与248的二进制表示形式相同(无符号)所以在这两种情况下二进制表示是一样的。c++将其解释为int8结果,而c#将其简单地解释为正整数(int为32位,通过转换为char将截断为16,在这种情况下不会影响符号)
-8和248之间的区别在于如何解释数据。它们的存储方式完全相同(0xF8)。在c++中,默认的char类型是'signed'。因此,0xF8 = -8。如果您将数据类型更改为'unsigned char',它将被解释为248。VS也有一个编译器选项,使'char'默认为'unsigned'。
- 由于没有使用赋值运算符,映射的值是如何初始化的?
- C++:将值赋值给原始数据类型(例如布尔值)是原子操作吗?
- 在未初始化的变量上使用复合赋值运算符(+=, ..)不是C++中的UB?
- 链表指针赋值为什么我们不能直接将尾巴分配给 temp 而不是尾巴>尾巴下一个
- 复合赋值的左侧表达式是未初始化的值.计算出的值也将是垃圾
- 为什么在C++中,内建赋值返回的是非常量引用而不是常量引用
- 为什么在直接初始化和赋值中传递 lambda 而不是在复制初始化中传递 lambda 时会编译?
- C++不同类型的默认赋值运算符
- 原子变量的多重赋值是原子操作吗?
- 为什么类的赋值运算符的返回类型通常是非常量(而不是常量)引用?
- 我正在比较两个具有相同值的变量,但它说它们是不同的
- 查找所有移动构造函数和移动赋值运算符(特别是那些没有"noexcept"的运算符)
- c++ 取消引用赋值是按位赋值还是按位赋值或"smart"赋值?
- 重载赋值运算符:不同的数据类型-不可能
- 在函数中将指针赋值到不同的地址
- c++中的右移赋值是什么意思?
- 在c++和c#中,对字符数组进行赋值和赋值时的值是不同的
- 使用复制赋值实现不同对象容器之间的自动化
- 为什么对基类的赋值有效,但对派生类的赋值是编译错误
- 采用不同数据类型的赋值操作符的名称是什么?