需要一个指针指针

时间:2010-11-11 09:51:45

标签: c++ c pointers

  

可能重复:
  How do pointer to pointers work in C?

大家好,

我有一个非常基本的问题: 在C或C ++中使用双指针有什么用?

有人可以通过一些例子向我解释。

谢谢,

6 个答案:

答案 0 :(得分:4)

如果要更改原始指针在函数调用中指向的内容,则需要**。这是因为当您传递指针时,您传递的是指针的副本,即,如果您修改指针指向函数内部的内容(即,更改指针本身的值),它将反映在副本中但不会原始的(不同于修改原始指针指向的内容,而不是将其指向一个全新的对象)。

此外,可以通过指向指针的指针访问多维数组(指向指针的指针......无限制地)。

答案 1 :(得分:2)

常规数据指针是某个变量的地址。

指针本身也是变量,因此具有地址,因此它们是指针的指针。

在C语言中使用的指针多于在C ++中使用指针,因为在C ++中有一种使用引用的替代语法,以及指针多次包装在类中而不是直接使用的事实。

在C中,以下示例释放指针中的结构,并将传入的指针设置为NULL。

void FreeMyStruct( struct MyStruct ** ptr )
{
   free((*ptr)->resource);
   free(*ptr);
   *ptr = NULL;
}

您可以使用指针执行相同的操作,但如果将其设置为NULL,则对函数的调用者没有任何影响,因为它将是您将设置为NULL的指针的副本。

答案 2 :(得分:1)

来自C标准的例子:

long int strtol(
                const char * restrict nptr,
                char ** restrict endptr,
                int base);

...指向最终字符串的指针存储在endptr指向的对象中,前提是endptr不是空指针。

如果主题序列为空或没有预期的形式,则不进行转换 执行; nptr的值存储在endptr指向的对象中,提供 该endptr不是空指针。

答案 3 :(得分:1)

int main(int argc, char** argv);

努夫说? ; - )

答案 4 :(得分:1)

函数体使用其参数的副本进行操作。因此,当您想要更改作为函数参数传递的某个变量时,实际上需要传递变量的地址 - 它的指针。函数获取该指针的副本,该指针具有原始变量的地址,因此函数可以更改变量的值。同样,当您想要更改某个指针的值时,您需要将其地址作为函数参数传递。

典型示例是函数需要为某些数据结构重新分配内存的情况。在这个例子中,我们想要将一个字符数组传递给一个向它附加单个字符的函数。函数需要为新(扩展)数组重新分配内存,这意味着它的指针需要指向内存中的新位置 - 它的值需要更改。注意* pp(取消引用指针指针)被分配了值的行:

#include <iostream>
using namespace std;

void append_char(char** pp, char ch)
{
    // copy of pp is passed here

    if(pp)
    {
        if(*pp)
        {
            // pointer is already pointing to formed array of characters

            // 1. allocate memory for a new (extended) array 
            int nLen = strlen(*pp);
            // one place for ch and one for zero-termination 
            int nNewLen = nLen + 2;
            char* pNewStr = new char[nNewLen];

            // 2. copy existing array into a new one
            strcpy(pNewStr, (const char*)*pp);

            // 3. append new character
            pNewStr[nNewLen - 2] = ch;
            pNewStr[nNewLen - 1] = '\0';

            // 4. free memory of old array
            delete[] *pp;

            // 5. assign new pointer's value
            *pp = pNewStr;
        }
        else
        {
            // pointer is NULL - passed character will be the first in a new array

            // 1. allocate memory, fill the array and assign new pointer's value
            *pp = new char[2];          
            (*pp)[0] = ch;
            (*pp)[1] = '\0';
        }
    }
}

int main()
{   
    char* p = new char[3];
    p[0] = 'A';
    p[1] = 'B';
    p[2] = '\0';

    cout << p << endl;

    append_char(&p, 'C');

    cout << p << endl;

    delete[] p;

    return 0;
}

我在这里使用了C风格的字符串,因为它是内存管理的常见示例。在您的C ++代码中,尽量避免使用C字符串并使用C ++强制转换运算符。

答案 5 :(得分:0)

马上就会想到一件事 -
当您使用“通过指针传递”传递指向函数的指针时,只有指针的副本传递给函数。我们可以说“通过指针传递”,它实际上是按值传递指针。在大多数情况下,这不会产生问题。但是,修改函数内部的指针时会出现问题。您只修改指针的副本而不是修改变量,而原始指针保持不变,即它仍然指向旧变量