数据的存储

本文详细介绍了C语言中的基本数据类型,包括整型家族、浮点型以及构造类型。重点讨论了整型在内存中的存储方式,如原码、反码、补码的概念,以及大小端存储模式的区别。同时,提供了判断系统大小端的代码示例,并通过练习题解析了不同类型变量在内存中的表示和截断情况。此外,还概述了浮点数在内存中的表示遵循的IEEE754标准。
摘要由CSDN通过智能技术生成
    • 数据类型:

char(字符型)

short(短整型)

int (整型)

long (长整型)

long long(更长的整型)

float(单精度浮点型)

double(双精度浮点型)

    • 类型的基本归类

整型家族

char (字符在存储时存储的是ASCII码值)

unsigned char signed char

(signed char 和char 并不一定相等,取决于编译器)

short

unsigned short signed short

int

unsigned int

signed int

long

unsigned long

signed long

浮点型家族

float

double

构造类型

数组类型

结构体类型

枚举类型

联合类型

指针类型:

int*p

char*p

float*p

void*p

空类型:

void表示空类型(无类型)

(函数的返回类型,函数参数,指针类型)

    • 整型在内存中的存储:

整数有3种二进制表示方法,即原码、反码、补码。

三种表示方法都分为符号位和数值位两部分,第一位为符号位,剩余为数值位

符号位中,0表示正,1表示负

正数的原码、反码、补码都相同。

负数的原码、反码、补码则不同:

原码:直接将数值按照正负数形式转换为二进制

反码:原码的符号位不变,其他位依次按位取反

补码:反码+1

(将补码的符号位不变,其他位依次按位取反,并+1后得到原码)

对于整型来说,数据存放内存中其实存放的是补码(16进制存放)

然而在观察内存时,a和b在内存中的存储又与我们想象的不太一样

    • 大小端

大端存储模式:数据的低位保存在内存的高地址中,而数据的高位保存在低地址中

小端存储模式:数据的低位保存在内存的低地址中,而数据的高位保存在高地址中

(上内存中的存储模式为小端存储,而我们所分析的是大端存储)

    • 判断大小端:

设计一个函数用于判断大小端

int a=1;若为大端模式,则在内存中的存储应为0x 00 00 00 01

若为小端模式,则在内存中的存储应为0x 01 00 00 00

所以只需取出第一个字节的内容,看是否等于1,若为1则是小端存储,否则即为大端存储

#include<stdio.h>
//判断大小端
int check()
{
    int a = 1;
    //小端:0x 01 00 00 00
    //大端:0x 00 00 00 01
    return *((char*)&a);
}
int main()
{
    int ret=check();
    if (ret == 1)
        printf("小端\n");
    else
        printf("大端\n");
}

    • 练习1

以下程序输出什么

#include <stdio.h>
int main()
{
char a= -1;
//10000000000000000000000000000001-原码
//11111111111111111111111111111111-补码
//由于a为char类型,所以在内存中存储时会发生截断,故存储内容为
//11111111
//11111111111111111111111111111111-提升后的补码
//10000000000000000000000000000001-提升后的原码
//输出-1
signed char b=-1;
//10000000000000000000000000000001-原码
//11111111111111111111111111111111-补码
//由于b为signed char类型,所以在内存中存储时会发生截断,故存储内容为
//11111111
//11111111111111111111111111111111-提升后的补码
//10000000000000000000000000000001-提升后的原码
//输出-1
unsigned char c=-1;
//10000000000000000000000000000001-原码
//11111111111111111111111111111111-补码
//由于c为unsigned char类型,所以在内存中存储时会发生截断,故存储内容为
//11111111
//由于c为unsigned char类型,所以提升时直接在前面补0
//00000000000000000000000011111111-提升后的补码
//00000000000000000000000011111111-提升后的原码
//输出255
printf("a=%d,b=%d,c=%d",a,b,c);
//%d为打印有符号的整数,而a,b,c都为char类型,所以需要提升
//%u为打印有符号的整数
return 0;
}
    • 练习2

以下程序输出什么

#include<stdio.h>
int main()
{
    char a[1000];
    int i;
    for(i=0; i<1000; i++)
    {
        a[i] = -1-i;
        //-1 -2 -3...-128 127 126...3 2 1 0 -1..
    }
    printf("%d",strlen(a));
    //strlen遇'\0'停止,即计算0之前的字符串长度
    //128+127=255
    return 0;
}
    • 浮点型在内存中的存储

根据国际标准IEEE754,任意一个二进制浮点数V都可以表示成:

(-1)^S*M*2^E

(-1)^S表示符号位,当S=0,V为整数;当S=1,V为负数。

M表示有效数字,大于等于1,小于2。

2^E表示指数位

例如:

5.0=101.0=1.01*2^2

S=0,M=1.01,E=2

IEEE 754规定:

对于32位的浮点数,最高的1位是符号位S,接着的8位是指数E,剩下的23位为有效数字M

对于64位的浮点数,最高的1位是符号位S,接着的11位是指数E,剩下的52位为有效数字M

对于有效数字M:

在计算机内部保存M时,默认这个数的第一位总是1,因此可以被舍去,只保存后面的数字

等到读取的时候再加上1,这样可以节省1位有效数字

对于有效数字E:

E为一个无符号整数,如果E为8位,取值范围是0~255,如果E为11位,取值范围是0~2047,而科学计数法中,指数可以为负数,所以规定一个中间数来区分正负,对于8位的E,中间数为127,对于11位,中间数为1023。比如2^10的E为10,所以保存成32位浮点数时保存成10+127=137,即10001001。

当E不全为0或不全为1时:

指数E的计算值减去127或1023,得到真实值,再将有效数字M前加上第一位的1

当E全为0时:

浮点数的指数E等于1-127(或1-1023)即为真实值,有效数字M不再加上第一位的1,而是还原为0.xxxxxx的小数。

当E全为1时:

如果有效数字M全为0,则表示正负无穷大(正负去决于符号位S);

举例:

#include <stdio.h>
int main()
{
    int n = 9;
    //在内存中以补码的形式存放
    //00000000000000000000000000001001
    float* pFloat = (float*)&n;
    //以浮点数的角度,n的存储内容为
    //0 00000000 00000000000000000001001
    //E全为0,有效数字M不再加上第一位,E为-126
    //(-1)^0*0.00000000000000000001001*2^-126(该数无限接近于0)
    printf("n的值为:%d\n", n);//9
    printf("*pFloat的值为:%f\n", *pFloat);//0.000000000
    *pFloat = 9.0;
    //9.0=1001.0=1.001*2^3
    //在内存中的存储形式为
    //0 10000010 001000000000000000000000
    //以整型的角度,存储的内容则为补码
    //010000010001000000000000000000000=1091567616
    printf("num的值为:%d\n", n);//1091567616
    printf("*pFloat的值为:%f\n", *pFloat);//9.0
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值