函数调用数据传递都会复制一份副本,函数直接改变的是副本,函数结束后会丢弃,只有间接访问才会改变外部变量值。
对于第一题中你标注的1的描述是正确的。s和t是p和q的副本,交换st不影响pq。
第二题中,你要注意多级指针与普通指针的区别,你不能将二级指针理解为s指针指向了i,s是主函数中r的副本,r->p->i,对比第一题的p和q,他们是p->i,q->j。是不是多了一层关系?所以s和r一样,s->p->i,指向的是p。
r传递给函数后,函数得到r的副本s,此时函数内定义了一个局部指针t指向全局变量k,即t->k。
然后将 t 赋值给s指向的变量。
重点就在这里,注意左值是*s不是s,如果左值为s,则赋值后改变s的值,但那是无法编译的,因为s是二级指针,且是r的副本, 因为r->p,所以s->p,,t是一级指针,与p一个层次。
*s的意思是s所指地址中的值,也即所指向的变量,由于s是二级指针,它所指的是p,p是一级指针,因为s->p,所以*s=t意思并非赋值给s而是通过s间接将K的地址(t->k)赋值给了p,叫间接访问,这也就是为什么指针即方便又不安全的原因,它带来了灵活性但破坏的封装或增加了耦合。
指针本来就搞,二级指针更费脑子,所以有点啰嗦哦,怕说不明白。
两道题不矛盾,都是对的。
注意这里的差别,第二题使用了二维指针!
你对第二的理解有误,首先,作为指针参数,r的地址不会被改变,被改变的是*r,而*r原本是p的地址,因此就改变了二维指针中一维的指向。
这两道题对比看,恰恰是解释了二维指针参数的作用:指针作为参数,指针的地址不会被改变,改变的是指针里面的数值,因此需要改变指针地址,需要使用一个保存指针地址的指针(指向指针的指针),也就是二维指针。
这是由于第二题是二维指针,第一题是一维指针。
指针存储的是地址,作为函数形参只有通过地址操作,指针变量指向的值才会改变。而不是说和指针相关的操作都会改变指针指向。
第一题操作时并没有用到地址,而是直接用指针变量操作,这样做和普通变量效果没什么区别。
第二题是二维指针,存储的是一维指针的地址,题里面操作时是通过地址(一维指针)操作的,所以指针指向改变了。
这两题中,函数调用传递的都是形参。第二题中,函数f里面改变了形参s所指向的地址的内容,也就是说,r原来指向的是p,调用的时候,f将这个地址的内容给改变了,也就是p的内容,所以答案是D。
这里要注意指针和指针指向的内容的区别,你画个图就好理解了