数组与指针的解析 -- 摘自CSDN论坛回复

问题:

比如,现在有一维数组定义如下:
int arr[5]={1,2,3,4,5};

我们都知道 数组名arr是代表数组首元素的地址即arr[0]的地址。 
 那在数组名前面加上取地址符&,即&arr,打印出的地址同样也是arr[0]的地址。

 比如 
   printf("arr=%x\n&arr=%x\n&arr[0]=%x\n", arr, &arr, &arr[0]);

 假设 现在有一个数组指针定义如下:
 int (*p)[5]=NULL;
 p=&arr;// 这样赋值就不会报错。
 p=arr; // 但是这样赋值就会报错。&arr与arr的指向的地址相等的,那么为什么还会报错呢?


 
假设,现在再定义一个二维数组如下:
 int arr2[4][5]={...};
 p=arr2;  // 而这样就不会报错。
 p=&arr2; // 报错。

 
麻烦解释下 “数组名”与“&数组名”分别在一维、二维或更多维数组里的区别和作用? 最好能给出它们在内存,组织的原理或示意图。 
谢谢大家。

回答:

作者:

均陵鼠侠  
账号:sholber

比如,现在有一维数组定义如下:
int arr[5]={1,2,3,4,5};

我们都知道 数组名arr是代表数组首元素的地址即arr[0]的地址。 我很想知道,为什么成千上万的初学者,非得要纠结数组名,以及数组地址的问题。另:数组名代表数组首元素的地址,这个荒唐啊
  那在数组名前面加上取地址符&,即&arr,打印出的地址同样也是arr[0]的地址。

 比如 
    printf("arr=%x\n&arr=%x\n&arr[0]=%x\n", arr, &arr, &arr[0]);

  假设 现在有一个数组指针定义如下:
 int (*p)[5]=NULL;
  p=&arr;// 这样赋值就不会报错。
 p=arr; // 但是这样赋值就会报错。&arr与arr的指向的地址相等的,那么为什么还会报错呢?
这正是我恶心数组名和数组地址之类措辞的原因。因为,只用类型即可解释一切与数组有关的问题。标准说,对于表达式&E,若E的类型是T,则表达式&E的结果是指向T的指针。因为arr是数组,故&arr的结果是指向数组的指针。
标准又说,除非做为运算符sizeof和一元&的操作数,数组类型的标识符将被转换为指向其首元素的指针。因此,p=arr中,arr会被转换为指向其首元素的指针。因为元素的类型是int,故表达式arr转换后的类型是int *,与运算符=的左操作数p的类型不兼容。


 
假设,现在再定义一个二维数组如下:
 int arr2[4][5]={...};
  p=arr2;  // 而这样就不会报错。
 p=&arr2; // 报错。
arr2是一个数组,其元素类型也是数组。从前面说的,arr2被转换为指向其首元素的指针,也就是指向数组的指针(元素类型也是数组嘛),即int (*) [5]与p的类型兼容。相应地,&arr2的结果是指向数组的指针int (*) [4][5],尽管也是指向数组的指针,但与p的类型不兼容。
 
麻烦解释下 “数组名”与“&数组名”分别在一维、二维或更多维数组里的区别和作用? 最好能给出它们在内存,组织的原理或示意图。 
以C中,不存在二维数组和多维数组。所谓的二维数据,就是元素类型是数组的数组(这个过程可以递归进行)。如果用多维数组来理解和解释,反而更迷糊。
谢谢大家。 

更正一下:

标准又说,除非做为运算符sizeof和一元&的操作数,数组类型的标识符将被转换为指向其首元素的指针。

其中,数组类型的标识符改为“数组类型的表达式”。考虑如下声明:
C/C++ code
?
1
struct  t { int  a [22];  float  f;} t [3];

则表达式
C/C++ code
?
1
t [0].a

是数组类型的表达式。它会被转换为指向其首元素的指针:
C/C++ code
?
1
int  * p = t [0].a;

=======================

摘录自:https://bbs.csdn.net/topics/391002768?page=1

回答特别简单易懂,一下子就让我 茅塞顿开。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值