dequantianhe 发表于 2019-12-10 21:28:32

S1E24第5题,看过答案了,但还是有问题!

先看原题代码:
#include <stdio.h>

int main()
{
      int array = {1, 2, 3, 4, 5, 6, 7, 8, 9};
      int (*p) = (int (*))&array;

      printf("%d\n", p);

      return 0;
}

上机测试,输出结果为9,答案解释关键的一句: int (*p) = (int (*))&array;等号右边强制将 array 这个一维数组重新划分成 3 * 3 的二维数组,然后用数组指针指向它。

这里我还是不理解, (int (*))是怎样把强制将 array 这个一维数组重新划分成 3 * 3 的二维数组的?

如果说解释是:&array代表一个9个元素的一位数组整体的地址,所以前面的把这个一位数组三等分了?但后面说用数组指针指向它,也就是p指向的是一个二维数组,那么p的值是二维数组的地址还是二维数组第一个一维元素的地址?

正常来讲,我们定义一个指向2维数组的指针写法是:
int (*p) = &array;(此处array是一个3*3二维数组的名字)

然后用数组的方式表达最后一个元素应该是p,但原题目中的输出是p,这说明原题中的P指向的是二维数组的第一个一维元素的地址,而不是指向这个二维数组。

感觉这里还是有点混乱,跪求大神指点,越详细越好,谢谢!

ba21 发表于 2019-12-10 21:42:58

首先你要理解什么叫强制转换
如:
char c;
(int) c; 就把c强制转换成了int类型

这里也一样,array 是一个1维数组, 那么array &array 都是数组首元素的地址,也是数组的地址。

(int (*))&array 和 (int (*))array 都是将这个地址强制转换为 数组指针,而这个数组指针在这里的说法就是(3 * 3 的二维数组,然后用数组指针指向它。) 也就是二维数组指针

jackz007 发表于 2019-12-10 22:36:31

本帖最后由 jackz007 于 2019-12-11 00:32 编辑

int (*p) = (int (*))&array;
      这是强制类型转换,等号左边的 p 是一个指向末维为 3 的二维整型数组的指针,在等号右边,array 本来是一个一维整型数组,只是为了迎合等号左边 p 的类型,所以,才在 array 前面添加了强制类型转换符,成为 (int (*)) & array,这样,可以把 & array 视为一个 3 x 3 的二维数组,一、二维数组元素之间索引的对应关系为:
         二维数组                         一维数组
& array ~ & array对应于 array ~ array
& array ~ & array对应于 array ~ array
& array ~ & array对应于 array ~ array
      所以,不管数组在形式上是一维的还是多维的,归结到本质全都是一维的。所谓的 "数组划分",其实并不会对数组本身进行任何物理上的改变,只是为了便于访问,对数组的索引方式进行了一种逻辑上的重新规划而已。如果通过指针访问,就更加简单:
p   或    * (* (p + i) + j)      对应于   array
      当然,这样访问更加简单粗暴:
p   或    * (* p + k)         对应于   array    

dequantianhe 发表于 2019-12-11 08:55:46

ba21 发表于 2019-12-10 21:42
首先你要理解什么叫强制转换
如:
char c;


你说的我大概都清楚,但对于强制转换的规则还存在疑惑,比如我们强制转换一个int类型数据为char类型,那系统会怎么操作,是不是把int数据的某一个字节(第一个字节)内容保留,作为char的数据值?你说的(int (*))&array 和 (int (*))array 的确是将地址强制转换为数组指针,但关键是将哪部分内容转换为(看作)什么形式的内容,(int (*))&array 和 (int (*))array 两个作用的对象不同,结果应该是不一样的吧,前面的是整个数组,而后面的是第一个元素的地址,{:10_306:},不过我刚才上机试了一下,貌似没发现什么区别。。。。。

dequantianhe 发表于 2019-12-11 09:10:25

jackz007 发表于 2019-12-10 22:36
这是强制类型转换,等号左边的 p 是一个指向末维为 3 的二维整型数组的指针,在等号右边,array...

所以(int (*))&array 和 (int (*))array实际上是没区别的?只是个形式?

jackz007 发表于 2019-12-11 09:24:25

本帖最后由 jackz007 于 2019-12-11 09:45 编辑

dequantianhe 发表于 2019-12-11 09:10
所以(int (*))&array 和 (int (*))array实际上是没区别的?只是个形式?

         是的,但是,你不可以把等号右边的 '&' 去掉,如果去掉的话,等号两边的逻辑关系就不对称了,编译器会拒绝的。

dequantianhe 发表于 2019-12-11 10:11:18

jackz007 发表于 2019-12-11 09:24
是的,但是,你不可以把等号右边的 '&' 去掉,如果去掉的话,等号两边的逻辑关系就不对称了, ...

额,我上机试了,可以去掉&的,没影响,不过我通过多次调试,发现在自己真正的疑惑所在,开始我一直以为(int (*))&array 定义后,p指向的依旧是array数组的整体,其实不是,array是被看作了3*3的数组,但实际上P指向的只是元素1、2、3的首地址,解开这个疑惑,就都讲得通了,我抓紧再总结下,看究竟是我哪里之前掌握的不牢靠。

fishcyky 发表于 2019-12-17 17:13:55

本帖最后由 fishcyky 于 2019-12-17 17:27 编辑

&array 是得到数组中每个元素的地址,
(int (*)&array 就可以写成
(int (*)){1的地址,2的地址,3的地址,... , 9的地址}
这是是一个数组指针,指针指向了一个有3个地址元素的数组,然后元素划分就等分了,我试了试将元素改成8个,指向的值就是随机的了。但是将指向改成p就没有问题。
这可能跟分配有关了。。

然后这就相当于int (*p) 这个数组指针指向的是这个(int (*)){1的地址,2的地址,3的地址,... , 9的地址}有3个地址元素数组指针了
页: [1]
查看完整版本: S1E24第5题,看过答案了,但还是有问题!