【C语言进阶】一、数据的存储

1. long double

2. 空类型:void表示空类型(无类型),通常应用于函数的返回类型、函数的参数、指针类型。

void test(void)
{

}

int main()
{
    return 0;
}

其中 void test(void) 中第一个 void 值该函数无返回值,括号中的 void 指的是不需要传参。

3.为什么数据在内存中是补码?

        a、CPU中只有加法器;

        b、减法就是加一个负值

        c、原码计算:1-1

              1:                  00000000000000000000000000000001

              -1:                 10000000000000000000000000000001

              和:              10000000000000000000000000000010

               但此时和为-2,结果错误。

        d、补码计算:1-1

              1:                  00000000000000000000000000000001

              -1:                 1111111111111111111111111111111111111(补码)

              和:             100000000000000000000000000000000(和前边多了一位)

               此时和的第一位会被丢弃(因为存储的是32位),和是0。

        e、还与硬件有关,暂未深入研究

4.无符号数的打印是用%u

5.大端和小端(大小端字节序存储)

        首先:如,0x11223344 这个数字,44是最低位的数字,11是最高位的数字。

        a、大端:是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中,

        b、小端:是指数据的低位保存在内存的低地址中,而数据的高位,,保存在内存的高地址中。

        c、使用程序来判断是大端还是小端

#include <stdio>

int main()
{
    int a=1;
    char* p=(char*)&a;

    if(*p==1)
    {
        printf("小端 \n");
    }
    else
    {
        printf("大端\n");
    }
}

 几道例题

例1、

#include <stdio.h> 
int main() 
{ 
 char a = -128; 
 printf("%u\n",a); 
 return 0; 
}

此代码输出的数是一个很大的数;

因为:首先将-128这个整形数字放入char类型的变量中去

                10000000000000000000000010000000(-128的原码)

                1111111111111111111111111111011111111(反码)

                111111111111111111111111111110000000(补码)

                10000000(此时发生截断)

                %u打印无符号整数,打印时又会发生整形提升;

                111111111111111111111111111110000000

                 因为打印的是无符号数,所以原码反码和补码相同,故,上边的数就是打印出来的数

 例2、

#include <stdio.h> 
int main() 
{ 
 char a = 128; 
 printf("%u\n",a); 
 return 0; 
}

 128的原、反、补码相同,是:

                10000000000000000000000010000000

                存储时发生截断,

                100000000

                打印时整型提升

                111111111111111111111111111110000000

                所以答案与上边一样

 例3、

#include <stdio.h>

int main()
{
    unsigned int i; 
    for(i = 9; i >= 0; i--) 
    { 
        printf("%u\n",i); 
    }
    return 0;
}

 此代码是一个死循环;

                因为  unsigned int  类型没有小于 0 的数,当  i = 0  时, i--  又变成了无符号整形中的最大值

例4、

int main() 
{ 
 char a[1000]; 
 int i; 
 for(i=0; i<1000; i++) 
 { 
 a[i] = -1-i; 
 } 
 printf("%d",strlen(a)); 
 return 0; 
}

 此时的  char  是  signed char  ,取值范围是 -128~127,而for循环中从 -1 到 -128时正常运行,当 i = 129 时,此时存在char中的值是 127 ,并且在 char 中存储的数字会依次减小,当 i = 256时,char 中存储的数据为 0 。

例5、

#include <stdio.h> 
unsigned char i = 0; 
int main() 
{ 
 for(i = 0;i<=255;i++) 
 { 
 printf("hello world\n"); 
 } 
 return 0; 
}

 此时是死循环

6.浮点数在内存中的存储

        a、两个文件:float.h 定义了浮点数的取值范围的相关信息;

                                limits.h 定义了整型数的取值范围的相关信息。

        b、存储规则:

                        任意一个浮点数 V 都可存储为:

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

(-1)^S  表示符号位,当S=0,V 是正数,当S=1,V 是负数

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

2^E 表示指数位

例:

5.5

101.1                                             (二进制表示)

(-1)^0 * 1.011 * 2^2                      (使用上述规则表示)

        c、在内存中的存储

                浮点数存储存的是S、M、E三个值;

float:

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

 

double:

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

              

注:

        a、M 是一个二进制的数,所以它的大小只可能在 1 ~ 2 之间,所以在存储 M 时,只存小数点后边的数字,读取的时候再把前边的 1 加上去;

        b、

        (1)E的存入,E 是一个无符号数,8位(float)时,取值范围是0~255;11位(double)时,取值范围是0~2047,但是科学计数法中的E可能是负数,所以在存入时, E 真实值需要加一个中间数,即8位(float)中间值  127  ,11位(double)中间值  1023  。

        (2)E的读取,当E不全为0或不全为1时,E的计算值(内存中的值)减去127(或1023),得到真实值,再将有效数字M前加上第一位的1;E全为0时,E=1-127(或1-1023);E全为1时,表示的数是正负无穷大。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值