`
java-mans
  • 浏览: 11422986 次
文章分类
社区版块
存档分类
最新评论

C语言深度解剖(精讲版)——读书笔记15 &&自己的一些理解

 
阅读更多

第四章 指针和数组

数组

一.数组的内存布局

先看下面的例子:

int a[5];

数组示意图:数组包含5个int类型的数据
a作为右值时,代表数组首元素的首地址,而非数组的首地址;

如图我们定义一个数组a时,编译器根据指定的元素个数和元素类型分配确定大小的一块内存(大小为:元素类型大小*元素个数),并把这块内存的名字命名为a。名字a一旦与这块内存匹配就不能被改变。

现在来看一下下面问题:

sizeof(a)的值 sizeof( int )*5 ,32位系统下为20

sizeof(a[0])的值sizeof (int),32位系统下为4

sizeof (a[5])的值在32位系统下为4,并没有出错,为什么呢?

解析:关键字sizeof求值是在编译的时候,虽然并不存在a[5]这个元素,但是这里并没有去真正访问a[5],而是仅仅根据数组类型来确定其值。因此这里不会出错;

二.&a[0]和&a的区别

这里&a[0]和&a的区别到底有什么?a[0]是一个元素,a是整个数组,虽然&a[0]和&a值一样,但其值意义不一样。

&a[0] 表示:数组首元素的首地址; &a 表示:数组的首地址;

三.数组名a作为左值和右值的区别

x=y

左值:编译器认为x的含义是x代表地址,这个地址只有编译器才知道,编译在一个特定的区域保存这个地址,我们完全不必考虑这个地址保存在哪。

右值:编译器认为y的含义是y所代表的地址里面的内容,这个内容是什么,只有到运行时才知道。

a作为右值时意义:与&a[0]是一样的,代表的是数组首元素的首地址,而不是数组的首地址;【注意的是:这仅仅是代表,并没有一个地方来存存储这个地址,也就是说编译器并没有为数组a分配一块内存来存储其地址,这一点就与指针有很大差别】

a不能作为左值! 编译器会认为数组名作为左值代表的意思是a的首元素的首地址,但是这个地址开始的一块内存是一个总体,我们只能访问数组的某个元素,而无法把数组当一个总体进行访问。

所以我们可以把a[i]当左值,而无法把a当左值,其实我们完全可以把a当做一个普通的变量来看,只不过这个变量内部分为很多小块,只能通过分别访问这些小块来达到访问整个变量a的目的

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics