指向 "ENTER" 的'E'的地址 //则输出为"ER" printf("%s\n", *cpp[-2] + 3); //由于此时cpp → 指向cp[2] //cpp[-2]等效为*(cpp -2) //cpp-2 → 指向cp[0] //*(cpp-2)即为cp[0]; //*(cp[0])即为c[3] → 指向 "FIRST" 的首地址。
arr的数组第一个元素的取值, 并且 数组名表示的就是数组首元素的地址 那么我们可以这样理解: arr[1 ] == *(arr + 1) 同理 cpp[-2] == *(cpp - 2) *(cpp
此时也就不再指向N,而是指向E *-- * ++cpp:再解引用,得到E的地址 *-- * ++cpp + 3:得到ER printf("%s\n", *cpp[-2] + 3); cpp[-2]其实就是*(cpp -2) *cpp[-2]+3也就是 * *(cpp-2)+3 cpp-2在上面的额基础上减2,cpp不会变 *(cpp-2)通过解引用,得到c+3 **(cpp-2) 再次解引用,得到F **( cpp-2)+3 ,得到ST printf("%s\n", cpp[-1][-1] + 1); cpp[-1][-1]也就是 * (*(cpp-1)-1) 即, * (*(cpp-1)-1)+1 cpp
**++cpp); //POINT printf("%s\n", *-- * ++cpp + 3); //ER printf("%s\n", *cpp[-2] + 3); //ST - * *(cpp
printf内存布局图: printf("%s\n", *cpp[-2] + 3); *cpp[-2]不好理解拆解换算一下,cpp[-2]就是cpp+(-2)再解引用,再把原来的 * 加上就是 * * (cpp cpp-2就是cp+1+1-2,即cp。意思为cpp里的变量值-2,cp为c+3的地址,解引用拿到c+3的地址,c+3指向指向c数组里的F,再解引用拿到F的地址,+3指向S,打印结果为ST。
E的地址 (7)按字符串进行打印,所以结果是ER printf("%s\n", *cpp[-2]+3) (1)cpp中存放的是cp中的第三个元素c的地址 (2)cpp[-2]=*(cpp -2),找到了cp中的第一个元素的内容,即c的第四个元素的地址 (3)*cpp[-2]=**(cpp-2),找到了''FIRST"中F的地址 (4)*cpp[-2]+3,F的地址+3便是S的地址
++cpp + 3) 1.0s - (*-- * ++cpp + 3) printf("%s\n", *cpp[-2] + 3); cpp指向了数组cp的第三个元素,cpp[-2]等价于*(cpp cpp-2指向了数组cp的第一个元素&cp[0],解引用之后得到了cp[0],也就是数组c的第四个元素的地址c+3。
-> "ENTER",最后"ENTER"+3,从下标为三开始输出 结果: ER printf("%s\n", *cpp[-2] + 3);// ST //cpp[-2] --> *(cpp
③ printf("%s\n", *cpp[-2]+3); *cpp[-2]+3: *(cpp-2) --> *(*(cpp-2)) --> *(*(cpp-2))+3 *(cpp -2): cpp-2:就指向了cp[0],但这里不会改变cpp的值,只有自增自减的情况才会改变cpp的值,所以如下图所示,*(cpp-2)拿到了cp[0]这个元素。 *(*(cpp-2)): cp[0]的类型为char**,cp[0]指向的是c[3]这个类型为char*的指针,所以cp[0]存放的是c[3]的地址,通过解引用就拿到了c[3]这个元素。 *(*(cpp-2))+3: c[3]是一个字符指针,类型为char*,指向了“FIRST”,存放的就是"F"这个元素的地址,所以c[3]+3,指向了'S'这个字符,如下图所示: 最后以%s形式进行打印
; 原始图: 第一个 printf :请看黄色箭头: 注意现在的 cpp 指向的是 c+2; 第二个 printf :请看黑色箭头: 第三个 printf : *cpp[-2] 可以写成 **(cpp
printf(“%s\n”, *--*++cpp+3); 所以结果为 ER printf(“%s\n”, *cpp[-2]+3); 这里我们和上面一样, *cpp[-2]+3 = *(cpp 所以 cpp-2 然后再进行解引用指向的就是这里 然后再进行 +3 跳过3个字节进行打印 printf(“%s\n”, *cpp[-2]+3); 结果为 ST printf(“%s\n”, cpp[
*cpp[-2]+3 cpp[-2]等价于 *(cpp-2) 即**9cpp-2)+3 cpp在2中指向c+1 减2指向 c+3 解引用后 为c+3本身 再次解引用 为 FIRST
,从指向NEW到ENTER,这个时候加上3就是指向这个单词里面的T,所以打印TER; 这个要注意执行顺序的问题,也就是优先级,在没有+3之前,整体是从右边向左边执行的; (4)cpp[-2]等价于*(cpp
// // // // printf("%s\n", *cpp[-2] + 3);//ST //*cpp[-2]是**(cpp+(-2))就是**(cpp -2) // // 一开始cpp指向的是原先的c+1的地址,但是c+1自减了1,就成c了,那么现在cpp指向的就是c的地址了 // 那么cpp-2得到的就是c+3的地址 // 这里的cpp-2不会导致cpp的改变,还是指向c // // 那么cpp-2得到的是c+2的地址,解引用得到的就是c+3 // c+3指向的是这串字符串首元素字符F的地址
cpp[-2]等同于*(cpp-2),因此cpp[-2]指向了cp的首元素的地址,再解引用得到c的第四个元素的地址,然后+3指向了S这个元素地址。
图三原始图: cpp[-2]等价于*(cpp-2),表示访问cpp指向的元素,往前找两个位置,即cp的第一个元素,c+3, *cpp[-2]解引用得到c+3的地址.
然后我们再来看一下第三个,*cpp[-2]+3,这里cpp[-2]的意思其实就是*(cpp-2),然后由上面可得cpp此时位于c那里,然后-2就会位于c+3的位置,然后再解引用,此时会指向F这里,然后+
,即到达cp[2],–cp[2],即cp[2]从指向c[1]变成指向c[0],再解引用,到达ENTER的首地址,再+3,到达ER,即: 3)当我们执行第三个printf时,可变成: 即cpp
2.cpp[-2][1]这样的代码可以转换为(*(*cpp-2)+1)
中第三个元素的地址,解引用表示c+1,而--即 //对里面的内容c+1 -- 即为c,在解引用表示c所指向的内容,再+3即ER printf("%s\n", *cpp[-2] + 3); //即为先对*(cpp