你真的懂定义语句 "int a" 吗?

在刚开始学习一门新的编程语言的时候,我们通常的套路就是学习很多数据类型,定义各种变量。但你知不知道,数据类型的本质含义究竟是什么呢?

请看如下语句:

int a;

这是一条非常简单的定义语句,意义简单明了!就连初学者小白都脱口而出:定义了一个整型变量嘛!有什么了不起的?

的确,这没什么了不起的,但艰深繁复的东西,追本溯源,往往都起源于一些个极简的元概念,以上定义就涉及一个非常重要的元概念:内存使用的约定。

原则上,我们要在计算机中做的某件事情,都可以归结为要做某个运算,而运算就必然需要一段内存空间,来作为我们腾挪数据的地盘。因此向系统申请一块地盘,通常就是我们做的第一件事。

问题是,怎么向系统申请一块内存呢?向它大吼一声吗?显然不行,它又没长耳朵。实际上你可以有两种办法来申请:

1,直接定义变量,在栈空间申请内存: int a; 2,用malloc函数,在堆空间申请内存:malloc(4);

栈空间和堆空间,是内存中最重要的两大片地,总的来说栈较小,胜在灵活,堆较大,用来存放巨型数据或者动态数据。本文不深入讨论两者的区别和用法,我们要将精力集中在变量定义的类型,也就是约定上。

第一句话,定义了变量a,类型是 int ,这意味着我们不仅向系统申请了一块内存,而且还约好了这块内存将来的用途:用作存储整型数据,而系统也会乐于使用整型的存储格式,来解析将来存储其中的1和0序列。

这就好比你向写字楼申请租赁几间房间,写字楼物业当然很欢迎,但与此同时,他们也必定会询问你租着几个房间的实际用途,毕竟他们可不想你在清一色的科技公司写字楼里出现一家KTV,或者幼儿园。因为这会跟他们原本理解的不一样,他们觉得无法管理。

所以,定义一个变量 int a (租赁一块场地)实际上就是跟系统(物业公司)签订了一个协议(数据类型),规定了以后系统(物业公司)如何解析(管理)这块内存。与此同时,因为你规定了这块内存作何用途,所以也顺带规定了这块内存的大小尺寸。

现在重点来了,我们经常会在数据类型转换的迷雾中晕头转向,例如以下例子:

int a; *(float *)&a = 3.14; printf("a: %f\n, *(float &)&a);

一般人会认为,a 是一个整型变量,无法存储小数,但其实,编译系统才不管什么整型浮点型,他只知道 a 就是一块内存而已,里面放一些1和0的序列,类型的定义,充其量只是一个原始条约,到关键时刻临门毁约的事情很少见吗?因此你看到,当我们硬是要把 a 这块内存当做 float 型数据来看到,硬是把 a 这块内存的地址当做 float 型数据的地址来看待,你会发现一样可行,只不过要在每一次操作都需要使用 (float *) 这样的类型类型强制转换一下罢了,谁让你一开始定义 a 的时候跟你实际使用 a 之时情况不一致呢?

我们可以出尔反尔,只需要在使用内存的时候用类型强制转换糊弄一下系统即可。系统之所以那么好糊弄,因为如果出了错,你负全责。C语言对于内存管理,从来都是个懒蛋,他不管理任何内存。

理解了内存的类型,无非就是一种约定的内幕之后,我们对各种类型的指针、各种类型的数据就有了更清晰的理解了。

看完点个分享散播技术正能量呗~

本文分享自微信公众号 - 秘籍酷(mijiku040)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-05-07

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券