引用调用 vs 复制调用调用

Posted

技术标签:

【中文标题】引用调用 vs 复制调用调用【英文标题】:Call by reference vs call by copy restore 【发布时间】:2015-02-07 05:49:54 【问题描述】:

我正在查看通过引用调用和通过复制/恢复调用。我有些困惑。假设我有一个 2 参数函数,每个参数递增 1。现在,如果我将这两个参数用作同一个变量,比如incr(i, i),在引用调用和复制/恢复调用的情况下会发生什么?

【问题讨论】:

C 只有“按值传递”。因此,您必须通过传递指针来模拟“通过引用传递”,而且我不确定您期望从复制/恢复中获得什么语义;太多取决于谁进行复制和谁进行恢复。也许***的Evaluation Strategy 文章可以提供帮助;它有一个关于“通过复制/恢复调用”的部分。 您可能还会发现What's the difference between call by reference and copy/restore? 相关。是否有理由问题不应作为该问题的副本关闭? 是的,我特别希望在 incr(i,i) 函数方面实现这两种情况。 【参考方案1】:

问题What's the difference between call by reference and copy/restore 部分涵盖了这一点,但并不完整。 Evaluation Strategy 上的***文章很有帮助。

这里有两个实现,并调用了一个函数incr(),它接受两个参数并且每个参数递增。

引用调用

#include <stdio.h>

void incr(int *pi1, int *pi2)

    (*pi1)++;
    (*pi2)++;


int main(void)

    int i = 57;
    printf("%d\n", i);
    incr(&i, &i);
    printf("%d\n", i);
    return 0;

输出:

57
59

通过复制/恢复调用

incr 函数实际上与引用调用版本相比没有变化。

#include <stdio.h>

void incr(int *pi1, int *pi2)

    (*pi1)++;
    (*pi2)++;


int main(void)

    int i = 57;
    printf("%d\n", i);
    
    int cr_0000 = i;    // Copy for first argument
    int cr_0001 = i;    // Copy for second argument
    incr(&cr_0000, &cr_0001);
    i = cr_0001;        // Restore for second argument
    i = cr_0000;        // Restore for first argument
    
    printf("%d\n", i);
    return 0;

输出:

57
58

请注意,使用此 incr() 函数,恢复值的顺序无关紧要,但如果 incr() 函数不对称地处理其参数(例如,将 1 添加到第一个,将 2 添加到第二个),那么最终结果取决于cr_0000 是否在cr_0001 之前恢复,反之亦然。

【讨论】:

我明白了!非常感谢!! 虽然我知道输出是如何生成的……但我并没有明白复制/恢复背后的全部意义。它的“复制原始变量,通过引用传递副本,将副本重新分配回原始变量”。给专用名称“复制/恢复”有什么好处? @Mahesha999 第二个也是引用调用,他只是做了一些不同的事情。直到我在一些试卷上看到它,我才听到它,我认为他们编造了它

以上是关于引用调用 vs 复制调用调用的主要内容,如果未能解决你的问题,请参考以下文章

如果我没有更改状态的引用,为啥 React 会调用渲染函数? [复制]

read() 系统调用会复制数据而不是传递引用

复制引用的对象并调用虚方法 C++

std::thread 通过引用传递调用复制构造函数

std::thread 按引用传递调用复制构造函数

PHP:为啥用括号括起来的函数调用会阻止“通过引用”通知? [复制]