2014-03-12 164 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++中,你可以在这种情况下,通过一个指针引用,而不是)。