概述
个人博客网址:https://ljsblog.com
数据存储(六)
C语言内置类型
char //字符类型
short //短整型类型
int //整型类型
long //长整型类型
float //单精度浮点类型
double //双精度浮点类型
类型的意义
- 决定数据在内存中所占的字节数
- 数据在内存中的存储方式
类型的基本归类
整型类型
char
char在内存中存储的是ASCII码,ASCII码是整数,所以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表示空类型(无类型)
通常用与函数返回类型,函数的参数,指针类型
整型在内存中的存储
只要是整数,内存中存储的都是二进制的补码
正数:
原码 反码 补码相同
负数:
原码(直接列出该数的二进 制) -> 反码(符号位不变,其他位按位取反) -> 补码(反码+1)
大端小端存储模式
大端存储模式,别名大端字节序存储模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中
小端存储模式,别名小端字节序存储模式,是指数据的低位保存在内存的低地址中,而数据的高位,保存在内存的高地址中
例
//判断当前机器是大端还是小端
#include <stdio.h>
int sys()
{
int a=1;
return *(char*)&a;
//指针类型决定了指针解引用操作能访问几个字节,char*访问一个字节
}
int main()
{
if(sys()==1)
{
printf("小端n");
}
else
{
printf("大端n");
}
return 0;
}
整型提升
C的整型算术运算总是至少以缺省整型类型的精度来进行的。为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为“整型提升”。
例题
例1
#include <stdio.h>
int main()
{
char a=-1;
//11111111
signed char b=-1;
//11111111
unsigned char c=-1;
//11111111
printf("a=%d,b=%d,c=%dn",a,b,c);
return 0;
}
//a=-1,b=-1,c=255
例2
#include <stdio.h>
int main()
{
char a=-128;
//原:10000000000000000000000010000000
//反:11111111111111111111111101111111
//补:11111111111111111111111110000000
//a为10000000
//%u为无符号整型数
//a整型提升后11111111111111111111111110000000
printf("%un",a);//4294967168
return 0;
}
例3
#include <stdio.h>
int main()
{
int i=-20;
//原:100000000000000000000000000010100
//反:111111111111111111111111111101011
//补:111111111111111111111111111101100
unsigned int j=10;
//000000000000000000000000000001010
//i+j为
//111111111111111111111111111110110
//%d有符号整数,所以将i+j的值格式化为有符号整数
//补:111111111111111111111111111110110
//反:111111111111111111111111111110101
//原:100000000000000000000000000001010
printf("%dn",i+j);//-10
return 0;
}
浮点数在内存中的存储
根据国际标准IEEE 754(IEEE二进位浮点数算术标准),任意一个二进制浮点数V可以表示成下面形式:
(-1)S*M*2E
(-1)^S表示符号位,当S为0,V为正数,当S为1,V为负数
M表有效数字,范围1<=M<2
2^E表指数位
举例:
9.0
1001.0
(-1)^S * M * 2^E
(-1)^0 * 1.001 * 2^3
IEEE 754规定:
对于32位的浮点数,最高1位是符号位S,接着8位是E,剩下23位为有效数字M
对于64位的浮点数,最高1位是符号位S,接着11位是E,剩下52位为有效数字M
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QAc2YRCL-1624105922553)(IEEE754.jpg)]
有效数字M:
IEEE 754规定,在计算机内部保存M时,默认这个数的第一位总是1,因此可以被舍去,只保存后面的xxxxxx分。比如保存1.01的时候,只保存01 ,等到读取的时候,再把第一位的1加上去。
指数E:
E为一个无符号整数这意味着,如果E为8位,它的取值范围为0-255;
如果E为11位,它的取值范围为0-2047
但科学计数法中的E是可以出现负数的,所以IEEE 754规定,存入内存时E的真实值必须再加上一个中间数,对于8位的E,这个中间数是127;
对于11位的E,这个中间数是1023,比如,2^-1的E是-1,所以保存成32位浮点数时,必须保存成-1+127=126,即01111110。
例:
#include <stdio.h>
int main()
{
float f=5.5;
//5.5
//101.1
//(-1)^0*1.011*2^2
//S=0,M=1.011,E=2
//0 10000001 01100000000000000000000
return 0;
}
指数E从内存中取出还可以在分成三种情况:
**E不全为0或不全为1:**即指数E的计算值减去127(或1023),得到真实值,再将有效数字M前加上第一位的1。
**E全为0:**浮点数的指数E等于-126(或者-1022)即为真实值,有效数字M不再加上第一位的1,而是还原为0.xxxxxx小数。这样做是为了表示±0,以及接近于0的很小的数字。
**E全为0:**表示±无穷大(正负取决于符号位s)。
例:
#include <stdio.h>
int main()
{
int n=9;
//00000000000000000000000000001001
float* p=(float*)&n;
printf("n的值为:%dn",n);//9
//0 00000000 00000000000000000001001
//(-1)^0*0.00000000000000000001001*2^-126
printf("*p的值为:%fn",*p);//0.000000
*p=9.0;
//1001.0
//(-1)^0*1.001*2^3
//0 10000010 00100000000000000000000
//1091567616
printf("n的值为:%dn",n);//1091567616
printf("*p的值为:%fn",*p);//9.000000
return 0;
}
/*结果为
n的值为:9
*p的值为:0.000000
n的值为:1091567616
*p的值为:9.000000
*/
最后
以上就是动听冥王星为你收集整理的C语言:数据存储数据存储(六)的全部内容,希望文章能够帮你解决C语言:数据存储数据存储(六)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复