繼續上篇指針未完成的學習任務。
指向函數的指針
指向指針的指針
指向指針數組的指針
指向const 變量的指針
const 指針變量
void 指針
指向函數的指針包含函數的位址,可以通過指針調用該函數。下面這種格式聲明了一個函數指針:
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個原型菜單分别顯示一條消息:
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);
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)();
std::cout<<"File Function \n";
std::cout<<"Edit Function \n";
void ViewFunc(){
std::cout<<"View Function \n";
void ExitFunc(){
std::cout<<"Exit Function \n";
運作效果:
指向指針的指針可能不太容易處理。需要兩個星号聲明指針。如下所示:
char** opp;
可以由此類推,三個四個等多個星星,對應指向幾個指針的指針。
下面有一個DEMO示範如何使用一個被調用函數修改調用函數的局部指針,并處理指針數組:
void FindCredit(float** fpp);
float values[]={
34.23,87.33,46.33,-23.44,85.34,0
};
float* fp=values;
FindCredit(&fp);
std::cout<<*fp<<"\n";
void FindCredit(float** fpp){
while(**fpp!=0){
if(**fpp<0)
break;
else
(*fpp)++;
上面程式用數組位址初始化fp 指針,并把fp 指針的位址傳遞給FindCredit函數,該函數将指向指針的指針作為其唯一形參的實參。FindCredit用**fpp表達式間接地提取數組元素值。FindCredit函數遞增調用函數指針向數組的指針,而不是遞增自己指向調用函數指針的局部指針,以便在數組的循環通路中查找負值。(*fpp)++;語句的含義是遞增指針形參所指定的内容,。而當遇到負值則跳出循環體。程式結束。
指向指針的指針的另一種用法是處理指針數組。
下面的DEMO示範了如何通過指向指針數組的指針列印出數組内容:
char* Names[]={
"Bill",
"Sam",
"Jim",
"Charles",
"Donald",
char** nm=Names;
while(*nm!=0){
std::cout<<*nm++<<"\n";
如上代碼,把nm 指針初始化為字元指針數組Names的位址。每個std::count調用都傳遞nm指針所指的字元指針,然後遞增指針,指向數組的下一個元素(指針)。
當我們聲明一個指向const 變量的指針時,意味着程式不能通過指針修改變量。聲明形式如下:
const char* str;
任何對str指針所指字元資料的引用必須為隻讀的。這種用法有幾層含義。首先,不能将一個const 變量的位址賦予指針,除非指針按上面的方式聲明。此外,如果函數的某個形參被聲明為指向一個非const 的變量指針,就不能把const 變量的位址對應該形參的實參傳遞給函數。看如下DEMO:
void cpytoupper(char* s1,const char* s2)
char* s=s1;
std::cout<<"const :"<<s2<<"\n";
char* rcv="terry";
const char snd[]="Hello, terry";
cpytoupper(rcv,snd);
std::cout<<rcv<<"\n";
我們可以定義在初始化後就不能改變自身内容的指針,這種做法可以增加代碼的安全性。如果指針永遠不用于疊代,換言之,如果這個指針永遠保持其初始值,就按下面的方式将其聲明為const指針變量:
char* const ptr=buf;
這裡就不細究了。
void 指針可以指向任何類型的變量,其聲明方式如下:
void* vptr;
任何位址都可以賦給void 指針,除非使用了類型強型轉換,否則就不能用void 指針來取出一個變量值。
關于指針的學習,暫時到這裡,以後再回頭來加深下了解。
本文轉自 terry_龍 51CTO部落格,原文連結:http://blog.51cto.com/terryblog/410426,如需轉載請自行聯系原作者