数据在内存中的储存

一,数据类型的介绍

1.基本的内置类型:分为signed, unsigned(默认有符号数)

char:字符数据类型(1byte),有符号数的大小范围是-127~128,无符号数是0~255.

short:短整型(2byte),有符号数的大小范围是-2^15~2^15-1,无符号数是0~2^16-1.

int:整形(4byte),有符号数的大小范围是-2^31~2^31-1,无符号数是0~2^32-1.

long:长整形(4byte),有符号数的大小范围是-2^31~2^31-1,无符号数是0~2^32-1.

long long:更长整形(8byte),有符号数的大小范围是-2^63~2^63-1,无符号数是0~2^64-1.

float:单精度浮点数(4byte),有符号数的大小范围是-2^31~2^31-1,无符号数是0~2^32-1.

dounle:双精度浮点数(8byte),有符号数的大小范围是-2^63~2^63-1,无符号数是0~2^64-1.

类型的意义:类型的开辟决定了内存空间的大小,如何看待内存空间的大小

2.构造类型

数组类型,结构体类型(struct),枚举类型(enum),联合类型(union),自定义类型

3.指针类型 (int *)

   空类型(void):通常同于函数的返回类型,函数的参数,指针类型

二,整形在内存中的存储(存放的是补码

无符号数:是正数,补码就是原码;

有符号数:最高比特位为符号位,1表示负数,0表示整数;补码=(原码变成反码)+1;

在储存数据时,首先看类型(有无符号位),再看正负(最高比特位),最后储存数据;

在读取数据时,首先看类型(有无符号位),再看正负(最高比特位),最后读取数据;

三,大端小端的介绍

1,端模式:数据位保存在地址中,数据的位存在地址中;

2,端模式:数据的位保存在地址中,高位保存在高地址中;

从下面的程序判断是大端还是小端:


#include<stdio.h>
#include<windows.h>
int check_sys()
{
	int i = 1;
	return(*(char *)&i);//(char*)&i 强转成char*类型,再解引用就是首地址(低地址);
}
int main()
{
	int ret = check_sys();
	if (ret == 1)
	{
		printf("xiaoduan\n");
	}
	else{
		printf("daduan\n");
	}
	system("pause");
	return 0;
}

i (0000 0001) 强制转化为char *;低位是1,首地址是低地址,则是小端。

下面是整形在内存中储存的练习:

1,输出什么

#include<stdio.h>
int main()
{
    char a=-1;
    signed char b=-1;
    unsigned char c=-1;
    printf("a=%d,b=%d,c=%d",a,b,c);
    return 0;
}

首先看char a是有符号char类型,占1byte

a=-1;a的原码为1000 0001,但是在计算机内存补码,所以需要转化为补码:反码 1111 11110,补码=反码+1为 1111 1111

再看输出的a=%d,是有符号整形,这时需要填充(填充时看变量自身的类型,无符号数填充0,有符号数看最高符号位

填充后为1111 1111 1111 1111 1111 1111 1111 1111

输出有符号整形:补码-1变反码  1111 1111 1111 1111 1111 1111 1111 1110

                                                 1000 0000 0000 0000 0000 0000 0000 0001

则a=-1; 同理b=-1;


unsighed char c 是无符号char类型,占1byte;

c=-1,原码是1000 0001,在计算机存补码:1111 1111

输出的是c=%d,需要填充,这时变量c是无符号,则填充后为: 0000 0000 0000  0000  0000  0000 1111 1111

这时补码是个正数,原码=补码,则c=255;

2,把第一题代码不变,只改变输出,结果是什么

printf(“a=%u,b=%u,c=%u”,a,b,c);

a=%u输出的是无符号整形,也需要填充(变量a是有符号char)1111 1111 1111 1111 1111 1111 1111 1111

因为是无符号整形,则补码是正数,所以原码=补码,即输出结果为2^32-1;同理b=2^32-1;

c=%u输出的是无符号整形,需要填充(变量c是无符号)0000 0000 0000 0000 0000 0000 1111 1111,即输出c=2^8-1=255.

3,

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

char a是有符号char类型,a=-128 原码是1 1000 0000

                                                     反码是1  0111 1111

                                                      补码是1 1000 0000

由于char占1byte , 存在计算机的是1000 0000;

输出的a=%u,是无符号整形,需要填充(a变量是有符号) 1111 1111 1111 1111 1111 1111 1000 0000

输出无符号则说明补码是正数,所以原码=补码,输出a=2^31+2^30+.......+2^7=4294967168;

4,

#include<stdio.h>
int main()
{
    unsigned int i;
    for(i=9;i>=0;i++)
   {
     printf("%u\n",i);
   }
     return 0;
}

unsigned int是无符号整形,即是正数(i>=0),说明for条件永成立,当i=-1时,计算机会默认为无符号数

所以这个结果是死循环。

5,

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

当i=0时,a[0]=-1

当i=127时,a[127]=-1+(-127)=-128

-1在计算机存补码是1111 1111; -127  原码是 1111 1111,反码1000 0000,补码是1000 0001

1111 1111+1000 0001=1 1000 0000,则-1+(-127 )在计算机存1000 0000,即-128;

当i=128时,a[128]=-1+(-128)=127

-128 原码是1 1000 0000 ,反码是1 0111 1111,补码是1000 0000

1111 1111+1000 0000=1 0111 1111,则-1+(-128)在计算机存的是0111 1111,即127

当i=129时,a[129]=-1+(-129)=126

-129 的原码是1 1000 0001,反码是1 0111 1110,补码是1 0111 1111

1111 1111+1 0111 1111=10 0111 1110,则-1+(-129)在计算机存的是0111 1110,即126

像这样一直到结果为0结束。

从上面可以看出存的数有-1~-128,127~0;但是strlen不统计‘\0’,则共有255个空间。

6,

short num=32767;
short int a=num+1;
printf("%d\n",a);

32767化成二进制位0111 1111 1111 1111,加1->1000 0000 0000 0000

系统直接识别为最小值 ,不进行解码,结果为-32768.

三,浮点数在内存中的存储

1,浮点数在计算机内以二进制浮点数表示:(-1)^s*M*2^E

(-1)^s表示符号位,当s=0时,浮点数为正数,当s=1时,浮点数为负数;

M表示有效数字(小数点后面),大于等于1,小于2;

2^E表示指数位;

2,规定:对于32位的浮点数,最高的一位是符号位s,接着的八位是指数E,剩下的23位为有效数字M;

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

3,下面看一个例子:

#include<stdio.h>
#include<windows.h>
int main()
{ 
	int n = 9;
	float *p = (float *)&n;
	printf("n的值:%d\n", n);
	printf("*p的值:%f\n", *p);
	system("pause");
	return 0;
}

输出结果是:

为什么把9变成浮点数就成了0.000000呢?

首先把9写成二进制0000 0000 0000 0000 0000 0000 0000 1001

它的符号位是s=0,指数部分为E=0000  0000(-127),后23位为有效数字M=000 0000 0000 0000 0000 1001

则浮点数就可以写成二进制数(-1)^0*0.000 0000 0000 0000 0000 1001*2^(-127)=1.001*2^(-127),这个浮点数是接近0的正数,所以表示成十进制小数为0.000000






猜你喜欢

转载自blog.csdn.net/snowyuuu/article/details/80208934
今日推荐