欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
深入剖析C/C++函數的參數傳遞機制 (轉-有修正)作者:leeyeafu(明經(jīng)CAD社區 編程申請版塊 版主) - hairi的專(zhuān)欄

首先,這篇文章針對近期網(wǎng)友在ARX版塊的提問(wèn),很多都是在調用ARX函數或者設計自定義函數時(shí)出現的困惑,為方便大家分析和理解問(wèn)題,進(jìn)而正確解決問(wèn)題,我將個(gè)人的一些理解寫(xiě)成文字,希望對大家在做ARX程序設計時(shí)有所幫助。同時(shí),這篇文章也為“ObjectARX程序設計入門(mén)(2)”作些準備工作。

這篇文章與普通的C/C++教材相比,可能要深入得多,閱讀時(shí)應該細心。而對于未接觸過(guò)C語(yǔ)言的讀者來(lái)說(shuō),大概需要先閱讀一般的C++教材。我的看法,《C++編程思想》和《深入淺出MFC》一類(lèi)的書(shū)對于初學(xué)者太過(guò)深入,而類(lèi)似《Visual C++ 6.0從入門(mén)到精通》的書(shū)籍主要篇幅在介紹VC軟件的使用方法而不是講解C++程序設計方法,它們都不適宜作C++ARX程序設計入門(mén)學(xué)習用書(shū)。我個(gè)人學(xué)習C++使用的是南京大學(xué)出版社的書(shū)名就是《C++教程》,它是為C程序員編寫(xiě)的C++教材,全書(shū)僅130多頁(yè),內容淺顯但基本夠用。不過(guò)那是上世紀90年代初出版的,現在大概不好找了,不過(guò)類(lèi)似的(比如說(shuō)大學(xué)教材)我想書(shū)店里還是有的。

文章中的大部分內容是我個(gè)人的看法,一般的C++書(shū)籍上找不到類(lèi)似的說(shuō)法與其比較,對于其正確性,我沒(méi)有十足的把握。各位網(wǎng)友可以對此進(jìn)行討論或者批評。(只是不要真的用磚頭砸,那樣對于我英勇而忙碌的醫護人員太不尊重,別再給他們添亂了。)

C語(yǔ)言的函數入口參數,可以使用值傳遞和指針傳遞方式,C++又多了引用(reference)傳遞方式。引用傳遞方式在使用上類(lèi)似于值傳遞,而其傳遞的性質(zhì)又象是指針傳遞,這是C++初學(xué)者經(jīng)常感到困惑的。為深入介紹這三種參數傳遞方式,我們先把話(huà)題扯遠些:

1、 C/C++函數調用機制及值傳遞:

在結構化程序設計方法中,先輩們告訴我們,采用“自頂向下,逐步細化”的方法將一個(gè)現實(shí)的復雜問(wèn)題分成多個(gè)簡(jiǎn)單的問(wèn)題來(lái)解決。而細化到了最底層,就是“實(shí)現單一功能”的模塊,在C/C++中,這個(gè)最小的單元模塊就是函數。然而,這些單個(gè)的模塊(或者說(shuō)函數)組合起來(lái)要能完成一項復雜的功能,這就注定各個(gè)函數之間必然要有這樣或那樣的聯(lián)系(即耦合)。而參數耦合是各個(gè)函數之間最為常見(jiàn)的耦合方式,也就是說(shuō),各個(gè)函數之間通常通過(guò)參數傳遞的方式來(lái)實(shí)現通訊。

當我們設計或者調用一個(gè)函數時(shí),首先要注意的是函數的接口,也就是函數的參數和返回值。調用一個(gè)函數就是將符合函數接口要求的參數傳遞給函數體,函數執行后返回一個(gè)值給調用者。(當然,C/C++允許void類(lèi)型的參數和返回值。當返回值為void時(shí),函數類(lèi)似BasicSub子過(guò)程或者PascalProcedure過(guò)程。)

函數的參數傳遞,就是將在函數體外部已賦值(或者至少已經(jīng)定義并初始化)的變量通過(guò)函數接口傳遞到函數體內部。根據變量種類(lèi)的不同,有不同的參數傳遞方式:

若傳遞的參數是一個(gè)類(lèi)對象(包括象Intfloat這樣的C/C++內部數據類(lèi)型),這種傳遞方式為值傳遞。C/C++這種以函數為主體的語(yǔ)言中,幾乎所有的功能都是通過(guò)函數調用來(lái)實(shí)現的。<不是嗎?你說(shuō)C/C++運算符操作?還有變量聲明?你先等等,接下來(lái)我們就看看C++中這些操作是怎么實(shí)現的。>以下的C/C++代碼是如此的簡(jiǎn)單,可能你從未想過(guò)還有什么要分析的,但它確實(shí)是函數值傳遞方式的典型例子。

float x = 0.254;
float y = 3.1415;
float z = x + y;

以上代碼編譯執行時(shí),第一步float x,即聲明一個(gè)實(shí)數變量。即將標志符x認為是一個(gè)實(shí)數變量,并調用float類(lèi)的初始化函數。當然你可能感覺(jué)不到它的存在,因為現在的CPU都直接支持浮點(diǎn)運算,它只是一條匯編指令而已。

初始化完成后,調用賦值函數:

x.operator = (0.254); 

不要奇怪以上函數的寫(xiě)法,它實(shí)際上與 x = 0.254; 效果完全相同,會(huì )產(chǎn)生同樣的匯編代碼。

該函數首先根據變量x的數據類(lèi)型分配合適的內存空間,并將該內存地址與標志符x關(guān)聯(lián)。然后將立即數0.254寫(xiě)入分配的內存。(這里借用匯編語(yǔ)言的術(shù)語(yǔ),立即數可以理解為程序已指定的具體數值。)然而,賦值函數的設計者并不能獲知立即數0.254的數值,調用該函數時(shí)就必須通過(guò)參數傳遞的方法將數值通知給函數體。賦值函數接口大致是這樣:

float float::operator = (register float a);

變量a是在CPU寄存器中使用的臨時(shí)變量。調用賦值函數時(shí),將0.254送到寄存器變量a中,再將a值送到變量x所在的內存位置中。以上函數的返回值用于類(lèi)似這樣的鏈式表達式的實(shí)現:

x = y = z;

說(shuō)了許多,好象十分復雜,其實(shí)賦值操作僅僅只是兩條匯編代碼:

mov AX, 0.254 

mov [x], AX

事實(shí)上,它之所以簡(jiǎn)單,僅僅是因為floatCPU能直接處理的數據類(lèi)型。若以上代碼中不是float類(lèi)型數據賦值,而是更復雜的(比如說(shuō)自定義)類(lèi)型數據,同樣的賦值操作盡管是相同的步驟,但實(shí)際情況要復雜得多。因為寄存器容量限制,可能變量a無(wú)法作為寄存器變量存放,這樣即使是簡(jiǎn)單的賦值操作也要為函數的臨時(shí)變量分配內存并初始化,在函數的返回時(shí),臨時(shí)變量又要析構(或者說(shuō)從內存中釋放),這也就是參數值傳遞方式的弱點(diǎn)之一:效率低。以后我們還可以看到,值傳遞方式還有其力所不能及的時(shí)候。

上面的代碼段中加法調用這樣的函數,其參數傳遞方式同樣是值傳遞:

float::operator + (float a, float b);

下面看一個(gè)稍微復雜的類(lèi),Complex復數類(lèi)。ObjectARX程序設計中使用的大部份對象類(lèi)型都將比這個(gè)類(lèi)復雜。

class Complex
{
  public:
  Complex operator = (Complex others); //
賦值函數,事實(shí)上不聲明系統也會(huì )默認

  Complex operator + (Complex c1, Complex c2); //
加法
  void Complex (float Re, float Im); //
帶參數的構造函數
  //
當然,真正的復數類(lèi)接口遠比這復雜,為了說(shuō)明問(wèn)題,僅寫(xiě)出這三個(gè)接口函數。
  private:
  float Re; //
復數的實(shí)部
  float Im; //
復數的虛部
} //
類(lèi)接口函數的實(shí)現應該并不復雜,在此略過(guò)。

類(lèi)的接口函數的參數仍然用值傳遞方式。當執行下列代碼中的加法和賦值操作時(shí),程序將要多次執行Complex類(lèi)的構造函數和析構函數。

Complex A(2.5, 3);

Complex B(0.4, 2.5);

Complex C = A + B;

最后一句代碼,首先聲明一個(gè)Complex類(lèi)對象C,然后根據運算符優(yōu)先級,執行加法運算,將對象A,B傳遞給加法函數,這時(shí)C++調用Complex類(lèi)的默認構造函數聲明兩個(gè)臨時(shí)變量,再調用默認的“拷貝構造函數”采用位拷貝的方法將對象A,B復制到臨時(shí)變量,加法操作返回時(shí),再將臨時(shí)變量析構,返回值再用值傳遞方式傳遞給賦值函數。

從以上執行過(guò)程可以看出,值傳遞方式效率低的關(guān)鍵在于臨時(shí)變量的建立和析構。于是考慮,因為在調用函數時(shí)該變量已經(jīng)在內存中存在,將這個(gè)已經(jīng)存在的變量直接傳遞給函數體而不去聲明和拷貝臨時(shí)變量。這樣,臨時(shí)變量的構造、拷貝、析構等工作都被省略,從而大大提高了函數效率。這便是使用C/C++指針和引用傳遞機制的主要原因。另外,使用這樣的函數參數傳遞機制,在函數體內部可以很輕易地修改變量的內容。(而使用值傳遞方式,函數體內部只能修改臨時(shí)變量,沒(méi)有辦法修改這些外部變量本身的值。)這樣一方面增加了程序設計的靈活性,同時(shí)也給程序帶來(lái)了安全隱患。當然,我們可以使用const聲明防止變量的內容在函數體內部被修改,但這需要編程者有良好的編程風(fēng)格和編程習慣。在介紹函數參數的指針和引用傳遞方式之前,先說(shuō)一說(shuō)指針和引用這兩個(gè)概念。

2、指針和引用

在解釋指針和引用之前,先看看普通變量是怎樣在內存中存放的。聲明變量后,編譯程序要維護一張包括各種標識符的表。在這張表內,每一個(gè)標識符,比如說(shuō)變量名都應該有它的類(lèi)型和在內存中的位置。

在這要進(jìn)一步說(shuō)明幾個(gè)問(wèn)題,這些問(wèn)題可能涉及多個(gè)計算機專(zhuān)業(yè)領(lǐng)域,我也不想在這作深入介紹,看不明白沒(méi)有關(guān)系,不會(huì )影響您繼續閱讀這篇文章。

首先,C/C++的內存分配有靜態(tài)分配和動(dòng)態(tài)分配兩種機制。靜態(tài)分配內存是由編譯程序為標識符分配固定的內存地址,而動(dòng)態(tài)分配機制是應用程序在進(jìn)入內存后再根據程序使用內存的實(shí)際情況決定變量存放地址。這個(gè)話(huà)題非常復雜,不過(guò)進(jìn)行ObjectARX程序設計好象不必太在意內存分配機制,讓編譯程序和Windows去管這件事吧。而且內存分配機制對于我們理解指針和引用不會(huì )造成影響。

其次,標識符可以標識變量,也可以標識函數入口。從而它的類(lèi)型可以是CPU能直接處理的內部數據類(lèi)型<例如int類(lèi)型>,也可以是用戶(hù)自定義類(lèi)型,還可以是函數類(lèi)型。

另外,由于標識符的類(lèi)型不同,它占用內存的大小也各有差異。“在內存中的位置”實(shí)際上指的是它占用的內存塊的首地址。對于80286以上的計算機<這句話(huà)是不是多余?>,內存地址由基址(或段地址)加上偏移地址組成?;肥菓贸绦虮徽{入內存時(shí)由操作系統分配,當然,編譯程序把應用程序編譯成多個(gè)段,從而要求操作系統對于不同的段分配不同的基址。而編譯程序(哪怕是使用靜態(tài)地址分配)只能決定標識符存放的偏移地址,也就是說(shuō),“在內存中的位置”只是標識符占用內存的第一個(gè)字節的偏移地址。說(shuō)了這么多,有一點(diǎn)需要記住,無(wú)論是程序設計者還是編譯程序都無(wú)法確知變量的內存中的實(shí)際位置。

最后,這個(gè)標識符表要比上面說(shuō)的復雜,我只選擇了與目前討論的問(wèn)題有關(guān)的內容。

好了,準備工作做了許多,讓我們正式進(jìn)入C/C++指針和引用的神秘世界。

指針變量其實(shí)質(zhì)類(lèi)似一個(gè)int整型變量。我們在源程序中這樣聲明一個(gè)指針變量:

float *px;

此時(shí),標識符px指示的內存位置上存放的就是一個(gè)int類(lèi)型整數,或者說(shuō),通過(guò)變量px可以訪(fǎng)問(wèn)到一個(gè)int類(lèi)型整數,并且這個(gè)整數與指針指向的數據類(lèi)型<在此例中為float浮點(diǎn)數>無(wú)關(guān)。在ARX程序中,甚至可以用這樣的方式打印一個(gè)指針變量:

acutPrintf(“指針變量px的值為%d, px);

當然,這個(gè)整數值到底意味著(zhù)什么,可以只有計算機(或者說(shuō)操作系統)自己知道,因為這個(gè)值表示的是指針指向的數據在內存中的位置。也就是說(shuō),不應該將指針變量與普通int整型混淆,例如,對指針進(jìn)行四則運算將使用結果變得計算機和程序員都無(wú)法理解,盡管編譯器允許你這樣做。<實(shí)際上,計算數組下標就要使用指針的加法。>

與普通變量不同,若在程序中聲明指針變量的同時(shí)不進(jìn)行初始化,系統會(huì )自動(dòng)將指針變量初始化為NULL。<NULL的值與0相同,但好的編程風(fēng)格是使用NULL而非0,以與普通int類(lèi)型區別。>而聲明普通變量,系統僅為其分配內存,而不做自動(dòng)初始化,從而未初始化的變量值是不可預測的。當然,直接使用未初始化的指針決不是一個(gè)好程序(此時(shí)編譯器會(huì )發(fā)出警告信息),其危害或隱患以后在說(shuō)明內存管理技術(shù)時(shí)再討論。<ObjectARX程序設計連載能堅持寫(xiě)下去,我想會(huì )要涉及到內存管理的。>
在聲明時(shí)初始化指針變量可以這樣:

//float *px = 0.254;原文如此

float f = 0.254 ;

float *px = &f ;

這是初始化同時(shí)賦值,也可以使用new運算符進(jìn)行初始化:

float *px = new float;

這種初始化方式經(jīng)常用于不方便或不能直接賦值的復雜數據類(lèi)型。

上述語(yǔ)句執行時(shí),首先分配一塊可存放數據的內存區域<大小與數據類(lèi)型有關(guān)>,若要同時(shí)賦值,就調用賦值函數將數值寫(xiě)入剛分配的內存中。然后為標識符px分配一個(gè)int整型要占用的(通常為4字節)內存空間,最后將分配的用于存放數據的內存首地址寫(xiě)入內存。

注意:使用new運算符初始化指針,指針變量使用結束后應該用delete運算符釋放其占用的內存。也就是說(shuō),new運算符和delete運算符最好能成對使用。

指針的初始化可以在程序的任何位置進(jìn)行,<當然,最好在使用它之前初始化。>比如:

float x = 0.254;
float *px;
//
其它語(yǔ)句,請注意不要在這里使用px指針

px = &x; //
在這進(jìn)行px指針的初始化工作

上面最后一行代碼是將變量x的地址賦值給指針px。以上初始化指針的方法效率相差無(wú)幾,讀者可自行分析。&運算符稍后討論。

下面看一個(gè)ObjectARX程序中最為普通的使用指針的代碼段:(注意,以下不是完整的代碼,不能進(jìn)行編譯或執行。)

void Sample(void)
{
//
聲明指針變量同時(shí)調用AcDbLine類(lèi)的構造函數進(jìn)行初始化。

//
注意此時(shí)使用了new運算符為AcDbLine類(lèi)對象分配內存。
AcDbLine *pLine = new AcDbLine(AcGePoint3d(10, 20, 0) ,
AcGePoint3d(50, 75, 0));

//
下面看看如何訪(fǎng)問(wèn)指針變量及復雜類(lèi)的接口函數。
pLine->setColorIndex(1); //
將線(xiàn)對象的顏色設置為紅色

//layer()
函數返回一個(gè)指向char類(lèi)型的指針,先聲明一個(gè)指針變量用于接收返回值
char *pLayerName;
pLayerName = pLine->layer(); 
acutPrintf(
\n紅色的線(xiàn)對象在%s圖層上。”, pLayerName);
}

這段代碼不作深入分析,請讀者注意pLine指針的聲明和初始化過(guò)程以及pLayerName指針的賦值過(guò)程。

注意到我們在上面初始化px指針時(shí)使用了&運算符,即取地址運算符,這也是使用引用的一般方法之一。引用是C++概念,C++初學(xué)者容易將引用和指針混淆在一起。

以下代碼中,m就是n的一個(gè)引用:

int n;
int &m = n;

編譯程序編譯以上代碼時(shí),在標識符表中添加一個(gè)int引用類(lèi)型的標識符m,它使用與標識符n相同的內存位置。這樣對m的任何操作實(shí)際上就是對n的操作,反之亦然。注意,m既不是n的拷貝,(這樣的話(huà),內存中應該的兩塊不同的區域,存放著(zhù)完全相同的內容。),也不是指向n的指針,其實(shí)m就是n本身,只不過(guò)使用了另外一個(gè)名稱(chēng)而已。

盡管指針和引用都是利用內存地址來(lái)使用變量,它們之間還是有本質(zhì)的區別:

首先,指針變量(包括函數調用時(shí)的臨時(shí)指針變量)在編譯和運行時(shí)要分配相當于一個(gè)int變量的內存空間以存放指針變量的值,盡管這個(gè)值表示的是指針指向的變量的地址。而引用與普通變量一樣,標識符所指示的內存位置就是變量存放位置。這樣不僅不需要在內存中分配一個(gè)int變量的內存空間(盡管它可能微不足道),而且在使用中可以少一次內存訪(fǎng)問(wèn)。<僅就內存使用效率而言,指針和引用所帶來(lái)的區別確實(shí)不大,完全可以不去在意它。>

其次,由于標識符表在填寫(xiě)后就不能再被修改,因此引用在創(chuàng )建就必須初始化,并且初始化后,不能改變引用的關(guān)系。另外,引用初始化時(shí),系統不提供默認設置,引用必須與合法的內存位置相關(guān)聯(lián)。而這些特征對于指針而言都是不存在的。指針可以在程序任何時(shí)刻初始化,初始化的指針在程序中也可以根據需要隨時(shí)改變所指向的對象,(這只需要改寫(xiě)指針變量的值就可以了。)當然,未初始化的指針變量系統會(huì )初始化為NULL,而NULL引用是非法的。

下面看一段類(lèi)似文字游戲的程序:

int I = 6;
int J = 8;
int &K = I; //K
I的引用

K = J; //K
I的值都變成了8

注意,由于引用關(guān)系不能被修改,語(yǔ)句K = J;并不能將K修改為對J的引用,只是修改了K的值。實(shí)際上,聲明并初始化引用后,可以把引用當作普通變量來(lái)使用,只不過(guò)在操作時(shí)會(huì )影響另外一個(gè)變量。

以上代碼僅僅只是解釋引用的定義,并不能體現引用的價(jià)值。引用的主要功能在于函數的參數(或者返回值)的傳遞。

注:下圖應該是float *px = &x ;

3、 函數參數的指針和引用傳遞機制

先看一下簡(jiǎn)單的例子。

void Func1(int x) //這個(gè)函數的參數使用值傳遞方式
{
  x = x + 10;
}
//
當參數類(lèi)型更復雜時(shí),指針和引用傳遞方式在效率等方面的優(yōu)勢更為明顯
//
不過(guò)那樣例子就不夠“簡(jiǎn)單”了
void Func2(int *x) //
這個(gè)函數的參數使用指針傳遞方式
{
  *x = *x + 10;
}

void Func3(int &x) //
這個(gè)函數的參數使用引用傳遞方式
{
  x = x + 10;
}

以下代碼調用這些函數:

int n = 0;
Func1(n);
acutPrintf(
n = %d
, n); // n = 0
Func2(&n);
acutPrintf(
n = %d
, n); //n = 10
Func3(n);
acutPrintf(
n = %d, n); //n = 20

以上代碼段中,當程序調用Func1()函數時(shí),首先在棧(Stack)內分配一塊內存用于復制變量n。若變量n的類(lèi)型復雜,甚至重載了該類(lèi)的默認拷貝構造函數:

CMyClass(const CMyClass &obj);

這個(gè)過(guò)程可能會(huì )比較復雜。<類(lèi)的默認拷貝構造函數使用“位拷貝”而非“值拷貝”,若類(lèi)中包括指針成員,不重載該函數幾乎注定程序會(huì )出錯。關(guān)于這個(gè)問(wèn)題以后再深入探討。>

程序進(jìn)入函數Func1()體內后,操作的是棧中的臨時(shí)變量,當函數結束(或者說(shuō)返回)時(shí),棧內變量被釋放。而對于函數Func1()來(lái)說(shuō)的外部變量n并未起任何變化,因此隨后的acutPrintf函數將輸出n = 0。

程序調用函數Func2()時(shí),在棧內分配內存用于存放臨時(shí)的指針變量x。然后用&運算取得變量n的地址,并拷貝給臨時(shí)指針變量x作為x的值。此時(shí),指針x就成了指向變量n的指針。在函數體內,*x運算得到的是指針x指向的內容,即變量n。對*x操作實(shí)際上就是對n操作。因此,在函數Func2()中變量n的值起了變化。在分析Func2()函數時(shí)應該注意到,臨時(shí)指針變量x要指向的內存地址,也就是說(shuō)變量x的“值”仍然是采用了值傳遞方式從函數外部(或者說(shuō)函數調用者)獲得,那么“值”也就應該具有值傳遞方式的特點(diǎn),它要在棧中復制臨時(shí)變量,它在函數體內被修改不會(huì )影響到函數外部。比如說(shuō),在上面的代碼段中,函數Func2()內可以讓指針x指向另外的變量,但函數結束或返回后,在函數外部是無(wú)法得到這樣的指向另外變量的指針。

程序調用函數Func3()時(shí),臨時(shí)變量x是一個(gè)變量n的引用,此時(shí)變量x就是變量n本身,對x操作的同時(shí),外部變量n也起了變化。實(shí)際上,引用能做的事,指針也能做到。

以上的代碼段確實(shí)簡(jiǎn)單,以至還不能充分顯示指針和引用在傳遞函數參數時(shí)的許多其他功能。下面我們設計這樣一個(gè)函數,函數需要兩個(gè)參數,在函數內將兩個(gè)參數的值互換。由于值傳遞方式盡管能通過(guò)返回值賦值的方法修改一個(gè)參數值,但不能同時(shí)修改兩個(gè)參數值,因此這個(gè)函數不能使用值傳遞方式。使用指針傳遞方式,函數可以寫(xiě)成這樣:

bool swap(int *x, int *y)
{
  int temp;
  temp = *x;
  *x = *y;
  *y = temp;
  return true;
}

以下代碼調用該函數:

/*原文如此

int *a = 10;
int *b = 15;

*/

int a1 = 10 ;

int b1 =15 ;

int *a = &a1 ;

int *b = &b1 ;
if (swap(a, b))
{
  acutPrintf(
“整數a1,b1已交換數據,*a = %d, *b = %d
, *a, *b);
}

在以上代碼中,swap()函數設計成與常見(jiàn)的ARX函數一致的風(fēng)格,用一個(gè)bool類(lèi)型返回函數執行狀態(tài)。<ARX中,這個(gè)返回值通常使用Acad::ErrorStatus類(lèi)。>在調用函數時(shí),由于變量ab已經(jīng)聲明為指針,使用標識符ab訪(fǎng)問(wèn)的是int類(lèi)型變量的內存地址。

使用引用傳遞參數,可以這樣設計swap()函數:

bool swap(int &x, int &y)
{
int temp;
temp = x;
x = y;
y = temp;
return true;
}

使用代碼swap(int a, int b)調用以上函數時(shí),進(jìn)入函數體內,x、y分別是變量a、b的引用,對x、y操作就是操作變量a、b。函數返回后,變量a、b的值互相交換了。

注意:以上代碼只是交換兩個(gè)變量(或者指針指向的變量)的值。即將變量a、b(或指針a、b指向的變量)的修改為b、a(或指針b、a指向的變量)的值,而不是將指針a指向原來(lái)指針b指向的變量。也就是說(shuō),swap()函數調用前后,指針ab的值(地址)并沒(méi)有發(fā)生任何變化。(當然,引用關(guān)系在任何時(shí)候都不能修改。)要修改指針的地址值,應該使用指向指針的指針或者使用對指針的引用。這樣設計和調用函數:

bool swap(int **x, int **y); //使用指向指針的指針傳遞參數
int *a = 10;//
原文如此,不可
int *b = 15;// //
原文如此,不可
swap(&a, &b);

或者:

bool swap(int *&x, int *&y); //使用對指針的引用傳遞參數
int *a = 10; //
原文如此,不可
int *b = 15; //
原文如此,不可
swap(a,b);

在以上的兩個(gè)swap()函數以交換兩個(gè)指針的值,使指針a指向原來(lái)指針b指向的變量,指針b指向原來(lái)指針a指向的變量。
另外,由于引用關(guān)系不可修改,指向引用的指針和引用一個(gè)引用沒(méi)有實(shí)際意義。若編譯器允許它們存在,實(shí)際上也會(huì )退化為普通指針(或對指針的引用)和引用。這一點(diǎn)請讀者自行分析。

最后,我們看一個(gè)ARX程序中使用指針和引用傳遞參數的函數例子:

AcDbDatabase *pDb = new AcDbDatabase();
AcDbBlockTable *pBlkTbl;
pDb->getBlockTable(pBlkTbl, AcDb::kForRead);

ARX幫助中可以查看到,getBlockTable()函數的原型是:

Acad::ErrorStatus getBlockTable( AcDbBlockTable*& pTable, AcDb::OpenMode mode);

其中可以看到,函數的第一個(gè)參數是對一個(gè)AcDbBlockTable類(lèi)型指針的引用,從而可以在函數體內部對指針pBlkTbl進(jìn)行修改,使之指向pDb指針指向的圖形數據庫的塊表

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
C++中的引用
[原創(chuàng )] 程序員面試寶典:第七章 指針與引用
C++“引用作為參數”和“引用作為返回值”用法總結
C/C++語(yǔ)言精華《指針》
什么情況下使用指針的引用(指針)
C語(yǔ)言基本數據類(lèi)型簡(jiǎn)介
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久