在c++和c#中,对字符数组进行赋值和赋值时的值是不同的

Different values when ANDING and assigned uints to a char array in C++ and C#

本文关键字:赋值 是不同 字符 c++ 数组      更新时间:2023-10-16

我有一个非常简单的问题,这让我非常头疼,因为我从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_tunsigned 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'。