1,数据类型的介绍
本章重点
1,数据类型的详细介绍
2,整形在内存中的存储:原码,反码,补码
3,大小端字节序介绍及判断
4,浮点型在内存中的存储解析
基本的内置类型:
char //字符数据类型
short //短整型
int //整形
long //长整型
long long //更长的整形
double //双精度浮点型
类型的意义:
1,使用这个类型开辟的空间大小(大小决定了使用范围)
2,如何看待内存空间的视角
1.1,类型的基本归类
整形家族:
char
unsigned char
signed char
short
unsigned short [int]
signed short [int]
int
unsigned int
signed int
long
unsigned long [int]
signed long [int]
浮点家族:
float
double
构造类型:
> 数组类型
> 结构体类型-struct
> 枚举类型-enum
> 联合类型-union
指针类型:
int *pi;
char *pc;
float *pf;
void *pv;
空类型:
void 表示空类型(无类型)
通常用于函数的返回类型,函数的参数,指针类型
2,整形在内存中的存储
一个变量的创建是要在内存中开辟空间的。空间的大小是根据不同类型而决定的
2.1,原码、反码、补码
1,计算机中的整数有三种2进制表示方法:原码,反码,补码。
2,三种表示方法均有符号位和数值位两部分,符号位都是用0表示正,用1表示负
3,正数的原,反,补码都相同。
值得一说的是负数:
负整数的三种表示方式各不相同
原码
直接将数值按照正负数的形式翻译成二进制就可以得到原码
反码
将原码的符号位不变,其它位依此按位取反就可以得到反码
补码
反码+1就得到补码
疑问:为什么对于整形来说:数据存放内存中其实存放的是补码。
在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;
同时,加法和减法也可以统一处理(CPU只有加法器)此外,补码和原码互相转换,其运算过程是相同的,不需要额外的硬件电路。
2.2,大小端介绍
什么是大端,小端:
大端(存储)模式,是指数据低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中;
小端(存储)模式,是指数据的低位保存在内存的低地址中,而数据的高位,保存在内存的高地址中;
1字节 = 8比特位
int 类型 4字节 = 32bit
short 类型 2字节 = 16bit
char 类型 1字节 = 8bit
列如:一个16bit的short型x,在内存中的地址为0x0010,x的值为0x1122,那么0x11为高字节,0x22为低字节。对于大端模式,就将0x11放在低地址中,即0x0010中,0x22就放在高地址中,即0x0011中,小端模式刚好相反。(这里说一下0x10,和0x11为地址,10是一个字节,11是它向后的一个字节)
关于大端小端的一道笔试题:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
//判断机器为大端还是小端机器:
//1,设一个值为1,然后取出它的第一个字节。
//2,1的原码是00 00 00 01
//3,01是低字节,而内存是从低到高开始存储的。
//4,根据概念:小端机器:低地址放低字节,高地址放高字节。大端机器则相反
//5,所以取出第一个字节的值判断它是1还是0,是1则是小段,是0则是大端。
int panduan() {
int i = 1;
return (*(char*)&i);
}
int main() {
if (panduan() == 1) {
printf("小端机器\n");
}
else {
printf("大端机器\n");
}
return 0;
}
3,浮点型在内存中的存储
3.2、浮点数存储规则
根据国际标准IEEE754,任意一个二进制浮点数V可以表示成下面的形式:
(-1)^S*M*2^E
(-1)^S表示符号位,当S=0,V为正数,当S=1,V为负数
M表示有效数字位,大于等于1,小于2
2^E表示指数位
4,一些问题:
1,当用%d打印浮点数时:
float a=7.5f;
如果用printf("%d",a);输出的是0。
但float型用%d输出是否一定是0呢,答案肯定不都是0;
为什么 7.5 用%d输出的是0?分析如下:
首先来了解下printf的输出格式,int 和 long int 都是32位的,用%d输出;float 、double都是%f输出,但 float 是32位的,double 是64位的,所以在参数传递的时候C语言统一将 float 类型数值传换为 double 类型再传入 printf 函数。如果是32位整型则输出格式为%lld。
下面来讲一下 float a=7.5f ; printf("%d",a)输出为0的情况:
%d只输出低32位的数据,并将这些32位二进制以十进制数输出,编译器首先将 7.5从float类型转换为double类型,7.5在内存中的存放方式是0x40f00000,转换成double类型在内存中的数据就是这个0x401e000000000000,这个内存数据可以很明显看出低32位全是0,而%d则只能截取到低32位,所以这个以%d输出7.5的数值当然是 0了。如大家不相信可以用%lld 输出看看,这个%lld就很读到低64位数据,读出的结果就是0x401e000000000000,在屏幕上看到一个很大的十进制数。