char 的整数存储解释

c3daa479c3bf48ad88dc28d5ff748f7d.png

目录

1.原因讲解

1.有符号类型的char

2.无符号类型的char(0-255)

 练习题1.

 练习题2.

练习题3.


小心!VS2022不可直接接触,否则!没这个必要,方源面色淡然一把抓住!顷刻炼化! 


1.原因讲解

1.有符号类型的char

我们知道char类型只有一个字节,一个字节是8bit位

在计算机中,计算机只会识别二进制,并以补码的形式存储在内存中

8bit位的二进制补码可以列举出很多种情况,如图:

5637baa92b3947aea0c86d82166cc5a8.jpeg

8bit位的有符号二进制只能列举出这么多情况,从0开始,二进制不断地加1,最终完成一个闭环,127的补码加1后为-128,-1的补码加1后又回到0,如此循环,所以char类型是127—— -128


2.无符号类型的char(0-255)

无符号类型的char是0-255,是因为无符号类型中,每一位都算有效位,没有符号位的存在,所以补码的每一位都算有效位,如图:

1ed465500f6549fca4097bcfc686f095.jpeg

因此,无符号类型的char的范围是0-255,从0不断地加1,最终加到255

补码达到255时,再加1就会回到0,实现闭环循环


 练习题1.

#define _CRT_SECURE_NO_WARNINGS 
#include<stdio.h>
#include<string.h>
int main()
{	
	char a[1000];
	int i;
	for (int i = 0; i < 1000; i++) {
		a[i] = -1 - i;
	}
	printf("%d", strlen(a));
}	

 许多人会认为,a[i]会储存-1到-1000,但真的如此吗?

如果是这样想的话,那就出错误了

因为整数在有符号中储存只能存储127到-128的整数,那存储的是什么,打印的又是什么呢?

代码分析及结果:

详细讲解如下图:

1ec25fbf4cda435ba772767412e3dd7d.png


 练习题2.

#define _CRT_SECURE_NO_WARNINGS 
#include<stdio.h>
#include<string.h>
int main()
{
	unsigned char i = 0;

	for (i = 0; i <= 255; i++) {
		printf("hello world\n");
	}
}	

  这次打印出来的结果是什么呢?难道是打印256次 "hello world" 吗?

恭喜你又错了,正确答案是死循环打印 "hello world"

详解如下图:

545d5f7e5ad4451091ae3550dc30acdb.png


练习题3.

#define _CRT_SECURE_NO_WARNINGS 
#include<stdio.h>
#include<string.h>
int main()
{
	unsigned int i;
	
	for (i = 9; i >= 0; i--) {
		printf("%u\n", i);
	}
}	

  详细讲解如下图:

2a29e47eb72e4183a6579d604fc7a046.png

8fdd48caf53e46a897fd8a5554dbb454.png

### 关于 `unsigned char` 的赋值与注意事项 #### 1. 数据类型的范围 `unsigned char` 是一种字符数据类型,在 C 和 C++ 中通常占用 8 位 (bit),其取值范围为 0 到 255。这意味着它无法表示负数,任何超出此范围的值都会发生 **模运算** 或称为 **无符号溢出**[^1]。 #### 2. 负数赋值的行为 当尝试将 `-1` 这样的负数赋值给 `unsigned char` 变量时,编译器会将其视为无符号整数处理,并通过加法模运算来计算最终的结果。具体来说,`-1` 会被解释为 `(UINT_MAX + 1)`,即对于 8 位系统而言等于 255[^2]。 #### 3. 正确赋值方法 为了安全地将整数值赋予 `unsigned char` 类型变量,可以采用显式的类型转换操作符如 `static_cast`(推荐用于 C++),或者直接利用强制类型转换 `(unsigned char)` 来完成这一过程: ```cpp int main() { int num = 255; unsigned char uc; // 方法一:使用静态类型转换 (适用于C++) uc = static_cast<unsigned char>(num); // 方法二:使用传统的C风格强制类型转换 uc = (unsigned char)num; printf("Value after conversion: %u\n", uc); return 0; } ``` 如果输入值超出了 `unsigned char` 的合法范围,则需注意可能引发的数据截断现象。例如,当试图存储大于 255 的整数时,实际保存的是该数除以 256 后所得余数。 #### 4. 示例代码展示 下面提供了一个完整的例子,演示了如何正确以及不正确地向 `unsigned char` 赋值: ##### 错误示例 ```cpp #include <stdio.h> int main(){ unsigned char c = -1; // 不建议这样写,尽管能运行但逻辑上存在问题 printf("%d\n",c); // 输出可能是255而非预期的-1 return 0; } ``` ##### 正确示例 ```cpp #include <iostream> using namespace std; int main(){ int val = -1; unsigned char correctVal = static_cast<unsigned char>(val); // 推荐方式 cout << "Correctly casted value: " << +correctVal << endl; return 0; } ``` 此外,还可以借助标准库函数实现更复杂的场景下的转换需求,比如从十六进制字符串到 `unsigned char` 的转变[^3]: ```cpp #include <cstdio> #include <cstdlib> int main(){ const char* hexStr="FF"; unsigned char byteVal=0; sscanf(hexStr,"%hhx",&byteVal); printf("Hexadecimal '%s' converted to unsigned char is:%u\n",hexStr,byteVal); return EXIT_SUCCESS; } ``` 以上展示了多种情况下对 `unsigned char` 类型的有效初始化手段及其背后原理分析。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值