您的位置:首页 > 其它

指针和数组(第五节 定义与声明)

2016-12-08 18:59 197 查看
文件1中定义如下:chara[100];

文件2中声明如下:externchar*a; (关于extern的用法,以及定义和声明的区别,请复习第一章)

这里,文件1中定义了数组a,文件2中声明它为指针。这有什么问题吗?平时不是总说数组与指针相似,甚至可以通用吗?但是,很不幸,这是错误的。通过上面的分析我们也能明白一些,但是“革命尚未成功,同志仍需努力”。你或许还记得我上面说过的话:数组就是数组,指针就是指针,它们是完全不同的两码事!他们之间没有任何关系,只是经常穿着相似的衣服来迷惑你罢了。下面就来分析分析这个问题:
在第一章的开始,我就强调了定义和声明之间的区别,定义分配的内存,而声明没有。定义只能出现一次,而声明可以出现多次。这里extern告诉编译器a这个名字已经在别的文件中被定义了,下面的代码使用的名字a是别的文件定义的。再回顾到前面对于左值和右值的讨论,我们知道如果编译器需要某个地址(可能还需要加上偏移量)来执行某种操作的话,它就可以直接通过开锁动作(使用“*”这把钥匙)来读或者写这个地址上的内存,并不需要先去找到储存这个地址的地方。相反,对于指针而言,必须先去找到储存这个地址的地方,取出这个地址值然后对这个地址进行开锁(使用“*”这把钥匙)

这就是为什么externchara[]与externchara[100]等价的原因。因为这只是声明,不分配空间,所以编译器无需知道这个数组有多少个元素。这两个声明都告诉编译器a是在别的文件中被定义的一个数组,a同时代表着数组a的首元素的首地址,也就是这块内存的起始地址。数组内地任何元素的的地址都只需要知道这个地址就可以计算出来。

但是,当你声明为externchar*a时,编译器理所当然的认为a是一个指针变量,在32位系统下,占4个byte。这4个byte里保存了一个地址,这个地址上存的是字符类型数据。虽然在文件1中,编译器知道a是一个数组,但是在文件2中,编译器并不知道这点。大多数编译器是按文件分别编译的,编译器只按照本文件中声明的类型来处理。所以,虽然a实际大小为100个byte,但是在文件2中,编译器认为a只占4个byte。

我们说过,编译器会把存在指针变量中的任何数据当作地址来处理。所以,如果需要访问这些字符类型数据,我们必须先从指针变量a中取出其保存的地址
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐