青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

聚星亭

吾笨笨且懶散兮 急須改之而奮進(jìn)
posts - 74, comments - 166, trackbacks - 0, articles - 0
  C++博客 :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

是啊,不可避免的,我們要學(xué)習(xí)指針了。關(guān)于指針的概念,我們已經(jīng)在第一章節(jié) 理解程序中的數(shù)據(jù) 課題中大概的介紹過(guò)了,我想它并不是一個(gè)很難的概念,如果對(duì)指針沒(méi)有任何一點(diǎn)概念的朋友可以試著百度一下,再看一下我們以前的章節(jié)。

 

       之所以把指針?lè)诺浆F(xiàn)在來(lái)講,一方面是因?yàn)椋浆F(xiàn)在我們所學(xué)的知識(shí),可以允許我把一個(gè)完整的指針及其相關(guān)的知識(shí)展現(xiàn)給大家而不需將一個(gè)知識(shí)點(diǎn)打亂到各個(gè)別的章節(jié)中;再一方面就是我們接下來(lái)的要學(xué)習(xí)的繼承、多態(tài)等特性剛好需要這方面的的知識(shí),省的我們?cè)倩仡^復(fù)習(xí),當(dāng)然,主要原因還是我沒(méi)有信心能將這個(gè)專題寫好。

 

是的,我們?cè)诠芾韮?nèi)存,管理一些數(shù)據(jù)結(jié)構(gòu)等等,很多情況都要使用指針,我們這個(gè)專題,就專門來(lái)討論下指針的問(wèn)題。

 

讓我們?cè)賮?lái)回顧下,指針的一些概念。

一、     什么是指針(指針與變量)。

很多的教科書上說(shuō),指針就是一個(gè)保存別的變量地址的一個(gè)變量,直白點(diǎn)說(shuō),指針就是地址。關(guān)于什么是變量、什么是地址、什么是數(shù)據(jù)類型的問(wèn)題,我想大家應(yīng)該都明白的,這里我就節(jié)省一些篇幅。

 

好,我們看一下指針的定義格式:

數(shù)據(jù)類型  *指針變量名; // 單純的使用指針變量名就是操作地址,給變量名帶上*就是取內(nèi)容。

               

好,既然指針時(shí)用來(lái)保存別的變量的地址的,那我們可以很容易的給一個(gè)指針變量賦值,以及對(duì)一個(gè)指針變量進(jìn)行操作(見(jiàn)代碼:Exp01:

#include "stdafx.h"

#include <stdio.h>

#include <string.h>

 

int main(int argc, char* argv[])

{

    int nNum = 0;

    int *pnNum = NULL;

 

    pnNum = &nNum; // nNum的地址保存到pnNum變量中;

 

    scanf("%d", &nNum); // 輸入一個(gè)數(shù)值

 

    printf("nNum變量的地址: 0x%08X\r\n", &nNum);  // 輸出nNum變量的地址

    printf("nNum變量的內(nèi)容: %d\r\n", nNum);       // 輸出輸入的變量的內(nèi)容

    printf("pnNum的地址:  0x%08X\r\n", &pnNum);   // 輸出指針變量pnNum的地址

    printf("pnNum的內(nèi)容:  0x%08X\r\n", pnNum);    // 輸出指針變量pnNum的內(nèi)容

    printf("pnNum內(nèi)容的內(nèi)容: %d\r\n", *pnNum);    // 輸出指針變量pnNum內(nèi)容的內(nèi)容

 

    return 0;

}    

好,貼一下運(yùn)行結(jié)果,讓我們仔細(xì)比較這兩個(gè)變量之間的聯(lián)系。

 

看明白了么?是不是可以理解成pnNum指向了nNum變量呢?由此,我們可以說(shuō),pnNumnNum的指針。

如果大家真的明白了他們的關(guān)系,大家不妨試著寫寫nNum指針的指針的指針……

當(dāng)然,如果內(nèi)存學(xué)的夠好的朋友可以寫一下這兩個(gè)變量在棧的排列方式……

二、     指針與數(shù)組

忘記在哪本書中說(shuō)的: 指針和數(shù)組是近親。現(xiàn)在越來(lái)越發(fā)現(xiàn),確實(shí)是這個(gè)樣子的,下面讓我來(lái)帶著大家領(lǐng)略下它們的風(fēng)采。

1.       數(shù)組的基本用法

       關(guān)于數(shù)組,我想大家應(yīng)該太不陌生了,我們第一節(jié)課就講述了數(shù)組的用法。

       在這里,我們?yōu)榱斯?jié)省篇幅,我僅簡(jiǎn)單扼要的回顧一下數(shù)組相關(guān)的知識(shí)點(diǎn):

1、  數(shù)組是用來(lái)存放相同數(shù)據(jù)類型的數(shù)據(jù)集合

2、  數(shù)組名就是這一數(shù)據(jù)集合的首地址(是常量)。

3、  數(shù)組的下標(biāo)從0開(kāi)始,數(shù)組中的數(shù)據(jù)是按照數(shù)組的下標(biāo)順序依次存放。

 

如下面的程序:

#include <windows.h>

 

int main()

{

    char    szaddrName[] = "52pojie.cn";

    char    *pszTitle   = "Null";

 

       MessageBoxA(NULL, szaddrName , pszTitle, MB_OK);

 

       return 0;

}

 

       OK,我們看下他們的存放方式有什么區(qū)別:

哈哈,是不是一樣呢?

2.       數(shù)組和指針的互操作

char    g_szaddrName[] = "52pojie.cn";

char    *g_pszTitle   = "Null";

 

// 用指針操作數(shù)組

void TestPoint()

{

    char *pszPoint = g_szaddrName;

 

    while (*pszPoint)

    {

        printf("%c", *pszPoint++);

    }

 

    printf("\r\n");

}

 

// 用數(shù)組操作指針

void TestArr()

{

    char *pszPoint = g_szaddrName;

    int nLength = strlen(pszPoint);

 

    for (int i = 0; i < nLength; i++)

    {

        printf("%c", pszPoint[i]);

    }

 

    printf("\r\n");

}

3.       二維數(shù)組的基本用法

OK,明白了這些,我們舉一個(gè)簡(jiǎn)單走迷宮的例子來(lái)說(shuō)明二維數(shù)組的存儲(chǔ)和使用(具體代碼見(jiàn)Exp03):

我們先定義一個(gè)地圖:

/************************************************************************/

// 迷宮地圖數(shù)據(jù)

// 0表示墻

// 1表示可以行走的路

// 2表示已經(jīng)走過(guò)的路

// 3表示返回的路

/************************************************************************/

int g_MazeMapData[13][13] = {

    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},

    {0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1},

    {0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0},

    {0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0},

    {0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0},

    {0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0},

    {0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0},

    {0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0},

    {0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0},

    {0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0},

    {0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0},

    {0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0},

    {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};

有了地圖,我們需要一些標(biāo)記,用來(lái)確定如:入口點(diǎn)坐標(biāo),出口在哪里,指定的坐標(biāo)經(jīng)過(guò)沒(méi)有等等問(wèn)題:

#define IN_POS_X    1  // 入口點(diǎn)X坐標(biāo)

#define IN_POS_Y    12   // 入口點(diǎn)Y坐標(biāo)

#define OUT_POS_X   12   // 出口點(diǎn)X坐標(biāo)

#define OUT_POS_Y   1  // 出口點(diǎn)Y坐標(biāo)

 

#define UNKNOWN     1   // 從來(lái)沒(méi)走過(guò)的路

#define PASS        2   // 經(jīng)過(guò)的標(biāo)記

#define BACK        3   // 返回的標(biāo)記

 

#define GO          0   // 前進(jìn)

#define COMEBACK    1   // 后退

 

接下來(lái),我們需要考慮下,實(shí)現(xiàn)走路的方式:

/************************************************************************/

// 按照 上、右、下、左的順序?qū)ぢ?/span>

// 參數(shù)含義:

//     nFlag: GO 表示前進(jìn),COMEBACK表示返回

// :

//     1 : 向上走,2: 向右走, 3: 向下走, 4: 向左走, 0:異常(出地圖了,不移動(dòng))

/************************************************************************/

int MoveTo(int nFlag)

{

    if(nFlag == 0)

    {

        //

        if (g_MazeMapData[g_nCurPosX][g_nCurPosY-1] == UNKNOWN)

        {

            g_MazeMapData[g_nCurPosX][g_nCurPosY] = PASS;

            g_nCurPosY--;

            return 1;

        }

 

        //

        if (g_MazeMapData[g_nCurPosX+1][g_nCurPosY] == UNKNOWN)

        {

            g_MazeMapData[g_nCurPosX][g_nCurPosY] = PASS;

            g_nCurPosX++;

            return 2;

        }

 

        //

        if (g_MazeMapData[g_nCurPosX][g_nCurPosY+1] == UNKNOWN)

        {

            g_MazeMapData[g_nCurPosX][g_nCurPosY] = PASS;

            g_nCurPosY++;

            return 3;

        }

 

        //

        if (g_MazeMapData[g_nCurPosX-1][g_nCurPosY] == UNKNOWN)

        {

            g_MazeMapData[g_nCurPosX][g_nCurPosY] = PASS;

            g_nCurPosX--;

            return 4;

        }

    }

    else

    {

        //

        if (g_MazeMapData[g_nCurPosX][g_nCurPosY-1] == PASS)

        {

            g_MazeMapData[g_nCurPosX][g_nCurPosY] = BACK;

            g_nCurPosY--;

            return 1;

        }

 

        //

        if (g_MazeMapData[g_nCurPosX+1][g_nCurPosY] == PASS)

        {

            g_MazeMapData[g_nCurPosX][g_nCurPosY] = BACK;

            g_nCurPosX++;

            return 2;

        }

 

        //

        if (g_MazeMapData[g_nCurPosX][g_nCurPosY+1] == PASS)

        {

            g_MazeMapData[g_nCurPosX][g_nCurPosY] = BACK;

            g_nCurPosY++;

            return 3;

        }

       

        //

        if (g_MazeMapData[g_nCurPosX-1][g_nCurPosY] == PASS)

        {

            g_MazeMapData[g_nCurPosX][g_nCurPosY] = BACK;

            g_nCurPosX--;

            return 4;

        }

    }

 

    return 0;

}

 

最后,我們只需要一個(gè)函數(shù),來(lái)確定是否到達(dá)出口,或者判斷下有沒(méi)有出口并給出相應(yīng)提示:

/************************************************************************/

// 開(kāi)始走迷宮

// 如果找到出口了,返回1,否則返回0

// 如果程序異常中斷了,返回-1

/************************************************************************/

int Start()

{

    while (1)

    {

        // 開(kāi)始走路

        if (MoveTo(GO) == 0)

        {

            MoveTo(COMEBACK);

        }

 

        for(int i=0; i<=OUT_POS_X; i++)

        {

            for(int j = 0; j <= IN_POS_Y; j++)

            {

                printf("%d ", g_MazeMapData[i][j]);

            }

            printf("\r\n");

        }

 

            Sleep(500);

        system("cls");

 

        // 如果當(dāng)前的坐標(biāo)是出口坐標(biāo)表示找到出口了

        if (g_nCurPosX == OUT_POS_X && g_nCurPosY == OUT_POS_Y)

        {

            return 1;

        }

 

        // 如果又退回入口位置了,表示沒(méi)有找到出口

        if (g_nCurPosX == IN_POS_X && g_nCurPosY == IN_POS_Y)

        {

            return 0;

        }

    }

 

    return -1;

}

 

我相信,通過(guò)這個(gè)程序,足夠讓大家理解并掌握二維數(shù)組及多維數(shù)組的用法了。下面,我們來(lái)考慮一些具體的問(wèn)題。

4.       數(shù)組的尋址方式

相信好多朋友同我一樣,很抽象的將二維數(shù)組在內(nèi)存中的模樣就想像成二維的平面了,三維數(shù)組就想想成立方體……,卻忽略掉它們其實(shí)都是線性存儲(chǔ)的。

 

       這樣,無(wú)論是我們?cè)谝院蟮木幋a過(guò)程中還是在逆向分析中確定當(dāng)前操作的是哪個(gè)元素就尤為重要的。(比如通過(guò)單循環(huán)來(lái)遍歷一個(gè)二維數(shù)組等等)。

 

       其實(shí),如果真要說(shuō)起它的尋址方式,還真的挺容易的,不信,聽(tīng)我慢慢道來(lái):

a)      一維數(shù)組的尋址

       比如,已知在自己身前10米處有一柵門,門后面有一排邊長(zhǎng)為1米的正方形箱子,求第四個(gè)箱子離自己有多遠(yuǎn),哈哈,簡(jiǎn)單吧:相信很多朋友脫口就能說(shuō)出來(lái)是:10+1*4  = 14

 

       那再問(wèn),一個(gè)數(shù)組:int ary[10] = {0}; //已知 ary的地址是:0x12ff68,ary[3]的地址是多少?。

0x12ff68+sizeof(int)*3 = 0x12ff68+0x0C = 0x12ff74

 

b)      二維維數(shù)組的尋址

問(wèn): 有十個(gè)箱子,沒(méi)個(gè)箱子中放十個(gè)蘋果,求第七個(gè)箱子中第三個(gè)蘋果是這些箱子中的第幾個(gè)蘋果。

                    

       這個(gè)問(wèn)題是不是就相當(dāng)于有A[10][10] A[6][2]是第幾個(gè)元素。即:6*10+3 = 63 

       由此推理,我們可以推演一下它的尋址公式:

如:有數(shù)組:type ary[x][y]; ary[x][z]的地址是:

Ary[x]addr = ary addr + sizeof(type[y])*x = ary addr + sizeof(type)*x*y

Ary[x][z]addr = ary[x]addr + sizeof(type)*z

由此,將公式優(yōu)化一下:

Ary[x][z]addr = ary addr + sizeof(type)*y*x + sizeof(type)*z;

            = ary addr + sizeof(type)*(x*y+z);

 

因此,二維數(shù)據(jù)的尋址公式就是:Ary[x][z]addr = ary addr + sizeof(type)*(x*y+z);

此公式中x*y+z就是求第幾個(gè)元素的公式。

 

舉個(gè)例子實(shí)驗(yàn)一下:

如:int ary[3][4] = {0};已知數(shù)組首地址是:0x12ff68,ary[1][2]是第幾個(gè)元素,并求出其在內(nèi)存的地址。

套公式:

11*4+2 = 6 ,所以是第六個(gè)元素。

20x12ff68+sizeof(int)*(1*4+2) = 0x12ff68+ 4 * 6 = 0x12ff68 + 0x18 = 0x12ff80,地址是:0x12ff80

 

5.       淺談指針數(shù)組

只簡(jiǎn)單說(shuō)明下用法,詳細(xì)信息大家自己摸索,下滿舉個(gè)應(yīng)用的例子,一堆字符串的排序:

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

 

/************************************************************************/

// 按照字符順序排序

/************************************************************************/

int SortTaxis(char *szNameBuf[], int nCount)

{

    int x = 0, y = 0;

    char *szTmpBuf = NULL;

 

    if (szNameBuf == NULL)

    {

        return 0;

    }

 

    if (nCount <= 0)

    {

        return 0;

    }

 

    for (x = 0; x < nCount-1; x++)

    {

        for (y = x+1; y < nCount; y++)

        {

            if (strcmp(szNameBuf[x], szNameBuf[y]) > 0)

            {

                szTmpBuf = szNameBuf[x];

                szNameBuf[x] = szNameBuf[y];

                szNameBuf[y] = szTmpBuf;

            }

        }

    }

   

    return 0;

}

 

int main()

{

    int i = 0;

 

    char *szNameBuf[] = {

    "Kalkwasser",

    "John Parsons",

    "Nathan Bryce",

    "Edward",

    "John Mackintosh",

    "Henry Ford",

    "William Sanders",

    "Nathaniel",

    "George",

    "Tom Rees",

    "Clementia",

    "Mary Jones",

    "Natasha",

    "DrMudd",

    "Charlie Chaplin",

    "Julius Caesar",

    "Krakatoa",

    "James Brady",

    "John Paul II",

    "Freud",

    "Tom Rees",

    "pineapple lily",

    "Antony"};

 

    SortTaxis(szNameBuf, 23);

 

    for (i = 0; i < 23; i++)

    {

        puts(szNameBuf[i]);

    }

     return 0;

}

簡(jiǎn)單的評(píng)論下,這樣寫的代碼簡(jiǎn)單精簡(jiǎn),效率高,因?yàn)樗粨Q的是指針,用的是指針數(shù)組,與二維數(shù)組相比,它節(jié)省空間……

三、     指針與函數(shù)

1.       用指針作為函數(shù)的參數(shù)

我想,不論是指針作為參數(shù)還是引用作為參數(shù),都有值得讓我們來(lái)調(diào)試它一下,弄清楚其原理,由于這些比較簡(jiǎn)單,所以具體的調(diào)試過(guò)程留給大家,希望大家也能得到與我一樣的結(jié)論:傳遞的是地址,存在一份地址的拷貝。

 

具體使用指針作為參數(shù)的參考代碼可以見(jiàn)上面指針數(shù)組的函數(shù):

int SortTaxis(char *szNameBuf[], int nCount)

2.       用指針作為函數(shù)的返回類型

返回一個(gè)指針類型是可行的,但是我相信初學(xué)者一定像我一樣,都會(huì)犯一個(gè)同樣的錯(cuò)誤:返回局部變量的地址,如下代碼:

char * stringcat(char *pszStr1, char *pszStr2)

{

    if (!pszStr1 || !pszStr2)

    {

        return NULL;

    }

 

    char pszResultStr[128] = {0};

    strcpy(pszResultStr, pszStr1);

    strcat(pszResultStr, pszStr2);

     return pszResultStr;

}

                     這段代碼漏洞很多,我希望我的讀者朋友不會(huì)寫出這樣的代碼。

1、  首先它定義的是數(shù)組,空間大小可能越界造成棧溢出漏洞。

2、  它返回的是一個(gè)棧地址,容易被覆蓋。

我希望大家能調(diào)試一下這段代碼(Exp05)就想我以前調(diào)試分析別的代碼一樣,大家自己分析下,問(wèn)題出在哪里。

3.       使用函數(shù)指針

經(jīng)過(guò)上面的一翻學(xué)習(xí),我相信,大家已經(jīng)很清楚的明白,我們的指針不僅能夠指向棧數(shù)據(jù)區(qū),而且還可以指向堆數(shù)據(jù)區(qū)乃至全局?jǐn)?shù)據(jù)區(qū),當(dāng)然,我相信大家也肯定能夠理解指針也可以指向代碼區(qū),因?yàn)槲覀冊(cè)缭趯W(xué)習(xí)函數(shù)的專題中,用數(shù)組存放我們代碼的機(jī)器碼并執(zhí)行過(guò)它,數(shù)組名不就是數(shù)組的首地址么,函數(shù)名不也是地址么,地址不就是指針么。

 

好,不多廢話,看代碼(Exp06):

int sum(int nNum1, int nNum2)

{

    return nNum1 + nNum2;

}

 

int main()

{

    int nSum = sum(1, 2);

 

    printf("%d\r\n", nSum);

 

    return 0;

}

 

想必,這個(gè)是我寫過(guò)的最簡(jiǎn)單的函數(shù)了,不用加注釋,大家肯定能猜出來(lái)這段代碼的含義(如果真的不知道它的功能,那……)。

 

現(xiàn)在我們需要寫一個(gè)指針,讓它指向這個(gè)函數(shù),應(yīng)該怎么寫呢?

 

回想一下我們以前說(shuō)過(guò)的話,一個(gè)函數(shù)名,就是一個(gè)地址,也就是一個(gè)int類型的常量,倘若如果我們直接給一個(gè)整型指針賦值一個(gè)函數(shù)名,編譯器檢查應(yīng)該是類型報(bào)錯(cuò),我們先測(cè)試一下:

int *pFun = sum; // error C2440: 'initializing' : cannot convert from 'int (__cdecl *)(int,int)' to 'int *'             

很明顯,類型轉(zhuǎn)換出錯(cuò)了,按照錯(cuò)誤提示,我們修改一下:

int (__cdecl *pFun)(int,int) = sum; // 哈哈,編譯通過(guò)。

 

我們知道,__cdeclC調(diào)用方式(可以省略的.),OK,我們現(xiàn)在測(cè)試一下,這個(gè)函數(shù)指針能不能用:

int (*pFun)(int,int) = sum;

 

nSum = pFun(3, 8);

printf("%d\r\n", nSum);

                     OK,大功告成。

四、     指針的擴(kuò)展用法

1.       函數(shù)指針類型的定義

我想,像上面這樣定義一個(gè)指針,一定非常的麻煩的,如果我們?cè)跔砍兜揭恍?shù)據(jù)類型轉(zhuǎn)換,那更是讓人頭疼。比如下面的代碼:

int (WINAPI * call)(HWND,LPSTR,LPSTR,UINT);
HMODULE hDll=LoadLibrary("user32.dll");
call=(int(WINAPI * )(HWND,LPSTR,LPSTR,UINT))GetProcAddress(hDll,"MessageBoxA");
FreeLibrary(hDll);
(*call)(NULL,"HI,I AM  FROM USER32.DLL","TEST",MB_OK);

 

當(dāng)然,這還是簡(jiǎn)單的,還有更復(fù)雜足以讓我們頭暈的代碼,就不以此列舉了。這就迫使我們定義一個(gè)相關(guān)的數(shù)據(jù)類型,這樣以后只要像定義一個(gè)變量那樣使用就可以了,比如上面的代碼可以變成:

typedef int (WINAPI * call)(HWND,LPSTR,LPSTR,UINT);
call mycall;      //
定義一個(gè)函數(shù)指針變量
HMODULE hDll=LoadLibrary("user32.dll");

mycall=(call)GetProcAddress(hDll,"MessageBoxA");
FreeLibrary(hDll);
(*mycall)(NULL,"HI,I AM  FROM USER32.DLL","TEST",MB_OK);

這樣就讓人好理解,同樣也精簡(jiǎn)了代碼。

 

我相信,對(duì)于typedef這個(gè)關(guān)鍵字,我們一定不陌生,因?yàn)樵诒鞠盗械牡谝恍」?jié)中,我們已經(jīng)提到過(guò)它了。它的基本用法格式是: typedef 舊數(shù)據(jù)類型 新數(shù)據(jù)類型

 

通過(guò)上面的編譯錯(cuò)誤:'int (__cdecl *)(int,int)' to 'int *' 我們可以知道,int (__cdecl *)(int,int)本來(lái)就是數(shù)據(jù)類型。而 int (__cdecl *PFUN_TYPE)(int,int) 中的PFUN_TYPE就是新的數(shù)據(jù)類型。

 

這樣,我們最開(kāi)始的代碼就又可以寫成:

    typedef int (*PFUN_TYPE)(int,int);

    PFUN_TYPE pFun;

 

    pFun = sum;

    int nSum = pFun(3, 8);

    printf("%d\r\n", nSum);

2.       成員函數(shù)指針的使用

從進(jìn)入C++的課程以來(lái),我們講述了類中成員函數(shù)的調(diào)用方式,它們比起普通的函數(shù)多了一個(gè)傳遞this指針的過(guò)程,因此,我們剛才說(shuō)的定義函數(shù)指針的方法對(duì)于成員函數(shù)而言是無(wú)效的。其解決方法也自然的就變成了怎么傳遞一個(gè)this指針呢?

 

回想一下,我們?cè)陬愅舛x成員函數(shù)的代碼,比如:

bool CExample::SetNum(int nFirst, int nSec)

{

    m_nFirstNum  =  nFirst; 

    m_nSecNum  =  nSec ;

    return true;

}

對(duì),它限定了作用域,所以它表示它仍然是類內(nèi)的一個(gè)函數(shù),那我們的函數(shù)指針也仿造它來(lái)寫一個(gè)。

typedef void (Person::*PBASEFUN_TYPE)();  // 這里的*是為了與靜態(tài)成員函數(shù)區(qū)分

                好,我們編寫如下代碼(見(jiàn)Exp06):

class Person;

typedef void (*PFUN_TYPE)();

typedef void (Person::*PBASEFUN_TYPE)();

 

class Person

{

public:

    PBASEFUN_TYPE *m_pFunPoint;

    Person()

    {

           m_pFunPoint = (PBASEFUN_TYPE*)new PFUN_TYPE[2];

           m_pFunPoint[0] = (PBASEFUN_TYPE)sayHello;

           m_pFunPoint[1] = (PBASEFUN_TYPE)sayGoodbye;

    }

 

    void sayHello()

    {

           printf("person::Hello\r\n");

    }

 

    void sayGoodbye()

    {

           printf("person::Goodbye\r\n");

    }

};

這樣,我們就簡(jiǎn)單的實(shí)現(xiàn)了一個(gè)成員函數(shù)的指針數(shù)組,算是為我們學(xué)習(xí)類的多態(tài)性中虛函數(shù)大點(diǎn)兒基礎(chǔ),相信大家應(yīng)該能看明白吧。

調(diào)用測(cè)試一下:

    Person thePer;

    (thePer.*thePer.m_pFunPoint[0])();

五、     幾點(diǎn)注意事項(xiàng)

1、  一定要注意函數(shù)指針指向內(nèi)容的釋放以免防止內(nèi)存泄露。

2、  注意及時(shí)將不用的指針賦值為NULL,以避免野指針的問(wèn)題。

六、     小結(jié)

指針為我們的編程提供了諸多的技巧,簡(jiǎn)化了我們的代碼。當(dāng)然,于此同時(shí),它也有反面的作用:當(dāng)今軟件中的內(nèi)存錯(cuò)誤及不穩(wěn)定,90%以上是由于指針操作失誤而導(dǎo)致的,這足以見(jiàn)得指針的破壞力。

 因此,有效、合理、安全的使用指針是每個(gè)C程序員必備的基本素質(zhì)。

Feedback

# re: 笨鳥(niǎo)先飛學(xué)編程系列之 指針  回復(fù)  更多評(píng)論   

2010-03-24 13:45 by besterChen
@羅萊家紡官方網(wǎng)站
(⊙o⊙)…

# Xf6F2q , [url=http://okppdtrywaxj.com/]okppdtrywaxj[/url], [link=http://oagnutcxwefb.com/]oagnutcxwefb[/link], http://mxsesllsxojj.com/  回復(fù)  更多評(píng)論   

2011-05-27 01:10 by cegjjn
Xf6F2q , [url=http://okppdtrywaxj.com/]okppdtrywaxj[/url], [link=http://oagnutcxwefb.com/]oagnutcxwefb[/link], http://mxsesllsxojj.com/

# re: 笨鳥(niǎo)先飛學(xué)編程系列之 指針  回復(fù)  更多評(píng)論   

2011-11-06 15:42 by HuKer
看來(lái)你的指針學(xué)的很潛啊。

# re: 笨鳥(niǎo)先飛學(xué)編程系列之 指針  回復(fù)  更多評(píng)論   

2012-01-10 12:54 by 小菜貓
太高深了。。。 學(xué)習(xí)。。。。。。。。。
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            在线亚洲免费视频| 欧美一级艳片视频免费观看| 欧美日韩一区二区三| 老司机一区二区三区| 久久综合999| 美国成人毛片| 欧美国产精品日韩| 欧美日韩国产三区| 欧美午夜宅男影院| 国产性天天综合网| 亚洲高清视频在线| 一本色道久久88精品综合| 亚洲午夜精品久久久久久app| 亚洲图色在线| 久久精品72免费观看| 久久先锋资源| 亚洲国产精品热久久| 日韩天堂在线视频| 亚洲特级毛片| 久久亚洲图片| 欧美午夜激情小视频| 国产日韩欧美在线视频观看| 在线日韩视频| 一区二区av在线| 久久精品免费观看| 亚洲狼人综合| 玖玖精品视频| 国产欧美精品日韩精品| 亚洲精品国产精品久久清纯直播 | 亚洲一区二区三区乱码aⅴ蜜桃女 亚洲一区二区三区乱码aⅴ | 国产精品久久久久久久久免费| 国产精品国产三级国产aⅴ入口 | 国产女人18毛片水18精品| 亚洲福利一区| 欧美一区二区三区的| 欧美不卡三区| 欧美在线一区二区三区| 欧美日韩国产电影| 亚洲激情另类| 久久精品理论片| 亚洲一卡久久| 欧美视频在线观看免费| 亚洲激情专区| 乱码第一页成人| 久久精品99国产精品| 国产精品一区二区久久精品| 亚洲日本中文字幕| 你懂的一区二区| 久久久久久久性| 国产欧美精品一区| 欧美一区二区三区在线视频| 亚洲精品日日夜夜| 欧美国产亚洲精品久久久8v| 亚洲电影第三页| 久久久精品网| 亚洲直播在线一区| 国产精品激情电影| 亚洲婷婷在线| 亚洲天堂黄色| 国产日本精品| 久久影院午夜论| 久久久蜜桃精品| 在线观看日产精品| 免费久久久一本精品久久区| 久久久久久久激情视频| 在线成人中文字幕| 欧美高清成人| 欧美精品一区二区三区四区| 日韩视频在线观看免费| 欧美激情一级片一区二区| 牛人盗摄一区二区三区视频| 亚洲成人在线| 最新国产の精品合集bt伙计| 欧美日韩国产美女| 亚洲在线一区二区三区| 亚洲影视在线播放| 国产亚洲精品aa午夜观看| 欧美专区在线| 久久成人精品视频| 亚洲精品在线观看免费| 99视频精品| 国产综合一区二区| 亚洲福利在线视频| 欧美精品一区二区三区一线天视频| 99re视频这里只有精品| 亚洲字幕一区二区| 极品中文字幕一区| 亚洲黄色免费网站| 午夜一区二区三视频在线观看| 国产精品午夜国产小视频| 欧美自拍偷拍午夜视频| 久久精品国产第一区二区三区最新章节| 国内视频一区| 亚洲精品久久久久中文字幕欢迎你| 欧美日韩国产va另类| 午夜精品成人在线| 久久精品国产久精国产一老狼| 亚洲国产一区在线| 亚洲视频在线观看视频| 精品二区视频| 一本在线高清不卡dvd| 国产一级精品aaaaa看| 亚洲福利视频在线| 国产欧美日韩一区二区三区在线| 奶水喷射视频一区| 国产精品欧美日韩| 亚洲国产一区二区三区a毛片| 国产精品嫩草99av在线| 欧美不卡视频| 国产农村妇女精品| 亚洲国产精彩中文乱码av在线播放| 国产精品久久久久久久久| 欧美国产激情二区三区| 国产欧美日韩视频在线观看| 亚洲高清一二三区| 国产亚洲一级| 一区二区三区偷拍| 亚洲精品久久久久久久久| 欧美亚洲网站| 欧美亚洲一区三区| 国产精品免费福利| 99热在这里有精品免费| 亚洲国产日韩一区| 久久激情中文| 久久成人久久爱| 国产精品久久午夜| 一区二区三区四区国产精品| 亚洲九九九在线观看| 麻豆av一区二区三区久久| 久久久蜜桃精品| 国产三级欧美三级日产三级99| 99在线|亚洲一区二区| 亚洲人久久久| 久久精品国产欧美亚洲人人爽| 欧美在线电影| 国产欧美日本在线| 亚洲欧美国产精品专区久久| 亚洲免费影视| 国产乱码精品| 午夜精品福利在线| 久久久久久久久久久久久女国产乱| 国产精品私拍pans大尺度在线| 亚洲香蕉视频| 欧美亚洲日本国产| 国产一区二区三区在线播放免费观看| 午夜免费久久久久| 久久亚洲一区| 亚洲精品影院| 欧美午夜不卡在线观看免费| 亚洲一区观看| 久久天堂国产精品| 日韩视频永久免费| 国产精品久久久久av| 欧美一区二区在线视频| 老司机亚洲精品| 亚洲国产日韩欧美在线动漫| 欧美成人一区二区在线| 亚洲一级片在线观看| 国产精品爱久久久久久久| 亚洲欧美日本视频在线观看| 久久精品人人做人人综合| 亚洲国产成人不卡| 欧美日韩国产页| 亚洲欧美综合网| 欧美国产激情二区三区| 一区二区日本视频| 国产日韩欧美麻豆| 欧美成人一区在线| 亚洲欧美日韩精品久久奇米色影视| 美女精品网站| 亚洲淫片在线视频| 1024成人网色www| 欧美午夜剧场| 久久亚洲综合网| 亚洲伊人伊色伊影伊综合网 | 蜜桃精品久久久久久久免费影院| 亚洲国产精品一区二区第四页av| 欧美日韩p片| 午夜亚洲性色视频| 亚洲第一搞黄网站| 欧美亚洲免费在线| 亚洲精品欧美精品| 国产在线日韩| 国产精品捆绑调教| 欧美xxx成人| 久久er99精品| 在线综合亚洲| 亚洲第一天堂无码专区| 久久久久久精| 亚洲免费伊人电影在线观看av| 狠狠色狠狠色综合日日小说| 欧美性开放视频| 欧美精品日韩三级| 久久精品日韩欧美| 亚洲一区二区黄色| 亚洲精品视频免费| 欧美黑人多人双交| 久久综合导航| 久久视频在线免费观看| 先锋影音国产精品|