整形数据在内存中的存储(1)

目录

1.数据的类型

2.整形在内存中的存储

2.1 原码 反码 补码

2.2 大端小端

3.存储实例

3.1整形范围

3.2 有符号整形 无符号整形 

3.3数据存储的特点


通过前几天对内存中内数据的存储的学习,特地总结一下。

1.数据的类型

整形
     char           字符数据类型     占1个字节
     short         短整型                占2个字节
     int             整形                    占4个字节
     long          长整型                 占4或8个字节
     long long   更长的整形         占8个字节
浮点型
     float           单精度浮点数     占4个字节
    double       双精度浮点数     占8个字节 

2.整形在内存中的存储

       我们知道变量的创建是要在内存中开辟地址空间的,而空间的大小是由不同的数据类型决定的。那数据在内存中又是如何存储的呢?

     2.1 原码 反码 补码

     我们知道整形在内存中是以补码(二进制)形式存储的

      正数的原码,反码,补码都一样。

例如 int a = 1           原码 00000000 00000000 00000000 00000001

                                反码 00000000 00000000 00000000 00000001

                                补码 00000000 00000000 00000000 00000001

      负数的补码则要经过除除符号位外全部取反得到反码,再在反码的基础上加1,最终得到补码。

l例如int a = -1         原码 10000000 00000000 00000000 00000001

                               反码 111111111 111111111 111111111 111111110

                               补码 111111111 111111111 111111111 111111111

我们进入到内存中去看,如果你用的是VS编译器,可根据下面的步骤看:


#include<stdio.h>
int main() {

	int a = 10;
	int b = 20;

	return 0;
}

 上面是一段简单的代码,我们进行调试。按ctrl+F11或F11进入调试。

然后继续 ctrl+F11或F11,直到箭头到达return 0。

再按下面的操作找到内存

再分别输入&a按回车键,&b按回车键 

 VS内存中的数据是以16进制展现给我们。

我们不难得出a = 10 10的16进制为  00 00 00 0a

                      b = 20 20的16进制为  00 00 00 14

通过与上面内存中展示出来的相比较,老感觉顺序很别扭。通过查询,发现这与大端小端有关。

2.2 大端小端

 什么是大端小端?
 大端 数据的字节序在内存中是 低位存放在高地址中,高位存放在低地址中 
 小端 数据在内存中在内存中是 低位存放在低地址中,高位存放在高地址中

根据网上资料,大端存储还是小端存储,这与编译器有关,如果想知道我们使用的编译器是以大端存储还是小端存储,我们可以写一段程序来实现。这里我选择用1,也可以用其他数。

                           低             高
     若小端           01 00 00 00 
     若大端           00 00 00 01

#include<stdio.h>
int main() {

	int a = 1;

	char* p = &a;
	if (*p == 1) printf("小端");
	else printf("大端");

	return 0;
}

3.存储实例

我们举一些代码例子,以便更深入的理解。

3.1整形范围

    通过代码查询变量取值范围

#include<stdio.h>
#include<limits.h>
int main() {
	
	INT_MAX;

	return 0;
}

鼠标指到INT_MAX,右键点击,再点击转到定义。 

3.2 有符号整形 无符号整形 

int a = 1;   有符号整形

unsigned int a = 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;
}

我的理解:

//#include<stdio.h>
//int main() {
//
//                          //因为-1是一个整形数int    放在char里会发生截断      
//                          //11111111 11111111 11111111 11111111  (-1的补码)
//						    //11111111 (对补码进行截断,截断了后八位)
//	char a = -1;
//	//11111111
//
//	signed char b = -1;
//	//11111111
//
//	unsigned  char c = -1;
//	//无符号位时,截断后高位补0
//	//11111111
//	//00000000 00000000 00000000 11111111  高位补0后的值 255  最高位为0,表示正值 即无符号
//	printf("%u %d %d",a,b,c);  //最终输出 -1 -1 255
//
//
//	return 0;
//}

下面两段代码输出什么?

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



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

%u为打印整形 无符号输出十进制数

 原因:

//#include<stdio.h>
//int main() {
//
//char a = -128;
10000000 00000000 00000000 10000000  -128的原码
11111111 11111111 11111111 01111111  -128的反码
11111111 11111111 11111111 10000000  -128的补码
10000000     因为 a为char型  所以对-128的补码进行截断
11111111 11111111 11111111 10000000  整形提升 由于符号位为1 故高位补位时全补1 
//                                       整形提升 高位补0还是1 取决于截断后的最高符号位 
//
//char a1 = 128;
//printf("%u %u",a,a1);    //%u  打印整形(故需要整形提升) 无符号输出十进制数
//	return 0;
//}

3.3数据存储的特点

我们试着运行下面几段代码:

#include<stdio.h>
int main(){

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

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

一般情况下,我们会以为第一个代码从9输出到0就截止,第二个打印256个hello world就停了,可真的是这样吗?

通过运行

 通过运行,居然是个死循环。

为了便于观察,我们加点代码:

#include<stdio.h>
#include<windows.h>
int main() {
	unsigned int i;
	for (i = 9; i >= 0;i--) {

		printf("%u\n",i);
      Sleep(1000);

	}
return 0;
}

 运行如下:

从9到0我们不难理解,可0之后又变成4294967295这个数又是咋来的呢?

 通过观察,我们知道变量 i 是一个无符号整形,即i的取值范围为0到一个很大的数,故i永远也不会取负数,所以会死循环,当减为-1时

      原码 10000000 00000000 00000000 00000001

      反码 111111111 111111111 111111111 111111110

      补码 111111111 111111111 111111111 111111111

又因为%u为输出无符号十进制数,所以

4294967295 就是 111111111 111111111 111111111 111111111

若把%u换成%d呢

0后又跟-1?

这是因为%d输出有符号十进制数,故 此时111111111 111111111 111111111 111111111为-1的补码了

  补码 111111111 111111111 111111111 111111111

  反码 111111111 111111111 111111111 111111110

  原码 10000000 00000000 00000000 00000001

通过以上,我们得出一个规律:循环

 如上图所示,char型无符号时,0减1的值为255,255加1的值为0 即0---255为一个循环。

                    char型有符号时,127加1的值为-128,-128减1的值为127 即-128---127为一个循环。

おすすめ

転載: blog.csdn.net/m0_73381672/article/details/131013016