【问题标题】:Need for a pointer to pointer [duplicate]需要一个指向指针的指针[重复]
【发布时间】:2010-11-11 09:51:44
【问题描述】:

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

大家好,

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

请有人用一些例子解释一下。

谢谢,

【问题讨论】:

标签: c++ c pointers


【解决方案1】:

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

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

【讨论】:

  • 你能给我一个场景,我只能使用双指针而不是单指针来实现逻辑吗?
【解决方案2】:

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

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

指针在 C 中的使用比在 C++ 中更多,因为在 C++ 中有一种使用引用的替代语法,以及很多时候指针被包装在类中而不是直接使用的事实。

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

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

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

【讨论】:

    【解决方案3】:

    来自 C 标准的示例:

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

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

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

    【讨论】:

      【解决方案4】:
      int main(int argc, char** argv);
      

      纳夫说? ;-)

      【讨论】:

        【解决方案5】:

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

        典型的例子是函数需要为某些数据结构重新分配内存的情况。在这个例子中,我们想将一个字符数组传递给一个函数,该函数将一个字符附加到它上面。函数需要为一个新的(扩展的)数组重新分配内存,这意味着它的指针需要指向内存中的一个新位置——它的值需要改变。注意 *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++ 强制转换运算符。

        【讨论】:

          【解决方案6】:

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

          【讨论】:

          • 哇 - 有人决定对有效回复投反对票,甚至没有提供解释!顺便说一句,有没有办法让某人找出哪个用户对他/她的答案投了反对票?
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2010-10-27
          • 1970-01-01
          • 1970-01-01
          • 2010-10-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多