数据的储存

前言

数据存储是编程学习的重要内容

目录

一、基本数据类型

二、计算机中数据的运算

三、整型提升

四、数组的存储与越界访问

五、指针类型的意义

六、浮点型数据的存储

总结


们发现并减少bug具有相当重要的意义


提示:以下是本篇文章正文内容,下面案例可供参考

一、基本数据类型

在学习C语言的过程中,对数据是如何在计算机中存储的探究与学习是十分必要的。C语言中数据可分为两大类--有符号数和无符号数(),它们的存储类型有以下几类:(这里不考虑结构体类型)

整型浮点型数组指针
int(signed int    unsigned int)double整型数组整型指针
shortfloat浮点型数组浮点型指针
long指针数组数组指针
long long
char(ASCII码值也为整型)

这里并未完全列出,我将对类型之间的转换以代码的形式做简要讲解。

二、计算机中数据的运算

我们都知道,数据在计算机中都以二进制补码储存,而CPU能进行加法运算,在我们编写程序时,所有的问题的解决都只是CPU进行着加法运算。像2-1,在计算机中便被理解为2+(-1),2*2,便是两个2相加,这些运算符都早由以前的程序员或科学家们设计好了。在计算机中2-1是这样运算的:

00000000 00000000 00000000 00000010 -- 2的原码、反码、补码(正数三码相同)
10000000 00000000 00000000 00000001 -- -1的原码
11111111 11111111 11111111 11111110 -- -1的反码(最高位为符号位不变)
11111111 11111111 11111111 11111111 -- -1的补码

二者补码相加得:1 00000000 00000000 00000000 00000001

我们知道int型数据由4个字节即32bit位构成,此时最高位的1超出32位被去掉,留下

00000000 00000000 00000000 00000001,这正是1的三码,不得不说这个方法很巧妙。

此外,计算机的存储模式分为大端存储模式和小端存储模式。例如一个16进制的数据:0x12345678,在计算机中大都以78 56 34 12存储,这是小端存储模式,二进制低位在低端,高位在高端,你们可以在自己的编译器上试一下,如果有内存监视窗口。

#include<stdio.h>

int check()
{
	int x = 1;
	return (*(char*)&x);//先用char类型指针接收整型x的地址,在对其解引用,取得一字节地址的值
}//计算机数据排列模式

int main()
{
	if (check() == 1)
		printf("小端");
	else
		printf("大端");
	return 0;
}

这里写了一段代码用于判断计算机的数据存储模式。若为0,则高位在低端,为大端存储,反之为小端存储。

整型提升

对于下面一段代码你们可以猜猜打印结果是什么(%u是无符号十进制输出)

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

由下面的图可知char的范围,但char是一字节八位,而%u输出的是四字节32位的十进制整数,那么,在计算机里是怎样操作的呢。

10000000 -- 128的三码,其实就是-128,在signed char类型中无128,由图知进一位为-128,这里就涉及到整型提升这个概念,在计算机将其转化为32位是,取最高位即符号位(无符号数补0)的数往前补,直到将其补满。那么-128便变成下面的二进制码。

11111111 11111111 11111111 10000000 -- 整型提升后的二进制码

由于以无符号数打印,则该数无符号为正数,改码即为其三码,用windows自带的计算器,调至程序员可算出结果为4,294,967,168,一个相当大的数。走程序发现两次打印相同且结果相同都为4,294,967,168,大家可以动手试试。这还有一道题,结果是什么呢?

#include<stdio.h>
#include<string.h>
int main()
{
	int i = 0;
	char a[1000] = { 0 };
	for ( i = 0; i < 1000; i++)
	{
		a[i] = -1 - i;
	}
	printf("%d\n", strlen(a));
	return 0;
}

strlen函数读取字符串长度,读取到‘\0’时停止,\0 的ASCII码值为0,即当读取到零时停止,由上图知从-1~-128,到-129时即为127,再从127~0停止,中间经过128+127=255个数,则结果为255。

你们可以自己检验一下。

四、数组的存储与越界访问

数组存储可由下面一段代码清楚明了的展示出来:

#include<stdio.h>
int main()
{
	char a1[10] = { 0 };
	int a2[10] = { 0 };
	printf("%d\n%d\n", sizeof(a1), sizeof(a2));
	for (int i = 0; i < 10; i++)
	{
		printf("%p %p\n", &a1[i], &a2[i]);//%p打印地址
	}
	return 0;
}

 char类型逐1增加,int型逐4增加,sizeof计算数据所占空间大小,这里不包含‘\0’,可知数组内元素是连续存储的。

#include<stdio.h>
int main()
{
	int  i = 0;
	int a[10] = { 0,1,2,3,4,5,6,7,8,9};
	for (i = 0; i <= 12; i++)
	{
		a[i] = 0;
		printf("ha\n");
	}
	return 0;
}

 这段代码在某些编译器上可能无法通过(我用的VS2017就不行),在VS2013上这是一个死循环。我们知道,局部变量都存在栈区,先创建的放在栈上方,后创建的放在下方,当越界修改数组的值时,就可能修改先前创建的局部变量的值,在此处即a[12]的地址等于i的地址,从而i<=12恒成立陷入死循环。因此,在编写代码时,一定不要越界使用数组和指针。

五、指针类型的意义

这里简单的对指针类型的意义进行说明。

#include<stdio.h>
int main()
{
	int a[10] = { 1,2,3,4,5,6,7,8,9,10 };
	char*p = (char*)a;
	int*pa = a;
	int**ppa =&pa;//二级指针,指针类型为int*
	int***pppa = &ppa;//三级指针,指针类型为int**
	*pa = 999;
	printf("%d %d %d %d %d", a[0], *pa, **ppa, ***pppa,*p);
}

像int*pa=a,表明pa是指向a的int型指针,int**ppa=&pa说明ppa是指向pa的int*型指针。

指针的这种访问结构叫做链式结构,由上一个数据找到下一个数据,连成一串。

指针都占4或8个字节,不过指针类型决定了解引用时所访问的步长,如果用char型指针接收int类数据在解引用时就会造成上述整型提升中所遇到的问题,因此,指针类型具有重要意义,避免不同数据在接收时造成混乱,提高对空间的利用率。

六、浮点型数据的存储

IEEE754标准规定了浮点数的存储方式。

#include<stdio.h>
int main()
{
	int n = 13;
	float*p = (float*)&n;
	printf("%d %f\n", n, *p);
	*p = 13.0;//(-1)^0*1.101*2^3 ieee754标准,1位表符号为s,8位表指数,为e,余下23位存储m,
	printf("%d %f", n, *p);
	return 0;
}

像13以float形式存储时要在E位上加127,其M位为13减去E的值,其二进制码为:

0 (符号位S)10000010 (E位+127)10100000 00000000 0000000(M位由高位向低位写,值为原数-E)

当以十进制打印时,由其二进制补码知值为1,095,761,920.

13的补码为:00000000 00000000 00000000 00001101,在float类型下,改二进制码被理解为

:0 01111111 00000000 00000000 00001101,如此M位为很小的一个数,该值无限接近于零。所以打印结果为0.000000

总结

了解数据在计算机中是如何存储的对我们发现问题很有帮助,还请大家一起努力学习。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

...404 Not Found

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值