【C】整数在内存中的存储

C语言中的整数存储:原码、反码与补码解析

在C语言中,整数是按照二进制存储的。

一个整型是4个字节,一个字节是8个比特位,4*8=32。

比如-3这个数字,在内存中就是10000000000000000000000000000011

关于原码、反码、补码

系统在内存中存放数据的时候,会先把二进制源码转化为反码,在把反码转换为补码,最后存放到内存中。

原码

什么是原码?像我们前面的-3,直接转化成二进制就是原码了。

反码

怎么得出反码呢?其实就是由原码的符号位不变,其他位按位取反得到的,那么-3的反码就是

11111111111111111111111111111100

符号位就是二进制从左开始的第一位,如果是正数就是0,如果是负数就是1,比如3的源码是

00000000000000000000000000000011

补码

补码就是在反码的基础上给二进制位加上个1,那么就得到了

11111111111111111111111111111101

我们还要知道一件事情,那就是正数的原码、补码、反码是一样的,这就是为什么我们前面要用-3来举栗子

当要用到-3的时候,系统就会将-3的补码转换成反码(减1),再将反码转换成原码(符号位不变,其他位按位取反),就得到了原来的数字。

<think> 我们正在讨论C语言中中文汉字的存储问题。根据引用[1]和[4],我们知道在C语言中,字符(char)类型通常占用1个字节,存储的是ASCII码值。但是,汉字通常需要多个字节来表示(在GBK编码中占2字节,UTF-8中占3-4字节),因此单个char变量无法存储一个完整的汉字。 在C语言中,汉字通常是用字符数组(字符串)的形式存储的,每个汉字由多个连续的char元素(字节)组成。每个字节存储的是该字符在特定编码(如GBK或UTF-8)下的整数值。 例如,在GBK编码中,一个汉字由两个字节组成,每个字节的值都在一定范围内(第一个字节大于127,第二个字节通常也是大于127的,但具体范围要看编码标准)。在UTF-8编码中,一个汉字通常由三个字节组成,每个字节都有特定的格式(如第一个字节的高位是1110开头,后面两个字节是10开头)。 因此,当我们输入一个汉字时,实际上在内存存储的是这个汉字在特定编码下的多个字节的整数值(每个字节的范围是0-255)。 下面通过一个示例程序来展示如何输出汉字在内存存储整数值(以字节为单位): </think> ### C语言中中文汉字在内存中的存储机制 在C语言中,中文汉字在内存中的存储方式与ASCII字符有本质区别,主要通过多字节编码实现。以下是核心原理分析: #### 1. **汉字存储的基本原理** - 单个`char`类型只能存储1个字节(8位),但汉字需要多个字节表示 - 在简体中文环境(GBK编码)中: - 每个汉字占用**2个连续的`char`存储单元**(共16位) - 每个字节的值范围是`0xA1-0xFE`(十进制161-254)[^4] - 示例:汉字"中"的GBK编码为`0xD6 0xD0`,内存存储为: ``` 内存地址 | 存储值(十六进制) | 存储值(十进制) ------------------------------------ n | 0xD6 | 214 n+1 | 0xD0 | 208 ``` #### 2. **内存存储示例与可视化** 通过以下代码可验证汉字的内存存储值: ```c #include <stdio.h> int main() { char chinese[] = "中文"; // 创建包含汉字的字符数组 printf("内存存储值(十六进制):\n"); for(int i=0; i<sizeof(chinese)-1; i++) { printf("字节%d: 0x%02X ", i, (unsigned char)chinese[i]); } printf("\n\n内存存储值(十进制):\n"); for(int i=0; i<sizeof(chinese)-1; i++) { printf("字节%d: %3d ", i, (unsigned char)chinese[i]); } return 0; } ``` **典型输出**: ``` 内存存储值(十六进制): 字节0: 0xD6 字节1: 0xD0 字节2: 0xCE 字节3: 0xC4 内存存储值(十进制): 字节0: 214 字节1: 208 字节2: 206 字节3: 196 ``` > 说明:输出显示"中文"由4个字节组成(每个汉字2字节),数值均在GBK汉字编码范围内(161-254)[^4] #### 3. **编码系统的关键作用** - **GBK编码**:Windows简体中文系统默认编码,汉字范围: $$ \text{首字节} \in [0xA1, 0xFE], \quad \text{次字节} \in [0xA1, 0xFE] $$ - **UTF-8编码**:跨平台通用编码,汉字占3字节: - 首字节:`1110xxxx`(二进制前缀) - 后续字节:`10xxxxxx`(二进制前缀) - 示例:"中"的UTF-8编码为`0xE4 0xB8 0xAD`(十进制228, 184, 173) #### 4. **与ASCII字符的本质区别** | 特性 | ASCII字符 | 中文字符 | |--------------|-------------------|-------------------| | 所需字节数 | 1字节 | 2-4字节 | | 值范围 | 0-127 | 首字节≥161(GBK) | | 内存连续性 | 独立存储 | 必须连续存储 | | 解码依赖 | 无需额外信息 | 需知编码类型 | #### 5. **编程注意事项** 1. 使用`strlen()`计算汉字字符串长度时,返回的是**字节数**而非字符数 2. 截取子串需按完整汉字拆分,否则会导致乱码: ```c // 错误示例:截断汉字 char str[] = "中国"; str[2] = &#39;\0&#39;; // 将导致"中"字显示异常 ``` 3. 转换整数值时需用宽字符类型`wchar_t`: ```c #include <wchar.h> wchar_t wc = L&#39;中&#39;; printf("Unicode值: %d", wc); // 输出20013 ``` ### 总结 C语言通过连续的多字节序列存储汉字,每个字节存储的是特定编码系统(如GBK或UTF-8)定义的整数值。程序需识别这些数值组合才能正确显示汉字,这与ASCII字符的单字节存储有本质区别[^1][^4]。实际开发中应始终明确编码系统,并避免对汉字字节序列进行非常规操作。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值