我倒的这篇文章的图挂 了
前面讲到“白马、黑马”时,我们说一匹白马和一匹黑马具有共同的数据类型“马”,但二者是相对独立的个体。现在我们以共熟悉的“人”来继续这个话题,最终引出变量与内存地址的关系。
张三和李四的数据类型都是“人类”。但张三和李四显然是独立的量:张三吃了两块蛋糕,李四不可能因此就觉和肚子饱了;而李四在下班的路上捡到一个钱包,虽然正好是张三的,两人似乎通过钱包有了点关系,但谁得谁失仍然不容混淆。
这一切都很好理解。张三和李四之所以是不同的个体,根本原因在于两人有着不同的肉身。如果是一对连体婴儿,虽然也是两个人,但当左边的婴儿被蚊子咬一口时,右边婴儿是否也会觉得痒,就不好说了。
现在我们困难的是,如何理解两个不同的变量,也是互相独立的呢?
答案就在“内存地址”,“内存地址”就是变量的肉身。不同的变量,拥有不同的内存地址。譬如:
char a;
char b;
上面有两个字符类型的变量a和b,a拥有自已的内存地址,b也拥有自已的内存地址,二者绝不相同。而a、b只不过分别是那两个内存地址的“名字”,恰如“张三、李四”。
让我们看图解:
看,内存就像是开宾馆的。不过这有宾馆有点怪。首先它每一个“房间”的大小都是一个字节(因此,计算机能单独处理的最小内存单位为字节)。它的门牌号也不叫房号,而是叫内存地址。
在左图中,“房客”,变量a住在内存地址为1000002的内存中,而变量b则住在它的隔壁,地址为100003的内存中。另外,如果你足够细心,你还会发现:内存地址由下往上,从小到大排列。
变量的内存地址是在程序运行时,才由操作系统决定。这就好像我们住宾馆。我们预定一个房间,但房间号由宾馆根据情况决定,
我们可以改变变量的值,但变量的地址我们无法改变。对照宾馆一说,就是我们订了房间,可以不去住,还可以决定让谁去住在那个房间里。(当然,现实生活中宾馆可能不会允许你这么做)。
在前面图示的例子中,a、b是字符(char)类型。各占用1个字节。如果是 int类型,那么应该占4个字节。这4个字节必须是连续的。让我们再来看一个例子:
int a;
int b;
char c;
这回,我们声明了两个int类型和一个char类型的变量。同时和上面一样,我们事实上是假设了这三个变量被依次序分配在相邻的内存地址上(真实情况下,这和其它因素,如指定的字节对齐方式等有关)。从右图中可以看到整型变量a占用了1000001~100004这4个字节。
在我们已学习的数据类型中,long double占用10个字节,是占用内存空间最大的一种数据类型。以后我们学习数组,或者用户自定数据类型,则可能要求占用相当大的,并且同样必须是连续的空间。因此,如果操作系统仅仅通过简单的“按需分配”的原则进行内存管理,内存很快就会宣告不足。事实上,操作系统的内存管理相当复杂。幸好,一个普通的程序员并不要求去了解这些内幕。更多的有关内存管理的知识,我们会在下一部课程中学习。但是本章中有关内存的内容却相当重要。
让我们来看看我们学了什么:
1、不同的变量,存入在不同的内存地址,所以变量之间相互独立。
2、变量的数据类型决定了变量占用连续的多少个字节。
3、变量的内存地址在程序运行时得以确定。变量的内存地址不能改变。
除了这些以外,我们现在还要增加几点:
现在,我们可以明白,为什么需要变量,显然,这又是一个讨好人类的做法。在汇编和机器语言,就是只对内存进行直接操作。但你也看到了,内存地址是一堆长长的数,不好记忆;另外,管理内存复杂易错,让程序员直接管理内存显示不可能。而通过变量,不仅让内存地址有了直观易记的名字,而且程序员不用直接对内存操作,何乐而不为呢?事实上,这是所有高级语言赖于实现基础。
既然变量只不过是内存地址的名称,所以:
4、对变量的操作,等同于对变量所在地址的内存操作。
第五点是反过来说:
5、对指定内存地址的内存操作,等同对相应变量的操作。
尽管这简直就是在重复。但这一条却是我们今后理解C、C++语言相对于其它很多高级语言的,最灵活也最难学的“指针”概念的基石。