数组与指针关系

来自 http://community.csdn.net/Expert/topic/3142/3142075.xml?temp=.2214624

举个例子,有如下一个数组:
  int a[10][10];
  如果想得到数组a的首地址,我们可以使用这样的语句:
  printf("a:/t%p/n", a);    // 1
  这样,在显示屏上就可以输出该数组的十六进制首地址了。一般而言,这个首地址是位于栈上的。
  
  事实上,数组名a只是一个别名,它代表了一个地址常量。打印a的值,实际输出的就是它代表的地址值。通常在使用a的时候,我们可以把它当作数组来看待,使用下标运算符[]来寻址其中的元素;也可以把它当作地址来看待,使用取值运算符*来寻址其中的元素。比如:
  a[0][0] 等价于 *(*a)
  
  然而,要得到数组的首地址,方法有很多,并不限于打印数组名对应的地址值。还可以使用如下语句来输出数组首地址:
  printf("&a[0][0]:/t%p/n", &a[0][0]); // 2
  这个办法学过C的人都应该知道,因为数组中第一个元素总是分配在数组的最前头,因为它的首地址也必然与数组的首地址相同。但是,要注意的是,这两个地址只是值相同,而它们的数据类型并不相同!!!!
  让我们换一种输出方式,就可以让它们数据类型的不同显现出来。方法如下:
  printf("a+1:/t%p/n", a+1);    // 3
  printf("&a[0][0]:/t%p/n", &a[0][0]+1); // 4
  通过观察打印值,可以发现a+1的地址值比a的地址值多出了40个字节,而&a[0][0]+1却只比&a[0][0]多了4个字节。也就是说,a+1一下子跳过了10个整型元素(每个元素占4字节),而&a[0][0]+1只跳过了1个整型元素。
  嘿嘿,发现了吗?虽然首地址相同,可是首地址的数据类型,却并不相同。
  
  a的地址的数据类型,是int (*)[10]。它指向拥有10个元素的一维数组,其中每一个元素的数据类型又是拥有10个元素的一维数组。我们知道,a[0]与a[1]的不同,其实就是跳过了一个元素。而a[0]与*a实际是等价的(在实际使用数组时,通常会退化为对其地址--类似一个指针--进行操作),a[1]与*(a+1)也是等价的。因此,对a+1而言,应该跳过一个元素,即实际输出a+1对应的地址值时,应该跳过40个字节(最后一维数组中的元素个数*每个元素大小)。
  而a[0][0]的数据类型是int,对应地,&a[0][0]的数据类型是int *。按上面说过的,&a[0][0]+1实际上就只跳过了一个整型值占用的字节数,即4字节。

  所以咯,下面的东东就不说作很详细的说明了,我只给出它们对应的数据类型,大家不理解的话就多从它们的数据类型下手去思考吧。

#include
#include

using namespace std;

int main(int argc, char *argv[])
{
  int a[10][10];
 
  printf("a:/t%p/n", a);          // int (*)[10]  或者是 int [][10]
  printf("a+1:/t%p/n", a+1);      // int (*)[10]
  printf("&a:/t%p/n", &a);        // int (*)[10][10] 或者是 int [][10][10]
  printf("&a+1:/t%p/n/n", &a+1);  // int (*)[10][10]

//  printf("&&a:/t%p/n", &&a);  // 不可能
//  printf("&&a+1:/t%p/n/n", &&a+1);  // 不可能

  printf("a[0]:/t%p/n", a[0]);          // int *  或者是 int []
  printf("a[0]+1:/t%p/n", a[0]+1);      // int *
  printf("&a[0]:/t%p/n", &a[0]);        // int (*)[10]  或者是 int [][10]
  printf("&a[0]+1:/t%p/n/n", &a[0]+1);  // int (*)[10]

  printf("&a[0][0]:/t%p/n", &a[0][0]);        // int *  或者是 int []
  printf("&a[0][0]+1:/t%p/n/n", &a[0][0]+1);  // int *
 
  system("PAUSE"); 
  return 0;
}

  仔细观察,呵呵,有规律可循的。
  如果还有什么问题,或者是有什么错误,大家都可以提出咯。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值