c语言指针编程题及详解 指针

到此为止你掌握了类似&i , *pi写法嘚含义和相关操作吗总的一句话 ,我们的纸条就是我们的指针同样我们的pi也就是我们的纸条!剩下的就是我们如何应用这张纸条了 。朂后我给你一道题:

你能直接看出输出的结果是什么吗如 果你能,我想本篇的目的就达到了好了,就说到这了Happy to Study!在下篇中我将谈谈“指 针的指针”即对int * * ppa;中ppa 的理解。

3)  补充三种情况

这里, 我再补充以下三种情况其实只要上面的语义搞清楚了,这三种情况也就已经被包含了不过作为三种 具体的形式,我还是简单提一下吧!

下篇预告:函数参数的 指针传递值传递,引用传递 迷惑(以为ab已经代替叻x,y对x,y的操作就是对ab的操作了,这 是一个错误的观点啊!)

开讲之前,我先请你做三道题目(嘿嘿,得先把你的头脑搞昏才行 ……唉呀谁扔我鸡蛋?)

1.考题一:程序代码如下:

问下划线的部分应是什么请完成。

2.考题二:代码如下

问下划线的部分应是什么,請完成

问下划线的部分输出的应是什么, 请完成

你不在机子上试,能作出来吗你对你写出的答案有多大的把握?

正确的答案 想知噵吗?(呵呵让我慢慢地告诉你吧!)

好,废话少说继续我们的探索之旅了。

我们都知道:c语言指针编程题及详解中函数参数的传递囿:值传递地址传递,引用传递这三种形式题一为值 传递,题二为地址传递题三为引用传递。不过正是这几种参数传递的形式,缯把我给搞得晕头转向 我相信也有很多人与我有同感吧?

下面请让我逐个地谈谈这三种传递形式

二、函数 参数传递方式之一:值传递

1.徝传递的一个错误认识

先看题一中Exchg1函数的定义:

问:你认为这个函数是在做什么呀?

答:好像是对参数 xy的值对调吧?

请往下看我想利鼡这个函数来完成对a,b两个变量值的对调程序如下:

奇怪,明明我把ab分别代入了x,y中并在函数里完成了两个变量值的交换,为什么ab变量 值还是没有交换(仍然是a==4,b==6而不是a==6,b==4)如果你也会有这个疑问,那是因为你跟本 就不知实参ab与形参x,y的关系了

为了说明这個问题,我先给出 一个代码:

看好了没现在我问 你:最终a值是多少,x值是多少

(怎么搞的,给我这个小儿科的问题还不简单,不就昰a==4   x==7嘛!)

在这个代码中你要明白一个东西:虽然a值赋给了x,但是a变量并不是x变量哦 我们对x任何的修改,都不会改变a变量呵呵!虽嘫简单,并且一看就理所当然不过可是一个很重 要的认识喔。

看调用Exch1函数的代码:

Exchg1(a,b)时所完成的操作代码如下所示

请注意在调用执行Exchg1函數的操作中我人为地加上 了头两句:

这是调用函数时的两个隐含动作。它确实存在 现在我只不过把它显式地写了出来而已。问题一下就清晰起来啦(看到这里,现在你认为函数里面交 换操作的是ab变量或者只是x,y变量呢)

原来 ,其实函数在调用时是隐含地把实参ab 的 徝分别赋值给了x,y之后在你写的Exchg1函数体内再也没有对a,b进行任何的操作了交换的只是x, y变量并不是a,b.当然ab的值没有改变啦!函数呮是把a,b的值通过赋值传递给了xy,函数里头 操作的只是xy的值并不是a,b的值这就是所谓的参数的值传递了。

哈哈终于明白了,正是 洇为它隐含了那两个的赋值操作才让我们产生了前述的迷惑(以为a,b已经代替了xy,对xy的操 作就是对a,b的操作了这是一个错误的观點啊!)。

早在本系列第二篇中我就对指针的实质进行了阐述 今天我们又要学习一个叫做指向另一指针地址的指针。让我们先回顾一下指针的概念吧!

当我 们程序如下申明变量:

程序会 在内存某地址空间上为各变量开辟空间如下图所示。

内存地址→6     7  8      9     10     11    12    13     14    15

…  |      |  |  |  |  |  |  |  |  |

i 变量在内存地址5的位置占两个字节。

a变量在内存 地址7的位置占一个字节。

pi变量在内存地址9的位置占两个字节。(注:pi 是指针我这 里指针的宽度只有两个字节,32位系统昰四个字节)

经过上在两句的赋值变量的内存映象如下:

内存地址→6      7  8     9     10     11    12    13  14     15

…  |    50  |  |  |    6   |  |  |  |

看到没有:短整型指针变量pi的值为6,它就是I变量的内 存起始地址所以,这时当我们對*pi进行读写操作时其实就是对i变量的读写操作。如:

你可以回看本系列的第二篇那里有更加详细的解说。

二、指针的地址与指向另一指针地址的指针

在上一节中我们看到,指针变量本身与其 它变量一样也是在某个内存地址中的如pi的内存起始地址是10.同样的,我们也可能让某个指针指向这 个地址

第一句:short int * * ppi;——申明了一个指针变量 ppi,这个ppi是用来存储(或称指向)一个short int * 类型指针变量的地址

第二句: &pi那僦是取pi的地址,ppi=π就是把pi的地址赋给了ppi.即将地址值10赋值给ppi.如下图:

内存地址→6     7  8     9     10     11    12    13   14    15

…  |    50     |  |  |  6  |  10  |   |

从图中看出指针变 量ppi的内容就是指针变量pi的起始地址。于是……

ppi的值是多少呢 ——10.

*ppi的值是多少呢?——6即pi的值。

**ppi的值是多少 呢——50,即I的值也是*pi的值。

呵呵!不用我说太多了我相信你应明白这种 指针了吧!

要求:这个函数参数中的数组array是以0值为结束的字符串,要求在字符 串array中查找字符是参数search里的字符如果找到,函数通过第三个参数(pa)返回值为array字符 串中第一个找到的字符的地址如果没找到,则为pa为0.

设计:依题意实现代码如下

你觉得这个函数能实现所要求的功能吗?

我下面调用这个函数 试试

上面代码,你认为会是输出什么呢

唉!怎么输出的是:没有找到!

而不是:找到了,……

明明a值为‘d’,而str字符串的第四个字符是‘d’应该找得到呀!

依我在第五篇的分析方法,函数调用时会对每一个参数进行一个隐含的赋值操作

哦!參数pa与参数search的传递并没 有什么不同,都是值传递嘛(小语:地址传递其实就是地址值传递嘛)!所以对形参变量pa值(当然值 是一个地址值)的修改并不会改变实参变量p值因此p的值并没有改变(即p的指向并没有被改变)。

(如果还有疑问再看一看《第五篇:函数参数的传遞》了。)

主函数的调用处改如下:

这样调用函数时的整个操作变成如 下:

ppa指向指针p的地址

对*ppa的修改就是对p值的修改。

经过修改后的程序就可以完 成所要的功能了

看懂了这个例子,也就达到了本篇所要求的目的

一个通常的函数调用的例子:

这个MyFun函数是一个无返回值的函数,它并不完成什 么事情这种调用函数的格式你应该是很熟悉的吧!看主函数中调用MyFun函数的书写格式:

我们一开始只是从功能上或者說从数学意义上理解MyFun这个函数,知道 MyFun函数名代表的是一个功能(或是说一段代码)

学习到函数指 针概念时。我才不得不在思考:函数名箌底又是什么东西呢

(不要以为这是没有什么意义的事 噢!呵呵,继续往下看你就知道了)

二 函数指针变量的申明

就象某一数据变量嘚内存 地址可以存储在相应的指针变量中一样,函数的首地址也以存储在某个函数指针变量里的这样,我就 可以通过这个函数指针变量來调用所指向的函数了

在C系列语言中,任何一个变量总是要先 申明,之后才能使用的那么,函数指针变量也应该要先申明吧那又昰如何来申明呢?以上面的例子 为例我来申明一个可以指向MyFun函数的函数指针变量FunP.下面就是申明FunP变量的方法:

你看,整个函 数指针变量的申明格式如同函数MyFun的申明处一样只不过——我们把MyFun改成(*FunP) 而已,这样就有了一个能指向MyFun函数的指针FunP了(当然,这个FunP指针变量也可以指向所有其它 具有相同参数及返回值的函数了)

三 通过函数指针变量调用函数

有了FunP指针变量后 ,我们就可以对它赋值指向MyFun然后通过FunP来調用MyFun函数了。看我如何通过FunP指针变量来调 用MyFun函数的:

请看黑体字部 分的代码及注释

运行看看。嗯不错,程序运行得很好

哦,我的感覺是:MyFun与 FunP的类型关系类似于int 与int *的关系函数MyFun好像是一个如int的变量(或常量),而FunP则像 一个如int *一样的指针变量

四 调用函数的其它书 写格式

函数指针也可如下使用,来完成同样的事情:

我改了黑 体字部分(请自行与之前的代码比较一下)

运行试试,啊!一样地成功

可以这樣将MyFun值同赋值给FunP,难道MyFun与FunP是同一数据类型(即 如同的int 与int的关系)而不是如同int 与int*的关系了?(有没有一点点的糊涂了)

看 来与之前的代碼有点矛盾了,是吧!所以我说嘛!

请容许我暂不给你解释继续看以下几种情况 (这些可都是可以正确运行的代码哟!):

(哇 !真是偠晕倒了!)

你也许第一次见到吧:函数名调用也可以是这样写的啊!(只不过 我们平常没有这样书写罢了。)

那么这些又说明了什么呢?

呵呵!依据以往的知识和 经验来推理本篇的“新发现”我想就连“福尔摩斯”也必定会由此分析并推断 出以下的结论:

1. 其实,MyFun的函數名与FunP函数指针都是一样的即都是函数指针。MyFun 函数名是一个函数指针常量而FunP是一个函数数指针变量,这是它们的关系

2. 但函数名调 用洳果都得如(*MyFun)(10);这样,那书写与读起来都是不方便和不习惯的所以c语言指针编程题及详解的设计者们 才会设计成又可允许MyFun(10);這种形式地调用(这样方便多了并与数学中的函数形式一样,不是吗 )。

3. 为统一起见FunP函数指针变量也可以FunP(10)的形式来调用。

上述代碼的写法随便你爱怎么着!

请 这样理解吧!这可是有助于你对函数指针的应用喽!

补充说明一点 :在函数的申明处:

(请看注释)这一點 是要注意的。

五 定义某一函数的指针类型:

就像自定义数据类型一样我们也可以先定 义一个函数指针类型,然后再用这个类型来申明函数指针变量

我先给你一个自定义数据类型的 例子。

根据注释应该不难看懂吧!(虽然你可能很少这样定义使用,但以后学习Win32编程时會经常见到的 )

下面我们来看一下函数指针类型的定义及使用:(请与上对照!)

其它相同。整个程序完成了相同的事

有了FunType类型后 ,峩们就可以同样地、很方便地用FunType类型来申明多个同类型的函数指针变量了如下:

六 函数指针作为某个函数的参数

既然函数指针变量是一個变量,当然也可以作为某个函数的参数来使用的所以 ,你还应知道函数指针是如何作为某个函数的参数来传递使用的

要求 :我要设計一个CallMyFun函数,这个函数可以通过参数中的函数指针值不同来分别调用MyFun1、MyFun2 、MyFun3这三个函数(注:这三个函数的定义格式应相同)

分析:(看峩写的注释。你可按我注释的①②③④⑤顺序自行 分析)


我要回帖

更多关于 c语言指针编程题及详解 的文章

 

随机推荐