2014-03-12 190 views
0

Here我讀了一篇關於何時將指針作爲函數參數的文章。但是我想知道一些你應該將指針指針作爲函數參數傳遞的情況。 更清楚,我想知道什麼時候應該使用這樣的:何時將指針的指針作爲參數傳遞給C++中的函數?

func(int **x); 
+1

當你需要改變一個指針參數,例如'int alloc_my_object(my_object ** ob1)'。基本上如果你有一個需要改變的參數,那麼你將它作爲一個指針傳入..如果參數類型已經是一個指針,那麼你將傳遞一個'指針指針' – amdixon

+3

@amdixon你爲什麼要這樣做,而不是通過通過引用指針? – Angew

+0

更好地閱讀一些更多的文章,那是基於錯誤的前提E.g. '使用引用傳遞大對象'。這只是過早的優化,並不是通過引用傳遞的好理由。你應該根據你將要做的事情來選擇如何傳遞對象,並且傳遞指針是alomost * never *你真正需要的。 http://stackoverflow.com/questions/15600499/how-to-pass-parameters-correctly/15600615 http://stackoverflow.com/questions/270408/is-it-better-in-c-to-pass-by -value-or-pass-by-constant-reference/271344 – stijn

回答

2

C++

在C++中,可以通過引用傳遞,並且你,當所需要的參數的修改,以影響其中呼叫者在傳遞的參數,即,通過引用表示出來或輸入/輸出參數。

你傳遞一個指針,如果函數想要一個指針(明顯),或者如果你想表示一個可選的輸出參數 - 因爲引用總是具有結合的東西,但指針可以爲空。如果函數實際上需要雙指針(在C++中非常少見),或者如果您想表示指針類型的可選[in] out參數(也很少見),則通過相同的邏輯將指針傳遞給指針。

這裏有一些例子(做作,而是應該證明的東西):

int square(int x) //pass int by value 
{ return x * x; } 

void squareRoots(double in, double &plus, double &minus) //pass double by reference 
{ 
    plus = sqrt(in); 
    minus = -plus; 
} 

int toNumber(String s, bool *ok = nullptr) //optional out parameter 
{ 
    try { 
    int val = s.toNumber(); 
    if (ok) 
     *ok = true; 
    return val; 
    } catch (NotANumber &) { 
    if (ok) 
     *ok = false; 
    return 0; 
    } 
} 

int computeAge(Person *person) //pass pointer by value 
{ 
    if (!person) 
    return -1; 
    else 
    return now() - person->dateOfBirth(); 
} 

bool createPerson(Person * &person) //pass pointer by reference 
{ 
    if (tooManyPeople()) 
    return false; 
    person = new Person(); 
    return true; 
} 

int sum(int **values) //pass double pointer by value 
{ 
    if (!values) 
    return 0; 
    int res = 0; 
    while (*values) { 
    res += **values; 
    ++values; 
    } 
    return res; 
} 

bool allocate(int ** &arr) //pass double pointer by reference 
{ 
    if (!enoughMemory()) 
    return false; 
    arr = new int*[1024]; // array of 1024 pointers to int 
    return true; 
} 

bool newNode(Node **node = nullptr) //optional out parameter 
{ 
    Node *added = dataStructure.createNode(); 
    if (node) 
    *node = added; 
    return added; 
} 

(注1:我只談論非const引用在這裏,因爲這是有關路過指針與通過const引用傳遞通常意味着「對象太大而無法複製」,並且在指向指針的指針可能會涉及時並不適用)。 (注2:上面的例子很可怕,因爲它們使用擁有原始指針,動態數組分配等等。在實際的C++中,你可以使用智能指針,std::vector等等。這就是爲什麼指針指針在C++中很少見)。


Ç

在C中,雙指針是更常見的,因爲C沒有引用類型。因此,您還使用指向「通過引用傳遞」的指針。其中&用於上述C++示例中的參數類型中,*將用於C(並在操作參數時解除引用)。舉例:

void squareRoots(double in, double *plus, double *minus) //pass double "by reference" 
{ 
    *plus = sqrt(in); 
    *minus = -*plus; 
} 
1
void SomeFun1(int *); 
void SomeFun2(int **); 
int i; 
int *ptr = &i; 

//when you want value of ptr should remain unchanged, but you want to change only value of i, use, 
SomeFun1(int *) 

//when you want value of ptr should change. i.e, it should point to some other memory other than i, use, 
SomeFun2(int **); 
1

你傳遞一個指針的指針作爲參數,當你想要的功能設定指針的值。

您通常這樣做時,該函數要分配內存(通過malloc的或新的),並設置參數該值 - 那麼這將是主叫方的釋放它的責任。它比返回它作爲函數的返回值要好,因爲調用者不可能錯誤地忽略返回值,並且通過不釋放它而導致泄漏。

您也可能想,如果你正在返回多個值使用此。

另一個原因要做到這一點,當你想要選擇返回值(即指針的指針可以爲空)。例如,看看strtol()它有一個可選的endptr。

注意:永遠不要這個指針設置爲堆棧變量。

0

這也許是我的看法。但是,如果您希望將NULL用作完美值(例如,在鏈接列表中),則應將指針用於變量。 當您不希望將您的值初始化爲NULL時,應該使用參考。否則,引用和指針在很多方面都是相似的。您可以更改函數內的指針或參考參數的值。它們都是多態的。 ...

1

什麼也沒有被提及是動態分配二維數組 - 本質上,你將有指向其他指針數組的指針。

1
  • 當您要傳遞指針數組時,您將使用<type>**

例子:

int main(int argc, char **argv) { // argv is an array of char* 
  • ,如果你希望能夠改變指針地址也將使用它(在C++中,你可以在這種情況下,通過一個指針引用,而不是)。