| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 677 人关注过本帖
标题:关于指针引用二维数组的问题
只看楼主 加入收藏
轉身已陌路
Rank: 2
等 级:论坛游民
帖 子:25
专家分:16
注 册:2014-12-25
结帖率:100%
收藏
已结贴  问题点数:8 回复次数:9 
关于指针引用二维数组的问题
假设定义一个二维数组
 int    ​arr[3][3] = {1,2,3,4,5,6,7,8,9};
那么
printf("\n%p",arr+1);
printf("\n%p",*arr+1);
printf("\n%p",&arr+1);
下面是打印结果
010BFE0C
010BFE03
010BFE24
​在数组中数组名本来不就是数组的首地址嘛 ,*arr+1(如果说*arr是指针的,那么这个指针从来没有定义过啊)取出来的为什么不是数组的内容而还是地址呢,还有这里的arr+1,&arr+1原理上的区别在哪里。
[code=c][/code]
2015-01-12 10:25
longwu9t
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:小飞侠
威 望:6
帖 子:732
专家分:2468
注 册:2014-10-9
收藏
得分:0 
程序代码:
#include <stdio.h>

int main(void) {
    int arr[3][3] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    printf("%p\t%d\n", arr + 1, **(arr + 1));
    printf("%p\t%d\n", *arr + 1, *(*arr + 1));
    printf("%p\t%d\n", &arr, **(*&arr));
    return 0;
}

Only the Code Tells the Truth             K.I.S.S
2015-01-12 10:48
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9025
专家分:54030
注 册:2011-1-18
收藏
得分:1 
下面是打印结果
010BFE0C
010BFE03 // 瞎扯蛋吧,我不信
010BFE24

-------------------------------------------------------------

"在数组中数组名本来不就是数组的首地址嘛" --- 那最重要的数据类型信息呢?这种瞎扯B的话,我就不多说了。

-------------------------------------------------------------

我只说一点『数组 可以隐式降阶』,也就是 TYPE a[N] 可以隐式转化为 TYPE* 类型。
(
   举个例子,比如 int a[2]; 此时 a 是元素类型为 int 的数组,那么 a 可以隐式转化为其元素类型的指针,即 int*;
   举个例子,比如 int a[2][3]; 此时 a 是元素类型为 int[3] 的数组,那么 a 可以隐式转化为其元素类型的指针,即 int (*)[3];
   ……
}
所以
    arr+1 中 arr 类型降阶为 int (*)[3],所以 arr+1 指向 { 4, 5, 6 };
    *arr+1 中 arr 类型降阶为 int (*)[3],所以 *arr 类型为 int [3],内容为 { 1, 2, 3 }; *arr 再次降阶为 int*,所以 *arr+1 类型为 int*, 指向 2;
    &arr+1 中 arr 为 int [3][3],所以 &arr 类型为 int (*)[3][3] 类型,指向 {1,2,3,4,5,6,7,8,9};所以 &arr+1 指向 {1,2,3,4,5,6,7,8,9} 随后的下一个 int[3][3] 空间。


[ 本帖最后由 rjsp 于 2015-1-12 10:59 编辑 ]
2015-01-12 10:55
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:5 
小r版主解释的很清楚 学习了
2015-01-12 12:29
轉身已陌路
Rank: 2
等 级:论坛游民
帖 子:25
专家分:16
注 册:2014-12-25
收藏
得分:0 
回复 3楼 rjsp
*arr+1 中 arr 类型降阶为 int (*)[3],所以 *arr 类型为 int [3],内容为 { 1, 2, 3 }; *arr 再次降阶为 int*,所以 *arr+1 类型为 int*, 指向 2;标红色的还是没太明白。
--还有数组中*arr不表示取内容了?一维数组中还是取内容的啊
比如 int arr[4] = {1,2,3,4}  *arr取的是数据里的元素吧
2015-01-12 16:06
陈志文
Rank: 2
等 级:论坛游民
帖 子:17
专家分:10
注 册:2014-10-13
收藏
得分:1 
这是关于行指针和列指针,当arr为二维数组时,*arr为arr[0],但在二维数组中其不表示元素,即为&a[0][0]。但是,arr+i(i为0,1,2,3.......)它就是指向行指针,虽然也为每一行首元素地址,但和列地址有本质区别。多找点书研究一下,我也在学。
2015-01-12 16:26
TAAAAB
Rank: 7Rank: 7Rank: 7
来 自:湖南
等 级:黑侠
威 望:1
帖 子:243
专家分:635
注 册:2011-5-29
收藏
得分:0 
以下是引用rjsp在2015-1-12 10:55:52的发言:
我只说一点『数组 可以隐式降阶』,也就是 TYPE a[N] 可以隐式转化为 TYPE* 类型。
(
   举个例子,比如 int a[2]; 此时 a 是元素类型为 int 的数组,那么 a 可以隐式转化为其元素类型的指针,即 int*;
   举个例子,比如 int a[2][3]; 此时 a 是元素类型为 int[3] 的数组,那么 a 可以隐式转化为其元素类型的指针,即 int (*)[3];
   ……
}
所以
    arr+1 中 arr 类型降阶为 int (*)[3],所以 arr+1 指向 { 4, 5, 6 };
    *arr+1 中 arr 类型降阶为 int (*)[3],所以 *arr 类型为 int [3],内容为 { 1, 2, 3 }; *arr 再次降阶为 int*,所以 *arr+1 类型为 int*, 指向 2;
    &arr+1 中 arr 为 int [3][3],所以 &arr 类型为 int (*)[3][3] 类型,指向 {1,2,3,4,5,6,7,8,9};所以 &arr+1 指向 {1,2,3,4,5,6,7,8,9} 随后的下一个 int[3][3] 空间。


刚好学到这一段,这二天一直在想,总觉得想的还不够明白。原来可以是这样理解,太感谢了。

人有多懒,编程就有多难。
2015-01-12 17:39
yahwei
Rank: 7Rank: 7Rank: 7
来 自:湖~
等 级:黑侠
威 望:3
帖 子:145
专家分:644
注 册:2011-11-10
收藏
得分:1 
以下是引用轉身已陌路在2015-1-12 16:06:58的发言:

*arr+1 中 arr 类型降阶为 int (*)[3],所以 *arr 类型为 int [3],内容为 { 1, 2, 3 }; *arr 再次降阶为 int*,所以 *arr+1 类型为 int*, 指向 2;标红色的还是没太明白。
--还有数组中*arr不表示取内容了?一维数组中还是取内容的啊
比如 int arr[4] = {1,2,3,4}  *arr取的是数据里的元素吧
说明楼主对一级指针已经理解了,但对多级指针还没学好。一个变量有两个最基本的属性:类型和地址。类型说明了这个变量占多少存储空间,地址说明了这个变量从哪个存储单元开始存储。说到这顺便说下声明和定义的某个区别:声明告诉编译器某个变量的类型,定义告诉编译器某个变量的地址。前提知识讲完了,那么问题来了,指向整型的指针变量和指向整型指针的指针变量一样吗?

[qq]949654600[/qq]
2015-01-13 09:22
轉身已陌路
Rank: 2
等 级:论坛游民
帖 子:25
专家分:16
注 册:2014-12-25
收藏
得分:0 
回复 8楼 yahwei
现在已经搞明白了,在二维数组中是要讲究行和列的,每一行都是个以为数组,那么这样的话,二维数组中存在这二级指针,*arr其实就当二级指针来理解最好不过了,你如说一个二维数组,int arr[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};那么 arr,*arr,&arr都去首地址,但是其意义是有很大区别的arr是代表行的首地址,加1只能取下一行的首地址,*arr是取第一行第一列的首地址,加1的话当然就取第一行第二列的地址,再来说说&arr,取sizeof(&arr)可知长度是48,所以&arr+1指向下一个数据空间的长度,我只是搞清楚了怎么取,怎么用了,但是这个机制原理还有待研究。
2015-01-13 14:18
yahwei
Rank: 7Rank: 7Rank: 7
来 自:湖~
等 级:黑侠
威 望:3
帖 子:145
专家分:644
注 册:2011-11-10
收藏
得分:0 
以下是引用轉身已陌路在2015-1-13 14:18:02的发言:

现在已经搞明白了,在二维数组中是要讲究行和列的,每一行都是个以为数组,那么这样的话,二维数组中存在这二级指针,*arr其实就当二级指针来理解最好不过了,你如说一个二维数组,int arr[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};那么 arr,*arr,&arr都去首地址,但是其意义是有很大区别的arr是代表行的首地址,加1只能取下一行的首地址,*arr是取第一行第一列的首地址,加1的话当然就取第一行第二列的地址,再来说说&arr,取sizeof(&arr)可知长度是48,所以&arr+1指向下一个数据空间的长度,我只是搞清楚了怎么取,怎么用了,但是这个机制原理还有待研究。
从你的表述来看,你仍然没有完全理解指针。我前面已经说了,要理解指针,你首先得弄清楚变量的两个基本属性:类型和地址。地址,相信你已经理解了。关键在于类型,简单的类型相信你也是理解了的,比如int a; char ch;之类的类型。
但复杂的类型呢?比如:int a[2]; a的类型就是 int [2],通俗的说: a 是可以存储两个整型元素的数组。再比如int *a[3];中a的类型是 (int *)[3],通俗的讲: a是可以存储三个整型指针的数组。加个括号: int (*a)[3]中 a 的类型就变成了 int (*)[3],通俗的说,a 是一个指针,它指向一个数组,这个数组有三个整型元素。更多的知识,建议你搜索“C语言复杂类型”学习。当你理解了类型再来看指针就相当简单了。

再多句嘴,学到指针数组这些知识后,应该去看《C和指针》这本书,和《C专家编程》对照着学习效果更好。

[ 本帖最后由 yahwei 于 2015-1-13 20:01 编辑 ]

[qq]949654600[/qq]
2015-01-13 19:54
快速回复:关于指针引用二维数组的问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.057347 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved