数据的存储(上篇)

本文详细介绍了计算机中各种数据类型的字节大小、意义、存储方式,包括整型、浮点型和构造类型。重点讲解了整型数据在内存中以补码形式存储的原因,以及如何通过原、反、补码进行计算。还涉及到了数据的存储顺序(大小端)以及如何判断机器的字节序。最后,文章提供了若干编程题目以加深理解。
摘要由CSDN通过智能技术生成

目录

编辑各类型的所占字节大小:>

编辑类型意义:>

​编辑类型的基本归类 : >

编辑整型数据在内存中存储的方式 : >

例子:> 

原、反、补码计算小技巧:>

         数据的存储顺序(大小端):>

 判断机器的大小端顺序:>

 题目练习:>

         2.

 3.

 4.​

5.​

6.​

7.​​​​​​​​

各类型的所占字节大小:>

//各类型的所占字节大小

#include<stdio.h>

int main() {

	printf(" =%u\n", sizeof(char));
	printf(" =%u\n", sizeof(short));
	printf(" =%u\n", sizeof(int));
	printf(" =%u\n", sizeof(long));
	printf(" =%u\n", sizeof(long long));
	printf(" =%u\n", sizeof(float));
	printf(" =%u\n", sizeof(double));

	return 0;
}

 具体大小如下:>

 

类型意义:>

计算机是一个为我们所用的工具,是用来帮我们完成一些任务,而这些解决方法都是由人为的方式来定义的,当大量的数据需要被使用的时候,为了节省空间、提高效率和简化代码,类型由此而产生。

例如:>

int a;                                //这里的两个数据定义的类型不一样

float f;                             //计算机为此而开辟的空间也由定义的类型不一样而不一样

                                        //当要使用的时候也会由此直接找出

这时我们可以总结出以下结论 : >

                                1.使用这个类型开辟内存空间的大小(大小决定了使用范围)

                                2.定义了如何看待内存空间的视角 

基于以上两点可以知道,我们需要什么类型就定义什么类型,需要什么类型去接收就用什么类型去接收,否则会出现错误.

类型的基本归类 : >

整型家族:

char                                //char 在内存中的数值本质上是以 ASCII 码值存放的

        unsigned char

       unsigned char

short

        unsigned short

        signed short

int

        unsigned int

        signed int

long

        unsigned long(int)                //通常 int 可以省略

        signed long(int)

long long 

        unsigned long long(int)        //C99及之后支持

        signed long long(int)

一般情况下我们定义整型会直接 int 而不是用 signed int .因为通常会把 int 默认为 signed int  即 int  == > signed int  同理可以知道其他的类型也是如此.

不过特别注意的是 char 到底是 unsigned char 还是 unsigned char C语言未定义的,也就是说它 char 是什么类型取决于编译器是怎么样定义的.

假如有一个 int a = 0;

a是一个整型,有符号的整型,一个整型占4个字节==32bit位

00000000 00000000 00000000 00000000 共32bit

 

 

因此当我们表示一个数值的时候假如没有负值 : 比如体重、身高就没有负值,我们使用 unsigned 更加合理 ;又比如温度这类有负值的数据就应该使用 signed 类型了.

浮点型家族:>

float                                      //精度较低 小数点后面 6~7位

double                                 //精度高      小数点后面 15~16位

 关于浮点型因为复杂程度较高,具体留到下一次再讲.

构造类型:>

为自定义类型---我们可以自己创建出新的类型

> 数组类型

例        : > int arr[10];  //去掉数组名  这里的类型为 int [10];

同样的 : > int arr[7]; //去掉数组名  这里的类型为 int [7];

>结构体类型 struct

>枚举类型     enum

>联合体类型 union

整型数据在内存中存储的方式 : >

//整数的2进制有三种形式:>
// 1.正整数,原码、反码、补码相同
// 2.负整数,原码、反码、补码需要计算
// 原码:直接通过正负的形式写出的二进制序列就是原码
// 反码:原码的符号位不变,其他按位取反得到的就是反码
// 补码:反码+1就是补码

//例如
int main()
{
    int a = 20;
    //20
    //00000000 00000000 00000000 00010100 -- 原码
    //     00              00             00             14   
    //00000000 00000000 00000000 00010100 -- 反码
    //00000000 00000000 00000000 00010100 -- 补码
    int b = -10;
    //10000000 00000000 00000000 00001010 -- 原码
    //     0x80          00             00              0a
    //11111111 11111111 11111111 11110101 -- 反码
    //     0xff         ff              ff              f5
    //11111111 11111111 11111111 11110110 -- 补码
    //     0xff         ff              ff              f6
    return 0;

}

例如 : > 

通过以上两个 整型 数据在内存中的存储,我们可以知道它们在内存中存储的方式是以 16 进制的方式展现(便于节省空间),以 二进制方式存储 的,且是以 数据的补码 进行存储的.

二进制方式存储!!!   二进制方式存储!!!   二进制方式存储!!! 不要误以为是16进制!!!

为什么要以补码的形式进行存储:>

在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;

同时,加法和减法也可以统一处理(需知道 CPU只有加法器 ) 此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。

例子:> 

1-1 的运算

错误演示:>

c

 正确的演示:>

这就是前人的智慧啊!!! 

 原、反、补码计算小技巧:>

 数据的存储顺序(大小端):>

 判断机器的大小端顺序:>

#include<stdio.h>

int main() {

	int a = 1;
	if ( ( * (char*)&a ) == 1)
	{
		printf("小端字节序存储\n");
	}
	else
	{
		printf("大端字节序存储\n");
	}

	return 0;
}

这里是 Visual Studio 编译器下的结果:>

 题目练习:>

//1.
//输出什么?                //注意整型提升、数据溢出、各类型的存储范围
#include <stdio.h>
int main()
{
	char a = -1;
	signed char b = -1;
	unsigned char c = -1;
	printf("a=%d,b=%d,c=%d\n", a, b, c);
	return 0;
}

结果 

 2.

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

​//10000000 00000000 00000000 10000000    原码
//11111111 11111111 11111111 01111111    反码
//11111111 11111111 11111111 10000000    补码
//10000000 --截断
//11111111 11111111 11111111 10000000 -- 整型提升

//因为 %u 是无符号整型,所以原码、反码、补码都相同,
//于是 11111111 11111111 11111111 10000000 便是它打印出来的值

这是一个非常大的值!!! 

 3.

//3.
#include <stdio.h>
int main()
{
    char a = 128;
    printf("%u\n",a);
//00000000 00000000 00000000 10000000
//10000000 -- a

//10000000    -- 因为  char 是有符号数,因此在整型时候就会补1
//11111111 11111111 11111111 10000000


    printf("%d\n",a);
//10000000 -- a
//11111111 11111111 11111111 10000000 --提升 这时是补码
//10000000 00000000 00000000 01111111 --反码
//10000000 00000000 00000000 10000000 --原码


    return 0; 
}

​

结果图下 

 4.

//4.
#include<stdio.h>
int main() {
	int i = -20;
	//10000000 00000000 00000000 00010100 -- 原码
	//11111111 11111111 11111111 11101011 -- 反码
	//11111111 11111111 11111111 11101100 -- 补码
	unsigned int j = 10;
	//00000000 00000000 00000000 00001010 -- 原、反、补码
	printf("%d\n", i + j);
	//11111111 11111111 11111111 11101100 -- -20 补码
	//00000000 00000000 00000000 00001010 -- 10 补码
	//相加
	//11111111 11111111 11111111 11110110 -- 相加后的补码
	//10000000 00000000 00000000 00001001 -- 反码
	//10000000 00000000 00000000 00001010 -- 原码  -- 结果为 -10
	//
	return 0;
}
//按照补码的形式进行运算,最后格式化成为有符号整数

5.

这是一个典型的因为数据处理不当而产生的死循环

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

6.

//6.
#include<stdio.h> 
int main()
{
	char a[1000];
	int i;
	for (i = 0; i < 1000; i++)
	{
		a[i] = -1 - i;
	}
    printf("%d", strlen(a));     //结果为255
	return 0;
}

7.

 

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清风玉骨

爱了!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值