鱼C论坛

 找回密码
 立即注册
查看: 1560|回复: 4

[已解决]S1E24:指针和二维数组作业 地址和取值的问题

[复制链接]
发表于 2018-12-20 17:03:19 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
#include <stdio.h>

int main()
{
        char array[2][3][5] = {
                {
                        {'x', 'x', 'x', 'x', 'x'},
                        {'x', 'x', 'o', 'x', 'x'},
                        {'x', 'x', 'x', 'x', 'x'}
                },
                {
                        {'x', 'x', 'x', 'x', 'x'},
                        {'x', 'x', 'o', 'x', 'x'},
                        {'x', 'x', 'x', 'x', 'x'}
                }
        };

        printf("%c%c%c%c\n", *(*(*array + 1) + 2), *(*(*(array + 1) + 1) + 2), ***array, *(**array + 1));

        return 0;
}

这里小甲鱼的输出答案是ooxx 我照着编译输入发现只能输出后面的xx 前面的oo输不出来
我的问题:
1.我认为第一个输出的应该是第六行第一个元素x的地址,第二个输出的应该是第五行第三个元素o的地址,不知道是否正确?如果第二个写成*(*(*(array + 1) + 1) + 2) 则会报错,这是为什么呢?
2.***array应如何理解? 如果*array就是数组第一个元素的地址,那么**array不就可以输出第一个元素的值x吗?为什么**array不能输出?
最佳答案
2018-12-20 18:43:56
我在VC6上编译输出的ooxx
1.
第一个表达式从里往外看,*array代表array[0]也就是行地址 *(*array+1)代表a[0][1]   *(*(*array + 1) + 2)则代表了a[0][1][2] 所以第一个输出就是'o',第二个是正确的
你的后面的第二个的写法与程序中的不是一样的吗,程序里的没问题
2.
***array就是array[0][0][0] 第一个元素      **array只是array[0][0]的地址        因为是三维数组表示某一个值一定会有三个*才会表示变量的值

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-12-20 18:43:56 | 显示全部楼层    本楼为最佳答案   
我在VC6上编译输出的ooxx
1.
第一个表达式从里往外看,*array代表array[0]也就是行地址 *(*array+1)代表a[0][1]   *(*(*array + 1) + 2)则代表了a[0][1][2] 所以第一个输出就是'o',第二个是正确的
你的后面的第二个的写法与程序中的不是一样的吗,程序里的没问题
2.
***array就是array[0][0][0] 第一个元素      **array只是array[0][0]的地址        因为是三维数组表示某一个值一定会有三个*才会表示变量的值

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-12-20 18:55:41 | 显示全部楼层
楼主您好。对于多维数组来说的确有点难理解。主要是其中牵扯了多级指针。多对照二维数组来分析,楼主可能会有意想不到的收获 , 进入正题。
首先,本程序在我这里编译输出没有问题, 输出为 ooxx。
接下来先解释一下二维数组的多级指针吧。 对于 char c[3][3];  这个二维数组来说。  假如  c = 0; *c = 0;  c+1 = 3; *c +1 = 1。 如何理解呢。
c是char ** 二级指针, 他指向的就是 前面括号 [3] 对应的行,所以每次指针加一对应平移一行, 也就是+3(说明一下,char占用一个字节,所以平移+3。若是int 类型 , 就是+ 3*4=12)。  
*c  就是解了一次指针, c变成了 char* 类型, 他指向的就是某一个行内的元素,所以+1, 对应行内,平移一个元素,也就是+1。
对于 **c , 又解了一次指针,所以为 char 类型,对应数组内元素了。

类似的。对于三维数组来说。 a 就是 char *** 三级指针,他指向的就是前面的 [2]  对应的块,块大小 就是3*5=15,所以 假设a = 0, a+1 = 15,对应平移一块;
*a  就是 char **类型的指针,指向对应块内的行,也就是  [?][3]  所以 *a + 1 = 5;对应的是 在块内平移一行
**a  就是 char * 类型指针, 指向对应行内的元素  也就是  [?][?][5]  所以 **a +1 = 1; 对应的是 在块内的行内,平移一个元素。
***a  就是 char 类型元素  就是对应数组元素了。

接下来解决问题。建议 楼主思考后 参考。
(1)我认为第一个输出的应该是第六行第一个元素x的地址,第二个输出的应该是第五行第三个元素o的地址,不知道是否正确?
不正确:array 指向第0个块  *array 指向第0块第0行。*array+1指向第0块第1行。*(*array + 1)指向第0块第1行第0个元素。*(*array + 1) + 2 指向第0块第1行第2个元素。*(*(*array + 1) + 2),得到第0块第1行第2个元素 o。
array+1 指向第1个块。*(array + 1)指向第1个块第0个行。*(array + 1) + 1指向第1个块第1个行。*(*(array + 1) + 1)指向第1个块第1个行第0个元素。*(*(array + 1) + 1) + 2 指向第1个块第1个行第2个元素 即 o。
(2)如果第二个写成*(*(*(array + 1) + 1) + 2) 则会报错,这是为什么呢?
分析:这个  和源程序内是一样的 , 估计楼主给错了吧。
(3)***array应如何理解?
array 指向第一块。*array 指向第0块第0行 **array 指向第0块第0行第0个元素。 ***array 就是 第0块第0行第0个元素。
(4)如果*array就是数组第一个元素的地址,那么**array不就可以输出第一个元素的值x吗?为什么**array不能输出?
* array 不是第一个元素地址。上面以解释。**array 对应 char * 类型指针  不是字符类型
(5)小酒酒需不需要最佳和奖励?
当然是需要的。打字也有点累呢。有什么奖励都来吧。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-12-20 21:32:56 | 显示全部楼层
想了蛮久不知道怎么解说
*(*(*array + 1) + 2) == *(*(*(array+0) + 1) + 2) 估计你看了也懂了。
array 首元素的地址
array+0 首先是找到该行的地址,
*(array+0) == *array  对其解引用后是得到该行首元素的地址
***array  == *(*(*(array +0)+0)+0) == array[0][0][0] 看出没 就是*(*(*(array +0)+0)+0) 的简写


关键处是。行地址-->首元素地址
                               ↓
                         行地址->首元素地址
                                       ↓
                                   行地址->首元素地址
就是这么一级一级找下去, 最后在这个元素的地址上 *() 解引用 得到值。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-12-21 22:39:45 From FishC Mobile | 显示全部楼层
好伤心  没拿到最佳
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-1 00:45

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表