albus12 发表于 2018-9-20 20:52:50

关于指针的一个问题。

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

#include <stdio.h>

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

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

      return 0;
}
我的理解是*(p+1)不是取值的意思么,但是原array数组长度只有10,此时*11不是取不到值么?

claws0n 发表于 2018-9-20 23:13:44

嗯,跨度不为 1 的指针,可以当作是高维指针了,性质不一样啦{:10_256:}
11,又减6,跑回来 4啦

albus12 发表于 2018-9-20 23:38:00

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

感谢回复,意思就是我的理解没有问题,只是它最后因为减去数又回来了,所以没出错咯。。

claws0n 发表于 2018-9-20 23:58:14

albus12 发表于 2018-9-20 23:38
感谢回复,意思就是我的理解没有问题,只是它最后因为减去数又回来了,所以没出错咯。。

嗯,但是高维指针要注意一下

albus12 发表于 2018-9-21 16:38:11

claws0n 发表于 2018-9-20 23:58
嗯,但是高维指针要注意一下

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


moppet 发表于 2018-9-21 19:27:18

*(*(p + 1)-6) =P + ( ( (1*40) - (6*4) ) / 4 ) = 4= array

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

*(*(p+2)-6)) = P + ( ( (2*40) - (6*4) ) / 4 ) = 14= array

albus12 发表于 2018-9-21 20:56:11

moppet 发表于 2018-9-21 19:27
*(*(p + 1)-6) =P + ( ( (1*40) - (6*4) ) / 4 ) = 4= array

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

感谢您的回复,想请问下*40和*4这个操作要怎么理解,为什么后来还要/4啊?{:10_266:}

moppet 发表于 2018-9-21 22:20:31

本帖最后由 moppet 于 2018-9-22 11:39 编辑

int 类型 占4个字节 长度就是
array 10个int 就是10 * 4就是 0-39 这个数组占了40个字节的内存
那就是
array0-3
array4-7
array8-11
array12-15
array16-19
array20-23
array24-27
array28-31
array32-35
array36-39

array 40-43

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

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



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

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

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

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

*P + 1 是加一个int的长度
P + 1 是加一个array的长度


claws0n 发表于 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,再 -6 >> p
你这两个都是越界行为。指针是很容易越界的~

albus12 发表于 2018-9-21 23:09:14

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

感谢回复!

albus12 发表于 2018-9-21 23:11:39

moppet 发表于 2018-9-21 22:20
int 类型 占4个字节 长度就是
array 10个int 就是10 * 4就是 0-39 这个数组占了40个字节的内存
那 ...

清晰明了!谢谢!

albus12 发表于 2018-9-21 23:44:32

moppet 发表于 2018-9-21 22:20
int 类型 占4个字节 长度就是
array 10个int 就是10 * 4就是 0-39 这个数组占了40个字节的内存
那 ...

如果是*(*(p+1))是不是代表取第11个元素的值?

albus12 发表于 2018-9-21 23:54:46

moppet 发表于 2018-9-21 22:20
int 类型 占4个字节 长度就是
array 10个int 就是10 * 4就是 0-39 这个数组占了40个字节的内存
那 ...

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

albus12 发表于 2018-9-22 00:15:48

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

{:10_266:}真的抱歉,总是晕

claws0n 发表于 2018-9-22 00:18:25

albus12 发表于 2018-9-22 00:15
真的抱歉,总是晕

晕就不要随便给最佳答案,问个清楚明白

claws0n 发表于 2018-9-22 00:24:52

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

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

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

*(*p + 1);   // *p, 没有偏移,所以是首地址,偏移 1,所以是第二个元素。
*(*(p+1)) == *(*(p+1) + 0);    // 加一了,但跨度为 10,所以是第十个元素。
页: [1]
查看完整版本: 关于指针的一个问题。