鱼C论坛

 找回密码
 立即注册
查看: 1318|回复: 16

[已解决]关于指针的一个问题。

[复制链接]
发表于 2018-9-20 20:52:50 | 显示全部楼层 |阅读模式

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

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

x
课后作业size23里有个题目问下面的输出值:

#include <stdio.h>

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

        printf("%d\n", *(*(p+1)-6));

        return 0;
}
我的理解是*(p+1)不是取值的意思么,但是原array数组长度只有10,此时*11不是取不到值么?
最佳答案
2018-9-21 22:20:31
本帖最后由 moppet 于 2018-9-22 11:39 编辑

int 类型 占4个字节 长度就是
array[10] 10个int 就是10 * 4  就是 0-39 这个数组占了40个字节的内存
那就是
array[0]  0-3
array[1]  4-7
array[2]  8-11
array[3]  12-15
array[4]  16-19
array[5]  20-23
array[6]  24-27
array[7]  28-31
array[8]  32-35
array[9]  36-39

array[10] 40-43

4是int 类型的长度 每个元素之间的间隔 就是4
减去6 就等于减去6个int的间隔 所以要6*4 得到减去的总长度
指针每次+1 同等于+4 这1是给我们看的 程序在寻址的时候加的就是4 因为数据间隔是4
首地址 + 数组下标*数据类型长度 = 读取地址
总长度 - 需要减的长度 = 剩余长度 一个元素占4个字节 在除以4 得到的就是当前指向的位置了

*(P + 1)
P定义的事 array[10]   
array[10] 是10个int大小 = 40
那么P 的类型大小就是40
和上面同理 指针类型是 int 4长度的 那么指针 + 1 的时候就同等于 + 4
那么这个P 是40的长度
那么P + 1 就是 + 40的长度
36-39是array[9] 第10个元素
此时P指向的就是 40  也就是array[10] 第11个元素
*(*(P + 1) - 6) = 40(总长度) - (6个指针,每个指针指向的位置间隔是4 = 6*4=24)
此时指针指向的是 16 , 16-19 是第4个元素的地址



*(*p + 1) 和 *(*(p+1) )

*(*p + 1)
先看括号里的 *P得到的是array[0]地址 就是首地址了
然后地址 + 1  指向的就是array[1] 那么在定义这个数组的时候 是int类型
为了能正确指向1的位置 所以内部是加了4 为什么是4 上面说了 间隔
*(*p + 1) 然后读取 array[1]里面的内容  

*(*(p+1))
还是先看括号里的 是P+1  
P是 array[10]类型 总大小是 40
那就是在加1个和P类型一样大小内容出来
就好比 你把1定义成1个房子 这个房子里有N个人
然后你有把这个房子加了 1

*(p+1) 后指向的是 40的位置(;array[10] 40-43 )  每个元素占4个位置 在除以4 就得出 此时
P指向的地址是array[10]  
*(*(p+1) )然后读取这个地址的内容(array[10])

*P + 1 是加一个int的长度
P + 1 是加一个array[0-9]的长度


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

使用道具 举报

发表于 2018-9-20 23:13:44 From FishC Mobile | 显示全部楼层
嗯,跨度不为 1 的指针,可以当作是高维指针了,性质不一样啦
11,又减6,跑回来 4啦
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-9-20 23:38:00 | 显示全部楼层
claws0n 发表于 2018-9-20 23:13
嗯,跨度不为 1 的指针,可以当作是高维指针了,性质不一样啦
11,又减6,跑回来 4啦

感谢回复,意思就是我的理解没有问题,只是它最后因为减去数又回来了,所以没出错咯。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-9-20 23:58:14 From FishC Mobile | 显示全部楼层
albus12 发表于 2018-9-20 23:38
感谢回复,意思就是我的理解没有问题,只是它最后因为减去数又回来了,所以没出错咯。。

嗯,但是高维指针要注意一下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-9-21 16:38:11 | 显示全部楼层
claws0n 发表于 2018-9-20 23:58
嗯,但是高维指针要注意一下

但是我把 *(*(p+1)-6));这个改成 *(*(p)-6));和 *(*(p+2)-6));输出的值不是3和5啊?请教这是怎么回事?


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

使用道具 举报

发表于 2018-9-21 19:27:18 | 显示全部楼层
*(*(p + 1)-6) =  P + ( ( (1*40) - (6*4) ) / 4 ) = 4  = array[4]

*(*(p)-6)) = P + ( ( (0*40) - (6*4) ) / 4 ) = -6  = array[-6]

*(*(p+2)-6)) = P + ( ( (2*40) - (6*4) ) / 4 ) = 14  = array[14]
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-9-21 20:56:11 | 显示全部楼层
moppet 发表于 2018-9-21 19:27
*(*(p + 1)-6) =  P + ( ( (1*40) - (6*4) ) / 4 ) = 4  = array[4]

*(*(p)-6)) = P + ( ( (0*40) - (6* ...

感谢您的回复,想请问下*40和*4这个操作要怎么理解,为什么后来还要/4啊?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-9-21 22:20:31 | 显示全部楼层    本楼为最佳答案   
本帖最后由 moppet 于 2018-9-22 11:39 编辑

int 类型 占4个字节 长度就是
array[10] 10个int 就是10 * 4  就是 0-39 这个数组占了40个字节的内存
那就是
array[0]  0-3
array[1]  4-7
array[2]  8-11
array[3]  12-15
array[4]  16-19
array[5]  20-23
array[6]  24-27
array[7]  28-31
array[8]  32-35
array[9]  36-39

array[10] 40-43

4是int 类型的长度 每个元素之间的间隔 就是4
减去6 就等于减去6个int的间隔 所以要6*4 得到减去的总长度
指针每次+1 同等于+4 这1是给我们看的 程序在寻址的时候加的就是4 因为数据间隔是4
首地址 + 数组下标*数据类型长度 = 读取地址
总长度 - 需要减的长度 = 剩余长度 一个元素占4个字节 在除以4 得到的就是当前指向的位置了

*(P + 1)
P定义的事 array[10]   
array[10] 是10个int大小 = 40
那么P 的类型大小就是40
和上面同理 指针类型是 int 4长度的 那么指针 + 1 的时候就同等于 + 4
那么这个P 是40的长度
那么P + 1 就是 + 40的长度
36-39是array[9] 第10个元素
此时P指向的就是 40  也就是array[10] 第11个元素
*(*(P + 1) - 6) = 40(总长度) - (6个指针,每个指针指向的位置间隔是4 = 6*4=24)
此时指针指向的是 16 , 16-19 是第4个元素的地址



*(*p + 1) 和 *(*(p+1) )

*(*p + 1)
先看括号里的 *P得到的是array[0]地址 就是首地址了
然后地址 + 1  指向的就是array[1] 那么在定义这个数组的时候 是int类型
为了能正确指向1的位置 所以内部是加了4 为什么是4 上面说了 间隔
*(*p + 1) 然后读取 array[1]里面的内容  

*(*(p+1))
还是先看括号里的 是P+1  
P是 array[10]类型 总大小是 40
那就是在加1个和P类型一样大小内容出来
就好比 你把1定义成1个房子 这个房子里有N个人
然后你有把这个房子加了 1

*(p+1) 后指向的是 40的位置(;array[10] 40-43 )  每个元素占4个位置 在除以4 就得出 此时
P指向的地址是array[10]  
*(*(p+1) )然后读取这个地址的内容(array[10])

*P + 1 是加一个int的长度
P + 1 是加一个array[0-9]的长度


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

使用道具 举报

发表于 2018-9-21 22:28:17 | 显示全部楼层
albus12 发表于 2018-9-21 16:38
但是我把 *(*(p+1)-6));这个改成 *(*(p)-6));和 *(*(p+2)-6));输出的值不是3和5啊?请教这是怎 ...

抱歉,迟了,
*(*(p)-6));     // 第一层解引用,所以是基地址,-6 >> p[-6]
*(*(p+2)-6));   //跨度是 10,加 2 >> 偏移跨度为 10 两次 p[20],再 -6 >> p[14]
你这两个都是越界行为。指针是很容易越界的~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-9-21 23:09:14 | 显示全部楼层
claws0n 发表于 2018-9-21 22:28
抱歉,迟了,
*(*(p)-6));     // 第一层解引用,所以是基地址,-6 >> p[-6]
*(*(p+2)-6));   //跨度 ...

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

使用道具 举报

 楼主| 发表于 2018-9-21 23:11:39 | 显示全部楼层
moppet 发表于 2018-9-21 22:20
int 类型 占4个字节 长度就是
array[10] 10个int 就是10 * 4  就是 0-39 这个数组占了40个字节的内存
那 ...

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

使用道具 举报

 楼主| 发表于 2018-9-21 23:44:32 | 显示全部楼层
moppet 发表于 2018-9-21 22:20
int 类型 占4个字节 长度就是
array[10] 10个int 就是10 * 4  就是 0-39 这个数组占了40个字节的内存
那 ...

如果是*(*(p+1))是不是代表取第11个元素的值?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-9-21 23:54:46 | 显示全部楼层
moppet 发表于 2018-9-21 22:20
int 类型 占4个字节 长度就是
array[10] 10个int 就是10 * 4  就是 0-39 这个数组占了40个字节的内存
那 ...

还有就是*(*p+1)和*(*(p+1))分别代表什么啊,能否麻烦也用算式解答一下刚才好像懂了,一看题目就晕了

点评

无语………………………………  发表于 2018-9-21 23:56
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-9-22 00:15:48 From FishC Mobile | 显示全部楼层
albus12 发表于 2018-9-21 23:54
还有就是*(*p+1)和*(*(p+1))分别代表什么啊,能否麻烦也用算式解答一下刚才好像懂了,一 ...

真的抱歉,总是晕
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-9-22 00:18:25 | 显示全部楼层
albus12 发表于 2018-9-22 00:15
真的抱歉,总是晕

晕就不要随便给最佳答案,问个清楚明白
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-9-22 00:24:52 | 显示全部楼层
albus12 发表于 2018-9-21 23:54
还有就是*(*p+1)和*(*(p+1))分别代表什么啊,能否麻烦也用算式解答一下刚才好像懂了,一 ...

先说一下,你目前还算初学,一些坏习惯最好改掉。比如说没有空白~
不需要去管数据类型,那个太麻烦了,编译器自己会去算。你只要算有多少个元素就够了。

(*p)[10] = &array; // p 的跨度为 10

*(*p + 1);     // *p, 没有偏移,所以是首地址,偏移 1,所以是第二个元素。
*(*(p+1)) == *(*(p+1) + 0);    // 加一了,但跨度为 10,所以是第十个元素。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-25 20:04

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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