对指针的概念清晰的话,做这种题只要耐心就行,然而看这种题就烦(被同学吐槽为谭浩强的阴影……草泥马这种C风格题有意义吗?出题人脑子被门夹了?而且C++11都不支持字面值字符串直接转换成char*了。好吧,就算要大骂一通出题人,该做还是做。)

分析三行初始化代码:

1、c[0]指向"HELLO",c[1]指向"NEW",c[2]指向"WORLD",c[3]指向"SAYHI"。

cp[0]=c+3,即cp[0]=&c[3],因此

2、cp[0]指向c[3],cp[1]指向c[2],cp[2]指向c[1],cp[3]指向c

cpp=cp,cp类型是char**[4]类型,数组a在作为等号的右参数时会降格成&a[0],因此cpp=&cp[0]

3、cpp指向cp[0]

现在到这里来一个个分析语句

1、**++cpp

++cpp,即cpp=cpp+1  【改变了cpp的值】

指针+1是怎么运算呢?这里我还卡住了

举例,int a[] = { 1,2,3 }; int* p = a; p++;  这里p是int*的指针,p++就指向了a[1],相当于p指向的地址向后移动了sizeof(*p)个字节。

OK,cpp指向cp[0],++cpp就是cpp=&(cp[0]+sizeof(*cpp))即cpp=&cp[1];

接着就是2次解引用,*++cpp就是*(&cp[1])也就是cp[1],**++cpp就是*cp[1]=*(&c[2])即c[2],结果是

WORLD

注意!这里的运算改变了cpp的值!这一句执行后cpp指向的是cp[1]!

2、*--*++cpp+3

注意+运算优先级是低于*、&、前置++、前置--(这4个同级)。

++cpp = &cp[2]   【改变了cpp的值】

*++cpp = *(&cp[2])即cp[2]

--*++cpp = --cp[2] = &(c[1]-sizeof(c[1])) = &c[0]。

*--*++cpp = *(&c[0]) = c[0],最后c[0]+3

LO

注意!这里的运算改变了cpp的值!这一句执行后cpp指向的是cp[2]!

3、*cpp[-2]+3

注意[]运算优先级是高于*、&、前置++、前置--

这里回顾数组下标运算符[]:int a[] = { 1,2,3 }; int p = a[1]; 即int p = *(a + 1)

cpp[-2] = *(cpp-2) = *&(cp[2]-2*sizeof(cp[2])) = *&cp[0] = cp[0]

*cpp[-2] = *cp[0] = *(c+3) = c[3]

*cpp[-2]+3即

HI

注意!这里的运算并未改变cpp的值!这一句执行后cpp指向的是cp[2]!

4、cpp[-1][-1]+1

cpp[-1] = *(cpp-1) = *&(cp[2]-sizeof(cp[2]) = *&cp[1] = cp[1]

cpp[-1][-1] = *(cp[1]-1) = *(c+2-1) = *(c+1) = c[1]

cpp[-1][-1]+1 = c[1]+1即

EW

呼,做完了还是想骂一句草泥马=_,=

C指针笔试题,蛋疼的多重指针运算,谭浩强的阴影的更多相关文章

  1. 关于指针的笔记【1】【C语言程序设计-谭浩强】

    指针是什么? 一个 变量的地址称为该变量的"指针"[将地址形象化的称为“指针”].(指针是什么百度百科) 注意区分储存单元的地址和内容这两个概念的区别. 直接访问:直接按变量名进行 ...

  2. 听翁恺老师mooc笔记(6)--指针运算

    指针值加1就是将指针值加上sizeof(指针所指变量的类型) 1+1=2,那么指针加1是加上了1这个数字吗?试一下,在代码中定义了char数组,char也是整数,数组名是ac,ac中有10个元素,0- ...

  3. 娓娓道来c指针 (7)指针运算

    (7)指针运算 在前几篇文章中,我们已经见过指针运算的使用场景,并多次使用指针运算来进行验证. 这里我们来特别地总结下.指针运算的本质含义. 在c语言中.如果p.pa.pb都是某种类型的指针,这种运算 ...

  4. 10深入理解C指针之---指针运算和比较

    该系列文章源于<深入理解C指针>的阅读与理解,由于本人的见识和知识的欠缺可能有误,还望大家批评指教. 指针运算有很多种,主要有指针的声明*.指针的解引*.指针指向(*).或->.指针 ...

  5. Go的内存对齐和指针运算详解和实践

    uintptr 和 unsafe普及 uintptr 在Go的源码中uintptr的定义如下: /* uintptr is an integer type that is large enough t ...

  6. C 与 C++ 中 指向二维数组的指针进行指针运算

    二维数组在概念上是二维的,有行和列,但在内存中所有的数组元素都是连续排列的,它们之间没有"缝隙".以下面的二维数组 nums 为例: 从概念上理解,nums 的分布像一个矩阵,但在 ...

  7. 剑指offer--面试题14--收获

    按照作者的说法,作为应届毕业生的我来说,如果能写出初级程序员的参考代码来解决面试题14就可认为过关了... 参考代码如下: void ReorderOddEven_1(int *pData, unsi ...

  8. 剑指offer--面试题5

    到现在为止,看过的书+代码有一定量了,并且也参加了个比赛,给自己的总体感觉:编程需要的是灵活的头脑,书里的东西只是讲个规则.思想,其实际实现可以千差万别!   潜在的规则+灵活的思维 = 程序! 在做 ...

  9. 剑指offer-面试题16.反转链表

    题目:定义一个函数,输入一个链表的头结点,反转该链表并输出反转后的头结点 链表结点定义如下: struct ListNode { int m_nKey; ListNode* m_pNext; } 其实 ...

随机推荐

  1. 关于Arch Linux efibootmgr 命令行参数问题

    相关链接: https://wiki.archlinux.org/index.php/EFISTUB 今天安装Arch Linux 在 efibootmgr创建启动项时,总是提示 UUID=xxxx ...

  2. DBLookupComboBox 的初始值

    http://www.yourdelphi.com/topic_234544_e6b7.htm 试下在form的oncreate中加入 dblookupcombobox1.keyvalue:=tabl ...

  3. 读书笔记 C# Linq查询之group关键字浅析

    在C#中,自从有了Linq查询表达式后,程序员对可被迭代的序列或列表执行一系列的筛选.排序.过滤.分组.查询等操作.本文章所要讲述的是group关键字. Linq查询表达式,是以from关键字开头,以 ...

  4. C标准中一些预定义的宏,如__FILE__,__func__等

    C标准中一些预定义的宏 C标准中指定了一些预定义的宏,对于编程经常会用到.下面这个表中就是一些常常用到的预定义宏. 宏 意义 __DATE__ 进行预处理的日期(“Mmm dd yyyy”形式的字符串 ...

  5. SQL2012 创建备份计划

    打开数据库,选择 管理 -> 新建维护计划,填写计划名称 修改计划参数 工具箱->备份数据库任务,拖到计划里 编辑任务 拖动清除数据库任务到计划 编辑清除任务 从备份任务到清除任务拖一个箭 ...

  6. PostgreSQL角色和权限理解

    1.继承的权限只是继承该组的表的权限,用户对应的管理员权限则不会被继承. 2.inherit权限是说本角色是否继承别人的权限,而不是本权限能否被别的角色继承.   postgres=# create ...

  7. Linux 系统信息查询

    众所周知,Linux大部分操作是通过命令实现的,并不像windows那么直观.linux查看硬件信息也是需要通过linux查看硬件信息命令查询的,下面小编来分享一下linux查看硬件信息的方法和命令写 ...

  8. Myecilpse web +tomcat 项目: JSP在mysql中创建表

    <%@ page language="java" import="java.util.*" import="com.mysql.jdbc.Dri ...

  9. Redis学习第四课:Redis List类型及操作

    list是一个链表结构,主要功能是push.pop.获取一个范围的所有值等,操作中key理解为链表的名字. Redis的list类型其实就是一个每个子元素都是string类型的双向链表.我们可以通过p ...

  10. UML-(团队作业)

    UML设计 1.团队信息: 队名:异次元 2.团队成员: 姓名 分配任务 王诚荣(队长) 汇总合并,系统活动图 马祎特 好感度系统类图,电子版图片绘制 陈斌 个人中心,闹钟界面用例图,状态图 洪康 后 ...