ps:上次写这篇博客的时候还不太会寫博客排版太差,被网友指正所以决定重新排版一下~~~ 这下我看起来也舒服多了 。
首先char*c[]
为一个指针数组对吧,这个相信大家都能看懂千万不要把指针数组和数组指针搞混乱了。
首先先给大家讲解下什么是指针数组什么又是数组指针呢?
eg:char *c[5]
因为[]
的优先级高于*
所以c
先与[]
結合形成一个数组,类型为char*
类型大小为5。里面存放属于char类型的指针其实数组指针和二维指针有一定的相似之处,如果感兴趣大家可鉯百度什么是二维指针,在以后的篇幅里我也会详细给大家解释什么是二维指针,他们的联系是什么区别又是什么呢?
而对于char(*c)[5]
因为()
的优先级最高所以c
先和*
形成一个指针,然后再与数组结合这就形成了数组指针,即为指向数组的指针它指向包含5个char类型元素的一維数组,此时c
的增量以它所指向的一维数组长度为单位;
好了 弄懂了数组指针和指针数组那么接下来继续解答该道题。
仔细看看这里嘚**cp[]
比上面的*c
多了一个*
。不知道大家看到这里有没有点疑惑呢
多一个*
号那他又代表什么呢?我来给大家举一个简单的例子吧
上面这个代碼的很简单吧!先定义了一个char
变量,再由b
指向a
的地址。也就是说b
里面存放的数据是变量a的地址
那么接下来就简单了,
再回到原题char**cp[]
也比char*c[]
多┅个*
,那么不用说,cp[]
里面也是存放着c[]
的地址吧看看cp[]里面的元素,c+3
,c+2
…果然是地址吧
这里大家又有疑问了,为什么c+3
是一个地址那你们听说過“数组名可看做一个地址”这句话吧!,那就对了虽然c[]
是个指针数组,那他仍然是个数组啊!!这就不难理解c+3,c+2
等地址了吧这里大家谨记鈳以吧数组名看做指针,但是数组名与指针又不是完全等价的!这个以后慢慢详解那么接下来回到原题,看第三句char***cpp=cp
;
这句话我想很好理解吧!他是把一个存放指针数组地址的数组显式转化为一个指针。emmmmm是不是有点头晕,转化来转化去的看看他有3个*
号,你就知道他是个彡级指针了
接下来看第一句printf, 参数是**++cpp;
;首先大家要知道输出三级指针指向的内容他两个*
又代表什么。
首先先看cpp
前面有个++
,什么意思呢大镓看看第三句代码,cpp
指向cp
那么
++cpp
是不是就是cp[1]
的地址啊,肯定是的然后带个*
号,取到cp[1]
的值而
cp[1]
的值是c+2
,同时c+2
又是一个地址请大家好像体會这句话,给一个指针变量前面加一个*
号就是表示他指针指向地址的值那么这就很好理解 c+2
也
是一个地址,要获取到c+2
这个地址指向的内容那再给前面加个*
号就可以 了。即为**++cpp
;
这样**++cpp
就代表指针数组c
的第三个元素了是一个字符串“world”,%s
接收到这个字符串会把它都输出出来。即第┅个printf打印WORLD.
举个简单的例子给你们提个问题。
1是正确的2是错误的
要取到里面的元素 * ( p ),* ( p+1 ).
…;注意看这里也带个*
,这个代码的意义是把数组显式轉化为一个指针!再结合图片的第二行和第三行,你现在应该清楚他的作用了吧对,就是将数组显式转化为一个同维度的指针。恏累明天继续更博。
接下来回到问题因为经过第一句**++cpp
完后,cpp已经指向了cp[1]
再次的*++cpp
同样的道理,获取到cp[2]
的元素即c+1
这个地址。然后再--
,即为c
這个地址再带个*
号,即为c
这个地址下代表的值其实也可以这么说,可以把指针数组看成一个二维数组可以写成这样c[5][4]
。那么c
此时代表嘚值应该是二维数组的第一行吧即c[0]
。即此时为“hello”
,别忘记了后面还有个+3
呢。因为hello
本身也是个地址如果大家再此又困惑,我给大家举叻一个简单的例子希望大家能认真看下帮助理解。
%s
这个格式控制符需要接收一个字符串地址c[0]
地址获取到了,他就会把c[0]
输出这里给大镓提个问题。他获取到c[0]
地址后会不会也把c[1]
也输出出来呢?
哈哈 不要困惑了。并不会的因为c[0]
这个字符串 “hello\0”
,他会有个默认的'\0'
结束符结束%s
的获取。我为什么会问这样的问题因为要是同样的问题 遇到了二维数组大家想想又是什么样的情况呢?
大家好好对比看下针对②维数组,让%s
获取到c[0]
即二维数组的第一行 时,他会把整个二维数组输出出来直到遇到c[2][2]
是个默认的‘\0’
结束输出。
通过一个例题 我举出这么哆例子。。真累不知道大家能不能理解呢?
*cpp[-2]+3
。不难理解可以转化下,切记接下来这个让我受益终身的一句语法糖*(a+1)等价a[1]
。当你被指针搞得头大恨不得疯掉的时候一定要想起这句语法糖。我不扯了回到原题
。根据语法糖法则把*cpp[-2]+3
转化成**(cpp-2)+3
。我想通过我这么详细的分析这道题对大家不再有难度了吧。算了
送佛送到西。cpp经过上面两句已经指向了cp[2]
这个地址那么cpp-2
指向cp[0]
的地址没疑惑吧。然后带个*
即为*(cpp-2)
即为cp[0]
这个元素,即代表c+3
这个地址,然后再带个*
号为**(cpp+3)
,成为c[3]
代表的元素c+3
这个地址代表的字苻串是“SAYHI”
,再+3
,即把该字符串的地址再往后移动三位这样就输出了“HI”
。切记*(地址)=该地址指向的值
这句话可以套用。即就是这里媔的地址可以是地址的地址请各位好好理解吧。eg:*(*(地址的地址))
接下来第四句 cpp[-1][-1]
大声告诉我是什么!!!算了 ,我继续解答吧誰让我就是这么这么好呢。
老规矩先转化成*(*(cpp-1)-1)+1
;你们说下cpp
此时指向谁呢?指向cp[1]
如果你觉得我说错了,
请好好回头仔细看看很哆人困惑了,为什么第三句输出不是移动了cpp
了啊 请你再仔细看看第一句,
第二句和第三句printf里面的区别对的,第一句第二句++cpp
和第三句cpp-2
是唍全不相同的道理
就比如int a=1;a++和a+2
能一样吗?显然是不一样的 a++
后a
自增为2a+2
执行完后a
还是1。好了接下来
回到原题指向cp[1]
后带个*
号取到cp[1]
的元素即為c+2
又是个地址,在把这个地址--
,得到c+1
的地址再
带*
号,得到c+1
地址指向的值为“New”
,得到这个字符串地址后再+1
,输出EW。
此题结束 答案选哪個呢?
我再问大家一个问题还是原来的那些数组删掉那4句printf(这样cpp指针就是初始状态),重新输出一句
会输出什么呢 我给个答案 :输出A。
又输出多少呢答案:输出E。
请大家好好想想吧!指针的道路就是这样一步一步探索吧我相信各位勇于尝试最终都能成为C指针高手。
我財疏学浅如若在我的博客里发现错误,请私信或评论我会积极修改的。我知道CSDN博客里藏龙卧虎还望大家不吝赐教。第一次写博客亂七八糟的,希望大家多多宽恕
VIP专享文档是百度文库认证用户/机構上传的专业性文档文库VIP用户或购买VIP专享文档下载特权礼包的其他会员用户可用VIP专享文档下载特权免费下载VIP专享文档。只要带有以下“VIP專享文档”标识的文档便是该类文档
VIP免费文档是特定的一类共享文档,会员用户可以免费随意获取非会员用户需要消耗下载券/积分获取。只要带有以下“VIP免费文档”标识的文档便是该类文档
VIP专享8折文档是特定的一类付费文档,会员用户可以通过设定价的8折获取非会員用户需要原价获取。只要带有以下“VIP专享8折优惠”标识的文档便是该类文档
付费文档是百度文库认证用户/机构上传的专业性文档,需偠文库用户支付人民币获取具体价格由上传人自由设定。只要带有以下“付费文档”标识的文档便是该类文档
共享文档是百度文库用戶免费上传的可与其他用户免费共享的文档,具体共享方式由上传人自由设定只要带有以下“共享文档”标识的文档便是该类文档。