C语言学习——数据在内存中的存储

本文详细探讨C语言中整型(char, short, int, long, long long)和浮点型(float, double)的数据类型定义、内存存储原理,包括原码、反码、补码及数值范围,并通过实例解析整型提升与截断现象。
摘要由CSDN通过智能技术生成

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

主要学习整型与浮点型数据在内存中的存储方式以及相应代码分析。

一、C语言数据类型

C语言主要有四种类型:
1.基本类型:

(1)整型:

①字符整型char
②短整型short
③整型int
④长整型long
⑤更长整型long long
注意:整型数据每个类型都有signed、unsigned之分
而未标明有无符号时,默认为有符号

(2)浮点型:

①单精度浮点型float
②双精度浮点型double

2.构造类型:

(1)数组类型
(2)结构体类型:关键字struct
(3)枚举类型:关键字enum
(4)共用体类型:关键字union

3.指针类型
4.空类型:void

为何要使用数据类型?

1.数据类型决定了数据在内存中存储的方式与大小;
2.数据类型决定了看待内存空间的角度;

二、数据在内存的存储

这里主要探讨整型与浮点型数据在内存中的存储方式。

1.整型数据

(1)前提

在学习整型数据在内存的存储时,我们要先明确以下几点:
第一,整型数据有三种表达形式:原码、反码、补码;
第二,三种表现形式都由符号位与数值位组成,符号位0代表正数数,符号位1代表负数;
第三,正数原码、反码、补码相同;
第四,内存中存储的整型数据的二进制补码;

(2)原码

原码就是将一个int数据展开为32位的二进制数。
例如:
-5 ——>10000000 00000000 00000000 00000101
5 ——> 00000000 00000000 00000000 00000101

(3)反码

反码就是对原码除符号位之外的每一位按位取反得来的。
例如:
-5——>11111111 11111111 11111111 11111010
5 ——>00000000 00000000 00000000 00000101

(4)补码

补码就是反码加一
例如:
-5——>11111111 11111111 11111111 11111011
5 ——>00000000 00000000 00000000 00000101

(5)重点

①char类型的数值范围

char类型只占一个字节(8个bit)
unsigned char:0-255

也就是11111111

signed char:-128-127

其取值变化范围为:
在这里插入图片描述

②整型提升与截断

什么是整型提升?

整型提升就是在进行整型运算时,将字节数小于int字节的数据类型(short或者char)转化为整型(int)类型。

为什么要进行整型提升?

因为在计算机中运算都是有CPU中的运算器ALU完成的,而ALU在设计时被规定,其操作对象的大小至少是int类型;与此同时,ALU的操作对象是存储在内存中的寄存器上,而计算机的通用寄存器的字节大小是与算术逻辑单元(ALU)保持一致的。所以这就要求对于short或者char类型的数据进行整型运算时,要先将它们整型提升为int。

如何进行整型提示?

对于有符号的数据类型,我们需要在其二进制补码前补符号位,直到将8个bit位的char数据补成32个bit位,或者16个bit为的short类型补到32个bit位;

对于无符号的数据类型,我们需要在其二进制数前补0,直至补齐32个bit位;

截断:

截断就是在将整型数据存入short或者char类型变量中时,只存放16、8个bit位,去除其它位。注意所保留的位数是从二进制的数值低位开始数。

(6)例题

	char a = 255;
	unsigned char b = -1;

	printf("a = %u\n", a);
	printf("b = %u\n", b);

分析过程:
第一行:255的二进制原码(补码)1111 1111,变量a是有符号的char类型,将255的补码存入a中。因为a有符号,故第一个1是符号位,此时a代表的数值要进行补码到原码的转化,即1000 0001,所以a中数值是-1;
第二行:-1的二进制补码是1111 1111,变量b是无符号的char类型。所以求a中数值时,八个bit位都是数值位,而且没有原码补码的区分,故b中数值是255;
第三行:打印涉及整形运算,先将a进行整型提升,a中存放1111 1111,且a是有符号的,故在高位补符号位1,得到11111111 11111111 11111111 11111111,又以无符号形式打印,所以该二进制没有原码补码的区分且全是数值位,打印得到极大的数:4294967295;
第四行:将b进行整型提升,b中存放1111 1111,且b无符号,直接在高位补0,得到00000000 00000000 00000000 11111111,又以无符号形式打印,所以该二进制位都是数值位,且原码补码不区分,打印得到:255
结果:
在这里插入图片描述

	char a = 255;
	unsigned char b = -1;

	printf("a = %d\n", a);
	printf("b = %d\n", b);

分析:
第一行:同上;
第二行:同上;
第三行:a进行整型提升,且a是有符号的,故在高位补符号位,得到11111111 11111111 11111111 11111111,以有符号的形式打印,因为首位是1,所以是负数,要将二进制补码转为原码,得到10000000 00000000 00000000 00000001,所以打印得到:-1;
第四行:b进行整型提升,且b无符号,故在高位补0,得到00000000 00000000 00000000 11111111。以有符号的形式打印,因为首位是0,所以是正数,原码补码一致,打印得到:255;
结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值