天天看點

菜鳥C++自學筆記【指針】下

繼續上篇指針未完成的學習任務。

指向函數的指針

指向指針的指針

指向指針數組的指針

指向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,如需轉載請自行聯系原作者

繼續閱讀