【问题标题】:Passing pointer to function is'nt passing by reference in C?将指针传递给函数不是在 C 中通过引用传递吗?
【发布时间】:2016-12-04 12:47:13
【问题描述】:
#include<stdio.h>
int func(int*);
int main(void)
{
        int a = 3;
        int *p = NULL;
        p = &a;
        printf("p = %p\n", p);
        func(p);
        printf("p inc: %p\n", p);
        return 0;
}
int func(int *p)
{
        p++;
        return 0;
}

输出:p=0x7fff6f87e89c p 公司:0x7fff6f87e89c

指针 p 被传递给函数 func 并且指针 p 在 func 中递增,但在 main 函数中它的地址仍然相同!将指针传递给函数不是通过引用传递吗?

【问题讨论】:

  • 注意:在c中没有通过引用传递
  • 您要递增maina 还是mainp
  • 我只是想检查指针的地址,我在函数func()中增加指针的地址,想检查它是否反映在main()中
  • 然后你需要传递指针的地址,在函数内部解引用它并增加这个解引用的结果。

标签: c pointers pass-by-reference


【解决方案1】:

指针按值传递。
如果你想通过引用传递一个指针,你只需传递一个指针的指针!

像这样:

#include<stdio.h>
int func(int**);
int main(void)
{
    int a = 3;
    int *p = NULL;
    p = &a;
    printf("p = %p\n", p);
    func(&p);
    printf("p inc: %p\n", p);
    return 0;
}
int func(int **p)
{
    (*p)++;
    return 0;
}

【讨论】:

  • 差不多。您仍在按值传递指针。唯一改变的是指针指向的对象类型。
【解决方案2】:

C 中没有引用传递。当你传递一个指向函数的指针时,你是在传递一个内存地址。

当你在函数内部这样做时:

int func(int *p)
{
    p++;
    return 0;
}

...您只是将参数p 指示的内存地址增加sizeof *p 字节。

为了在 C 中通过引用“模拟”通过,您需要显式取消引用指针以访问实际对象。如果p 是一个正确分配且有效的指针,那么*p 就是它指向的对象。如果非指针表达式是这样的:

a = a + 1;

...然后p == &amp;a 会变成这样:

*p = *p + 1;

...或者只是(*p)++。请注意,括号是必需的,否则 C 会将其读作*(p++)。你也可以习惯改写++*p

【讨论】:

    【解决方案3】:

    你增加的是指针,而不是值。

    这样试试

    (*p)++;
    

    printf("p inc: %d\n", *p);
    

    您需要了解指针。指针只是一个变量,用于存储数据实际所在的内存地址。您可以使用解引用运算符* 访问数据,因此如果要更改数据,只需解引用指针,然后修改数据即可。

    同样,对于打印,您希望查看数据的值。

    在您的代码中,您只需修改指针。在 c 中,您总是按值传递,指针本身的副本在 func() 函数内创建,最初它与原始指针拥有相同的地址,但由于它是一个副本,因此递增它只会影响本地地址复制。

    更进一步,因为它指向堆栈上的一个变量。对它的递增操作将导致您无法取消引用的指针,因为这将是未定义的行为。

    如果要增加指针的地址,需要给指针传递一个指针,像这样

    void func(int **p)
    {
        (*p)++;
    }
    

    主要是

    func(&p);
    

    注意func() 的主体是相同的,因为您需要再次访问p 指向的内存才能对其进行修改。

    【讨论】:

    • 建议你去掉“虚拟”和脚注。 C 没有虚拟内存和物理内存的概念。
    猜你喜欢
    • 2019-09-16
    • 2014-07-26
    • 2017-11-12
    • 2014-12-21
    • 2020-05-14
    • 1970-01-01
    • 1970-01-01
    • 2010-09-20
    • 1970-01-01
    相关资源
    最近更新 更多