免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 2609 | 回复: 10
打印 上一主题 下一主题

[C] 请教,关于指针的 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-09-26 21:34 |只看该作者 |倒序浏览
本帖最后由 max116 于 2012-09-26 21:39 编辑
  1. int map[3][3] = {1,2,3,4,5,6,1,8,9};
  2. int ** p = map;
  3. printf("%d",p[4]);
复制代码
p不是指向指针的指针吗,为什么解一次引用就够了?
而且好像不论 p 前面几颗星,结果都一样。
p[1][2] 报段错误

论坛徽章:
0
2 [报告]
发表于 2012-09-26 21:59 |只看该作者
没人回答,我明天再来好了,

论坛徽章:
11
摩羯座
日期:2013-09-16 11:10:272015亚冠之阿尔萨德
日期:2015-06-12 22:53:29午马
日期:2014-04-15 11:08:53亥猪
日期:2014-03-02 23:46:35申猴
日期:2013-12-06 22:07:00亥猪
日期:2013-11-28 12:03:13双鱼座
日期:2013-11-21 14:43:56亥猪
日期:2013-10-23 10:55:49处女座
日期:2013-10-17 18:15:43午马
日期:2013-09-27 17:40:4215-16赛季CBA联赛之青岛
日期:2016-06-22 00:45:55
3 [报告]
发表于 2012-09-26 22:01 |只看该作者
楼主,你这样写,你的编译器不报Warnings吗?

The warning says it all.

论坛徽章:
0
4 [报告]
发表于 2012-09-26 22:53 |只看该作者
int map[3][3] = {1,2,3,4,5,6,1,8,9};
int ** p = map;
printf("%d",p[4]);


在sizeof(int) 等于 sizeof(int *)的情况下,p[4]的值是 (int *)5,所以你能打印出5来。
另外,p[1]的值是 (int *)2,p[1][2]相当于访问 ((int *)2)[2],相当于强制地址访问,显然是段错误。

论坛徽章:
0
5 [报告]
发表于 2012-09-26 23:47 |只看该作者
本帖最后由 huangzhenfan 于 2012-09-26 23:51 编辑

数组的数据,在实际内存中不是按行和列实现的。是连续的排列的行,p[4] 就是map[3][4]的地址;数组已越界。即使能通过编译,输出的只会是p[3][3]后面那个地址值。C保证数组最后面元素后的一个地址值有效,但不对内容作任何保证。

论坛徽章:
0
6 [报告]
发表于 2012-09-27 00:13 |只看该作者
本帖最后由 xiaonanln_cu 于 2012-09-27 00:27 编辑
huangzhenfan 发表于 2012-09-26 23:47
数组的数据,在实际内存中不是按行和列实现的。是连续的排列的行,p[4] 就是map[3][4]的地址;数组已越界。 ...

错了,p[4]不是map[3][4]的地址,而是map[1][1]的地址,是合法的,值是5。
p被初始化为map,也就是int map[3][3]这个数组的起始地址。map数组是一个二维数组,在内存里就是9个连续的 int。p的定义是int **p,也就是一个指向int *类型的指针。p指向map,也就是个9个连续整数的空间,所以访问p相当于把这个9个整数当成9个int *指针来看待。p[4]就是访问第5个整数,也就是map[1][1]。

从编译器的角度来看,p[4]就相当于:  *(p + 4),也就是 *(int **)((unsigned int)p + sizeof(*p /* int * */) * 4),所以访问的内存地址就是map数组的起始地址 + sizeof(int) * 4的偏移。

话说回来,p正确的定义应该是:int (*p)[3]; 这样的话,p[4]就是非法的了,p[1][2]合法了。

论坛徽章:
0
7 [报告]
发表于 2012-09-27 09:26 |只看该作者
回复 3# Ager


  从微博上看来的代码,不确定答案,就编译试了下,提示是类型不匹配

论坛徽章:
0
8 [报告]
发表于 2012-09-27 09:33 |只看该作者
回复 4# xiaonanln_cu


嗯,多谢!   

论坛徽章:
2
程序设计版块每日发帖之星
日期:2015-06-17 22:20:00每日论坛发贴之星
日期:2015-06-17 22:20:00
9 [报告]
发表于 2012-09-27 09:37 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
10 [报告]
发表于 2012-09-27 09:40 |只看该作者
xiaonanln_cu 发表于 2012-09-27 00:13
错了,p[4]不是map[3][4]的地址,而是map[1][1]的地址,是合法的,值是5。
p被初始化为map,也就是int m ...


*(int **)((unsigned int)p + sizeof(*p /* int * */) * 4)   这个NB了。。。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP