【问题标题】:Updating pointers in a function更新函数中的指针
【发布时间】:2015-06-21 21:48:59
【问题描述】:

我正在向一个指针传递一个更新它的函数。但是,当函数返回指针时,它会返回到函数调用之前的值。

这是我的代码:

#include <stdio.h>
#include <stdlib.h>

static void func(char *pSrc) {
    int x;
    for ( x = 0; x < 10; x++ ) {
        *pSrc++;
    }

    printf("Pointer Within Function: %p\n", pSrc  );
}

int main(void) {

    char *pSrc = "Good morning Dr. Chandra. This is Hal. I am ready for my first lesson.";

    printf("Pointer Value Before Function: %p\n", pSrc  );

    func(pSrc);

    printf("Pointer Value After Function: %p\n", pSrc  );

    return EXIT_SUCCESS;
}

这是输出

Pointer Value Before Function: 0x100403050
Pointer Within Function: 0x10040305a
Pointer Value After Function: 0x100403050

我所期望的是函数后的值与函数内的值相匹配。

我尝试切换到char **pSrc,但效果不佳。

我确信答案相当简单,但我是一名正在康复的硬件工程师,似乎无法弄清楚:-)

【问题讨论】:

  • 您需要传递char *pSrc地址,这样您就可以修改pSrc 指向的内容(保留char *pSrc,将其传递为&amp;pSrc,并且让函数接受char **

标签: c function pointers pass-by-value


【解决方案1】:

函数内部的指针是传递的指针的副本。

他们都持有相同的地址但有不同的地址,因此更改其中一个持有的地址不会影响另一个。

如果你想增加函数内部的指针,传递它的地址,像这样

static void func(char **pSrc) {
    int x;
    for ( x = 0; x < 10; x++ ) {
        (*pSrc)++;
    }    
    printf("Pointer Within Function: %p\n", pSrc  );
}

func(&pSrc);

另外,注意不要修改内容,因为你的指针指向一个字符串字面量,而字符串字面量是不能修改的。

【讨论】:

    【解决方案2】:

    当你给一个函数的指针时,你有一个你最初拥有的引用值的副本。

    然后,如果您修改指针,您正在修改副本

    如果你想更新原来的指针,你需要用一个双指针** 传递它,这样你就可以修改原来的指针,传递一个“对引用的引用”(双指针)。

    【讨论】:

      【解决方案3】:

      C 使用 pass-by-value 进行函数参数传递。 pSrc 的值只是main()pSrc副本,而不是与main() 中的pSrc 相同的实体。这就是为什么在函数func() 中对pSrc 所做的任何更改都不会反映在main()(调用函数)中。

      但是,*pSrc 的所有更改都将持续。

      解决方案:要将main()pSrcfunc() 更改为,您需要从main() 传递一个指向pSrc(指向指针的指针)的指针,并相应地调整数据类型。此外,在这种情况下,请注意,pSrc 应该是可修改的(存在于读写内存中)。正如目前所写,main() 中的pSrc 不可修改。

      【讨论】:

      • C 也使用传递引用,不是吗?
      • @ryyker 是这样吗?请问怎么样?至少,据我所知,它没有。
      • 我认为正确的说法是 除了数组和函数,C 总是按值传递参数。 (例如 from here )我理解你的回答的重点,并没有真正的问题,只有这一点:)
      • @ryyker 我明白你的意思,但我不同意你的话。在数组的情况下,paramater 本身也仅按值传递。您可以从函数内部更改数组的基地址(考虑双指针)吗? :-)
      • 出于同样的原因,您是说如果我将一个指针传递给一个包含该结构成员值的结构吗?它们不是,但可以通过 reference 访问该结构的位置。下面是 another reference 详细介绍。
      【解决方案4】:

      C 是按值传递参数,因此它会在你的函数中创建一个 pSrc 的副本,并且你所做的所有更改都将应用于 pSrc 的一个副本。如果你想改变 pSrc 的值,那么你应该传递一个指向 pSrc 的指针,像这样:

      static void func(char **pSrc){ // pointer to char*
           int x;
           for (x = 0; x < 10; x++)
               (*pSrc)++
      }
      

      【讨论】:

        【解决方案5】:

        您通过传递pSrc 调用func。您认为您传递的是相同的变量——即func 在更改pSrc 时将在相同的内存位置上运行。这是错误的。

        func 获得pSrc 的副本。调用func 时内置的堆栈帧将拥有自己的pSrc。修改的是它的版本而不是调用函数的版本。

        要让func 对main 中的实际变量进行操作,您必须传递pSrc - &amp;pSrc 的地址。

        相关概念 - 按值传递和按引用传递。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-11-18
          • 2012-07-16
          • 1970-01-01
          • 1970-01-01
          • 2020-08-12
          相关资源
          最近更新 更多