概述
目录
数据类型的介绍
类型的意义:
类型的基本归类
整形家族
字符型插曲
浮点数家族(实型)
C语言中表示小数的两种方式
构造类型(自定义类型)
指针类型
空类型(无具体类型)
整形在内存中的存储
原码反码与补码
补码思想
大端小端字节序
浮点型在内存中的存储
浮点数表示形式
举例说明:
IEEE 754规定浮点数存储方式
对于有效数字M规定
对于指数E规定
从内存中取出
经典案例
数据类型的介绍
前言:在创建一个变量或者常量时,必须要指定出相应的数据类型,否则无法给变量分配内存
- char:字符数据类型——1字节
- short:短整型——2字节
- int:整形——4字节
- long:长整型——4字节
- long long:更长得整形——8字节
- float:单精度浮点数——4字节
- double:双精度浮点数——8字节
类型的意义:
- 使用这个类型开辟内存空间的大小(大小决定了使用范围)
- 如何看待内存空间的视角
类型的基本归类
整形家族
char(字符型)
- 无符号字符型:unsigned char
- 有符号字符型:signed char
short(短整型)
- 无符号短整型:unsigned short
- 有符号短整型:signed short
int(整型)
- 无符号整型:unsigned short
- 有符号整型:signed short
long(长整型)
- 无符号长整型:unsigned long
- 有符号长整型:signed long
字符型插曲
作用:字符型变量用于显示单个字符
语法:char ch= 'a';
注意:
- 在显示字符型变量时,用单引号将字符括起来,不要用双引号
- 单引号内只能有一个字符,不能是字符串
- C和C++中字符型变量只占有一个字节
- 字符型变量并不是把字符本身放到内存中储存,而是将对应的ASCII码放入到储存单元
案例演示
#include <iostream>
using namespace std;
int main()
{
int a = 98;
int a1 = 'b';
char b = 98;
char b1 = 'b';
cout << "a的值为:" << a << endl;//98
cout << "a1的值为:" << a1 << endl;//98
cout << "b的值为:" << b << endl;//b
cout << "b1的值为:" << b1 << endl;//b
system("pause");
return 0;
}
注意:本质上字符的储存就是将字符对应的ASCII码存到内存中,若以int类型接收得到的就是int类型数据,若以char类型接收,得到的就是char类型数据
浮点数家族(实型)
单精度浮点型:float
双精度浮点型:double
C语言中表示小数的两种方式
- 直接用小数点表示:3.14
- 科学计数法表示:314e-2
构造类型(自定义类型)
数组类型
结构体类型 struct
枚举类型 enum
联合类型 union
指针类型
int* pi;
char* pc;
float* pf;
void* pv;
空类型(无具体类型)
void
函数返回类型:void test();
函数参数:void test(void);
无具体类型的指针:void* p;
注意:对于无具体类型的属性,任意类型的数据都可放入p但是不能用,使用时需对p进行强制转换为确定类型
#include <stdio.h>
void print(void) {
printf("hello");
}
void main() {
print();
}
整形在内存中的存储
数据在内存中以二进制的形式储存
原码反码与补码
对于整数来说,整数的二进制有3种表示形式:原码,反码,补码。
正整数:其原码,反码,补码相同
负整数:其原码,反码,补码要进行计算
机器数:一个数在计算机中的二进制表示形式,机器数带符号,正数在最高位放0,负数放1
真值:带符号位的机器数对应的真正数值
原码:符号位加上真值的绝对值
反码:正数反码为其本身,负数反码在原码的基础上符号位不变,逐位取反。
补码:正数补码为其本身,负数补码=反码+1.
eg:-10
- 原码:10000000000000000000000000001010
- 反码:11111111111111111111111111110101
- 补码:11111111111111111111111111110110
注意:整数在内存中储存的是其二进制的补码
原因:使用补码可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理(cpu只有加法器)此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。
补码的创建是针对负数的计算,正整数的原码,反码,补码都相同
补码思想
现在是9点,如果我想调到6点;
9 - 3 -> 6 往前拨3个小时——(-3为源码)
9 + 9 -> 6 往后拨9个小时——(9为补码)
这里称12为模,写作mod12; 称9是-3以12位模的补数,记作 -3≡+9(mod 12)
由于前面9和-3互为补数且是以12为模,此刻我们先抛开负数不提得到9+3=12(反正最后在给任意一个变量加上符号,这两个数便互为补码)
一个 N 位的二进制数,可表示的最大值是2^N-1;
假设存在 x+y = 2^N-1 --> x+y+1 = 2^N;
如果此时把2^N 当做模 --> -x(如今加上负号) 和 y+1 就互为补数;
而x+y = 2^N-1,2^N-1是一个 N 位的二进制数最大的数了(就是各位是1的数),如果x和y相加真要得到这个数那么就两个从各位逐个相加一位是1那么第二个数的该位必定是0,现在我们已经知道了x和y逐个位相反,然而-x与y+1为补码啊,那么由反码定义可知-x与y必为反码。
C语言中加上一个数就等于加上这个数的补数(本质:运算溢出情况)。
运算溢出(以char为例)
char类型一字节范围:-128——127;
注意:无符号char类型一字节范围:0——255;
运算相加减遵循顺序(本质:整形提升截取)
……-128——0——127——- -128——0——127……
大端小端字节序
触发条件:数据的大小高于1字节(地址管理的内存大小)
内存有低地址和高地址之分
高字节序与低字节序
eg:1234——字节序从左到右逐渐降低
大端字节序:把数据低位字节序的内容存放在高地址出,把数据高字节序内容存放在低地址处
小端字节序:把数据高位字节序的内容存放在高地址出,把数据低字节序内容存放在低地址处
例子:00000001
不管是大端还是小端字节序,最后都能将其还原成00000001(只不过是存放方式的问题)
浮点型在内存中的存储
浮点数家族包括:float,double,long double类型。
浮点数表示范围:float.h中定义
浮点数的两种写法
- 一般写法:3.14159
- 科学计数法:1E10(1.0*10^10)
注意:浮点型指针解引用是向内存中拿一个浮点类型的数
#include <stdio.h>
void main() {
int n = 9;
float* pf =(float*) &n;
printf("n=%dn", n);//9
printf("pf=%fn", *pf);//浮点数视角取0.000000
*pf = 9.0;
printf("n=%dn", n);//整数视角取1091567516
printf("pf=%fn", *pf);//浮点数视角取9.000000
}
由此观之:浮点数和整数在内存中的存储方式一定有区别
浮点数表示形式
根据IEEE(电器和电子工程协会)754,任意一个二进制浮点数V可以表示成下面的形式
举例说明:
浮点数:5.5——10进制
转化为二进制
5:101
0.5:2^-1
得到:101.1——>分别对应2^2,2^1,2^0,2^-1
推出:1.011*2^2——>(-1)*0*1.011*2^2
其中:S=0,M=1.011,E=2
由此观之,只要有S、M、E储存好,那么这个浮点数也就储存好了
IEEE 754规定浮点数存储方式
对于float(32位)浮点数,最高的一位是符号位S,接着的8位是指数E,剩下的23位是有效数字M
对于double(64位)浮点数,最高的一位是符号位S,接着11位是指数E,剩下的52位是有效数字M
对于有效数字M规定
对于有效数字M,因为0=<M<2,因此M可以写成1.xxxxx,因为1是确定的,在IEEE 754规定,在计算机内部保存M时,默认这个数的第一位总是1,因此可以被舍去,只保留后面的小数部分,等到读取的时候再把这个1加上,并且,小数点后位如果没填满23/52位,则之后用0填补。
这样做的目的是:节省一位有效数字,以32位浮点数为例,留给M的只有23位,将第一位的1舍弃以后,等于可以保存24位有效数字
对于指数E规定
如果E的数字没有填满8/11位则前面补0(反正没符号)
因此,对于(-1)*0*1.011*2^2——S=0,M=1.011,E=2
在计算机存储为:[0](0) [100 0000 1](2+127) [011 0000 0000 0000 0000 0000](011)
0100 0000 1011 0000 0000 0000 0000 0000——5.5
从内存中取出
E不全为0或E不全为1
指数E的真实值减去127/1023,得到真实值,再将有效数字M前加上第一位的1
E全为0
1.xxxxx*2^-127——0.1xxxxx*2^-126——0.xxxxx*2^-126
E全为1
这时,如果有效数字M全为0,表示+/-无穷大(正负取决于符号位S)
经典案例
#include <stdio.h>
void main() {
int n = 9;
float* pf =(float*) &n;
printf("n=%dn", n);//9
printf("pf=%fn", *pf);//浮点数视角取0.000000
*pf = 9.0;
printf("n=%dn", n);//整数视角取1091567516
printf("pf=%fn", *pf);//浮点数视角取9.000000
}
理解:
n=9:00000000000000000000000000001001
以整形打印就是9(原码、反码、补码均一样)
以浮点数形式拿出
[0](S) [00000000](E) [00000000000000000001001](M)
E全为0——0.00000000000000000001001*2^(1-127)约等于0
*pf=9.0: 1001.0——1.001*2^3——(-1)*0*1.001*2^3
[0](S) [10000010](130——E) [00100000000000000000000](M)
01000001000100000000000000000000
以整数形式拿出(其为补码,拿出原码——就是本身)
以浮点数形式拿出——9.0
最后
以上就是傻傻戒指为你收集整理的C语言之数据的储存数据类型的介绍类型的意义:类型的基本归类整形在内存中的存储大端小端字节序浮点型在内存中的存储的全部内容,希望文章能够帮你解决C语言之数据的储存数据类型的介绍类型的意义:类型的基本归类整形在内存中的存储大端小端字节序浮点型在内存中的存储所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复