C语言:数据存储

个人博客网址:https://ljsblog.com

数据存储(六)

C语言内置类型

char //字符类型
short //短整型类型
int //整型类型
long //长整型类型
float //单精度浮点类型
double //双精度浮点类型
类型的意义

  1. 决定数据在内存中所占的字节数
  2. 数据在内存中的存储方式

类型的基本归类

整型类型

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=%d\n",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("%u\n",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("%d\n",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的值为:%d\n",n);//9
    //0 00000000 00000000000000000001001
    //(-1)^0*0.00000000000000000001001*2^-126
    printf("*p的值为:%f\n",*p);//0.000000
    *p=9.0;
    //1001.0
    //(-1)^0*1.001*2^3
    //0 10000010 00100000000000000000000
    //1091567616
    printf("n的值为:%d\n",n);//1091567616
    printf("*p的值为:%f\n",*p);//9.000000
    return 0;
}
/*结果为
n的值为:9
*p的值为:0.000000
n的值为:1091567616
*p的值为:9.000000
*/
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值