菜鸟C++自学笔记【指针】下

it2022-05-09  26

继续上篇指针未完成的学习任务。

 

指向函数的指针指向指针的指针指向指针数组的指针指向const 变量的指针const 指针变量void 指针

1.指向函数的指针

指向函数的指针包含函数的地址,可以通过指针调用该函数。下面这种格式声明了一个函数指针:

int (*fpt)();

 

指针的名字是fpt。这个特殊的指针指向一个返回整数值并且不接受实参的函数。指针声明必须与指针所指函数的声明相匹配。

下面的DEMO表明,一个函数指针在不同时段可以具有不同的函数地址:

 

#include  " stdafx.h " #include  < iostream > void  FileFunc(),EditFunc(); int  main( int  argc,  char *  argv[]){      void  ( * fileTmp)();  // 声明一个指针函数      fileTmp = FileFunc;   // 指向函数的地址     ( * fileTmp)();     // 通过指针调用函数     fileTmp = EditFunc;   ( * fileTmp)();     return   0 ;} void  FileFunc(){    std::cout << " File Function\n " ;}  void  EditFunc(){    std::cout << " Edit Function\n " ;}

 

 

运行效果如下:

通过使用函数指针的数组,可以创建一个有限状态机,程序行为取决于变量的值,根据变量值确定程序接下来执行哪个函数。表格驱动的菜单管理程序就是一个有限状态机的例子。

如下DEMO演示了如何通过4个原型菜单分别显示一条消息:

 

#include  " stdafx.h " #include  < iostream > struct  Menu{     char *  name;     void  ( * fn)();}; void  FileFunc(); void  EditFunc(); void  ViewFunc(); void  ExitFunc();Menu menu[] = {    { " File " ,FileFunc},    {         " Edit " ,ExitFunc    },    {         " View " ,ViewFunc    },    {         " Exit " ,ExitFunc    }}; const   int  sels = sizeof  menu / sizeof (Menu); int  main( int  argc,  char *  argv[]){    unsigned sel = 0 ;     while (sel != sels){         for  ( int  i = 0 ;i < sels;i ++ )        {            std::cout << i + 1 << " : " << menu[i].name << " \n " ;        }        std::cout << " select: " ;        std::cin >> sel;          if (sel < sels + 1 && sels > 0 )        {            ( * menu[sel - 1 ].fn)();        }    }     return   0 ;} void  FileFunc(){    std::cout << " File Function \n " ;} void  EditFunc(){    std::cout << " Edit Function \n " ;} void  ViewFunc(){    std::cout << " View Function \n " ;} void  ExitFunc(){    std::cout << " Exit Function \n " ;}

 

 

运行效果:

 

2.指向指针的指针

指向指针的指针可能不太容易处理。需要两个星号声明指针。如下所示:

char** opp;

可以由此类推,三个四个等多个星星,对应指向几个指针的指针。

下面有一个DEMO演示如何使用一个被调用函数修改调用函数的局部指针,并处理指针数组:

 

#include  " stdafx.h " #include  < iostream > void  FindCredit( float **  fpp);  int  main( int  argc,  char *  argv[]){     float  values[] = {         34.23 , 87.33 , 46.33 , - 23.44 , 85.34 , 0     };      float *  fp = values;    FindCredit( & fp);    std::cout <<* fp << " \n " ;     return   0 ;}  void  FindCredit( float **  fpp){     while ( ** fpp != 0 ){         if ( ** fpp < 0 )        {             break ;        }         else         {            ( * fpp) ++ ;        }    }}

 

 

运行效果如下:

 

上面程序用数组地址初始化fp 指针,并把fp 指针的地址传递给FindCredit函数,该函数将指向指针的指针作为其唯一形参的实参。FindCredit用**fpp表达式间接地提取数组元素值。FindCredit函数递增调用函数指针向数组的指针,而不是递增自己指向调用函数指针的局部指针,以便在数组的循环访问中查找负值。(*fpp)++;语句的含义是递增指针形参所指定的内容,。而当遇到负值则跳出循环体。程序结束。

3.指向指针数组的指针

指向指针的指针的另一种用法是处理指针数组。

下面的DEMO演示了如何通过指向指针数组的指针打印出数组内容:

 

#include  " stdafx.h " #include  < iostream >   char *  Names[] = {     " Bill " ,     " Sam " ,     " Jim " ,     " Charles " ,     " Donald " ,     0 };  int  main( int  argc,  char *  argv[]){      char **  nm = Names;     while ( * nm != 0 ){        std::cout <<* nm ++<< " \n " ;    }     return   0 ;} 

 

 

运行效果如下:

如上代码,把nm 指针初始化为字符指针数组Names的地址。每个std::count调用都传递nm指针所指的字符指针,然后递增指针,指向数组的下一个元素(指针)。

 

4.指向const变量的指针

当我们声明一个指向const 变量的指针时,意味着程序不能通过指针修改变量。声明形式如下:

const char* str;

任何对str指针所指字符数据的引用必须为只读的。这种用法有几层含义。首先,不能将一个const 变量的地址赋予指针,除非指针按上面的方式声明。此外,如果函数的某个形参被声明为指向一个非const 的变量指针,就不能把const 变量的地址对应该形参的实参传递给函数。看如下DEMO:

 

#include  " stdafx.h " #include  < iostream >   void  cpytoupper( char *  s1, const   char *  s2){     char *  s = s1;    std::cout << " const : " << s2 << " \n " ;     }  int  main( int  argc,  char *  argv[]){         char *  rcv = " terry " const   char  snd[] = " Hello, terry " ; cpytoupper(rcv,snd); std::cout << rcv << " \n " ;      return   0 ;} 

 

运行效果如下:

 

5.const指针变量

我们可以定义在初始化后就不能改变自身内容的指针,这种做法可以增加代码的安全性。如果指针永远不用于迭代,换言之,如果这个指针永远保持其初始值,就按下面的方式将其声明为const指针变量:

char* const ptr=buf;

这里就不细究了。

 

6.void 指针

void 指针可以指向任何类型的变量,其声明方式如下:

void* vptr;

任何地址都可以赋给void 指针,除非使用了类型强型转换,否则就不能用void 指针来取出一个变量值。

关于指针的学习,暂时到这里,以后再回头来加深下理解。

转载于:https://www.cnblogs.com/TerryBlog/archive/2010/10/25/1860471.html

相关资源:数据结构—成绩单生成器

最新回复(0)