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

本文详细介绍了C语言中各种指针的应用,包括指向函数的指针、指向指针的指针、指向指针数组的指针等。通过具体示例展示了如何使用这些指针以及它们在实际编程中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

 

指向函数的指针指向指针的指针指向指针数组的指针指向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 指针来取出一个变量值。

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值