指针与数组

一,前言
提起指针与数组,大家可能都再熟悉不过,尤其是指针,令许多人既喜欢,又害怕;当然除此之外在面试中我们也经常会遇到关于指针与数组操作的问题;这篇文章便是为了弄清楚指针与数组的关系而出现的。
二,指针与数组的不同
这个问题一般人都会这样回答:指针是一种变量,它存储相应类型变量的地址,在定义一个指针时编译器只会为指针本身申请存储空间,而对于数组而言,编译器需要为数组中的每一个元素都申请相应的空间。例如:
int a[]={1,2,3,4};
int* p=a;
如上面的例子,在定义a的时候,需要申请4*4=16个字节的空间;而对于指针p而言只需要4个字节的存储空间(32bit下,指针都为4个字节)

此后当我们访问a中的元素时,可以采用a[i]的形式,也可以采用:
1,p[i]
2,(p+i)
此时你可能会有疑问,指针和数组都能采用取下标的操作,那么它们又有什么不同呢?
从刚开始学习数组,老师可能会再三提示“对于数组而言,数组名就是一个地址”,但他们却并没有完全告诉我们这是为什么?
2.1 它们是怎样取得数据的呢?
对于数组而言,数组名便代表一个地址,数组名作为左值在编译时便确定了它在内存中的位置,当我们想获得数组中的某个元素时,我们往往采用取下标的操作,此时操作系统便会在指定的位置取元素,例如:
int a[5]={1,2,3,4,5};
a[3]=?
此时,我们声明了一个整型数组,当我们想获得a[3]时,操作系统首先会获得数组a的地址,然后通过偏移地址,直接获得相应的值;假如a在内存中的地址为1212,因为int为4个字节,所以步长为4,访问a[3],即为访问:1212+3
4=1224中的内容;值得注意的是:偏移量等信息的获取是由编译器自动来完成的,这就是为什么在声明一个变量的时候需要指明它的类型。
而对于指针来说:int * p=a;
当我们想获取a[3]时,可以通过p[3]的形式,此时与数组访问好像没有什么区别,其实不然,因为p是一个指针,所以操作系统首先去内存为p的地址获得p中所存的数据,因为p为指针,所以此时数据也为地址,然后再通过对"该地址+偏移地址"进行访问获得相应的数据,这里面是一个间接访问的过程。通过指针获得数据,操作系统需要对内存访问两次。
用一个例子表示:p的地址为2223,操作系统对该地址进行访问获得数据为4152,然后再对4152+4*3=4164的内存空间进行访问,获得数据。
于是就可能存在这样一个问题:a是一个数组,在另一文件我们在使用a时将其声明为指针,于是就发生了戏剧性的一幕,操作系统把a当指针,首先在a所在的内存空间进行访问获得一个整型的数据,然后又把该数据当成地址,再次取内存中访问,此时程序就很有可能挂掉,因为你把一个整型数据解释为地址这显然是不合理的,程序当即挂掉,但这还是最好的情况,如果那个错误的地址正好可以访问,程序也读出了数据,然后在某一天突然就挂掉了,这才是最让人费神的事。问题在刚发生时就被发现,往往造成的损失也最少。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值