一、关于 char、int 中的 signed 和 unsigned
在C++中,char
是一种基本数据类型,用于表示单个字符。char
变量通常用于存储ASCII字符或者扩展的字符集中的一个字符。char
变量可以存储单个字符,包括字母、数字、标点符号和特殊字符等。在内存中,每个 char
变量通常占用一个字节(8位),它的值在-128到127之间,可以用于存储ASCII字符的编码。
例如,下面是一些使用 char
变量的示例:
char ch = 'A'; // 存储一个字符'A'
char digit = '7'; // 存储一个数字字符'7'
char symbol = '+'; // 存储一个符号字符'+'
char newline = '\n'; // 存储一个换行符
在C++中,char
类型还可以用于构建字符串,但是由于C风格字符串的限制,通常会使用C++中的 std::string
类型来处理字符串。
在C++中,int
是一种基本数据类型,用于表示整数。它可以存储范围内的整数值,通常占用4个字节(32位),其值的范围通常是从-2147483648到2147483647(如果是带符号的)或从0到4294967295(如果是无符号的)。
signed
和 unsigned
是C++中用于修饰整数类型的关键字,它们表示整数的有符号性质和无符号性质。
signed:
signed
是默认的整数类型修饰符,通常用于表示有符号整数。- 有符号整数可以表示正数、负数和零,范围通常是从负的最小值到正的最大值。
- 例如,
int
、short
、long
等整数类型默认都是有符号的,除非显式地指定为unsigned
。
unsigned:
unsigned
用于表示无符号整数,即只能表示非负整数(包括零)。- 无符号整数范围通常是从零到正的最大值。
- 例如,
unsigned int
、unsigned short
、unsigned long
等整数类型都是无符号的。
使用 signed
或 unsigned
可以根据需要来选择合适的整数类型。通常情况下,如果你确定整数值不会为负数,可以使用 unsigned
类型来节省内存空间。但需要注意,使用 unsigned
类型可能会引发一些意外的结果,因为它不支持负数。
二、长字节数据类型 int 转换到短字节类型 char
当从一个较长的数据类型(如int)转换为一个较短的数据类型(如char)时,可能会发生截断,因为目标数据类型无法容纳源数据类型的所有值。在这种情况下,编译器会将源数据类型的值截断为目标数据类型的大小,并且通常会丢失一些信息。
让我们以将int类型转换为char类型为例来说明:
#include <iostream>
int main() {
int sourceValue = 1000; // 假设源数据是一个较大的整数
char targetValue = sourceValue; // 将int类型转换为char类型
std::cout << "源数据值: " << sourceValue << std::endl;
std::cout << "转换后的目标数据值: " << static_cast<int>(targetValue) << std::endl;
return 0;
}
在这个例子中,源数据值为1000(sourceValue = 1000),这个值是一个int类型。然而,当将int类型转换为char类型时,会发生截断,只保留了源数据的最低位字节。因此,截断后的结果是1000被截断为一个char类型的值。但是,由于char类型的范围通常是从-128到127(或0到255,取决于是否有符号),因此1000这个值超出了char类型的表示范围。
因此,结果取决于char类型是有符号还是无符号:
- 如果char类型是有符号的,那么1000这个值会被截断为char类型的最大正数值,因此结果将是127。
- 如果char类型是无符号的,那么1000这个值会被截断为char类型的最大值,因此结果将是255。
实际结果取决于编译器对于截断的处理方式和char类型的有无符号性质。在截断过程中,源数据的高位字节(如果有的话)将被丢弃,只保留最低位的字节。这意味着在本例中,源数据的值将被截断为char类型可以表示的范围内,因此结果可能会与源数据不同。需要注意的是,当进行这种类型转换时,编译器通常会发出警告,因为可能会丢失一些信息。所以,要谨慎使用这种类型的转换,确保不会导致意外的结果。
三、短字节数据类型 char 转换到长字节类型 int
当将一个较短的数据类型(如char)转换为一个较长的数据类型(如int)时,通常不会发生截断,因为目标数据类型有足够的空间来容纳源数据类型的所有可能值。
让我们以将char类型转换为int类型为例来说明:
#include <iostream>
int main() {
char sourceValue = 'A'; // 假设源数据是一个字符
int targetValue = sourceValue; // 将char类型转换为int类型
std::cout << "源数据值: " << static_cast<int>(sourceValue) << std::endl;
std::cout << "转换后的目标数据值: " << targetValue << std::endl;
return 0;
}
字符 'A' 的值为65。在char类型中,如果char是带符号的,则 'A' 的二进制表示形式是 01000001,其中最高位(最左边的位)为0,表示正数。当将char类型的值转换为int类型时,将使用符号扩展来填充int类型的剩余位数。
当将signed char和unsigned char转换为int类型时,补位情况取决于原始值和目标类型。
signed char:
- 如果signed char的首位为1(表示负数),则进行符号扩展(0xFFFFFF)。
- 如果signed char的首位为0(表示非负数),则进行零扩展(0x000000)。
unsigned char:
- 无论unsigned char的首位是什么,转换为int类型时都会进行零扩展(0x000000)。
具体情况如下:
- 如果signed char的首位为1(表示负数),在转换为int类型时,会使用符号扩展填充剩余的位数,将原始值的符号位复制到int类型的所有扩展位上。
- 如果signed char的首位为0(表示非负数),在转换为int类型时,会使用零扩展填充剩余的位数,所有扩展位将被填充为0。
- 对于unsigned char类型,无论其首位是什么,在转换为int类型时都会进行零扩展,所有扩展位都将被填充为0。
例如:
- 对于signed char的值为-1(二进制表示为11111111),转换为int类型时,会进行符号扩展,所有扩展位都将被填充为1(即补位为0xFFFFFFFF)。
- 对于unsigned char的值为255(二进制表示为11111111),转换为int类型时,会进行零扩展,所有扩展位都将被填充为0(即补位为0x000000FF)。
面经!面经!背起走!