在 C 中通过引用和值传递

新手上路,请多包涵

我想澄清按值和按引用之间的区别。

我画了一张图:

在此处输入图像描述

因此,对于按值传递,使用不同的引用创建相同对象的副本,并为局部变量分配新的引用,因此指向新副本

我应该如何理解以下内容?

如果函数修改了该值,则修改也出现在调用函数的范围内,用于按值传递和按引用传递

原文由 user36064 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 286
1 个回答

我认为不传达 引用传递的 含义会产生很多混乱。当有些人说 通过引用传递 时,他们通常不是指参数本身,而是 _被引用的对象_。其他人说通过引用传递意味着对象不能在被调用者中更改。例子:

 struct Object {
    int i;
};

void sample(Object* o) { // 1
    o->i++;
}

void sample(Object const& o) { // 2
    // nothing useful here :)
}

void sample(Object & o) { // 3
    o.i++;
}

void sample1(Object o) { // 4
    o.i++;
}

int main() {
    Object obj = { 10 };
    Object const obj_c = { 10 };

    sample(&obj); // calls 1
    sample(obj) // calls 3
    sample(obj_c); // calls 2
    sample1(obj); // calls 4
}

有些人会声称 1 和 3 是通过引用传递,而 2 是通过值传递。另一组人说除了最后一个之外都是按引用传递,因为对象本身没有被复制。

我想在这里定义我声称 通过引用传递的 内容。可以在此处找到对其的一般概述: 按引用传递和按值传递之间的区别。第一个和最后一个是值传递,中间两个是引用传递:

     sample(&obj);
       // yields a `Object*`. Passes a *pointer* to the object by value.
       // The caller can change the pointer (the parameter), but that
       // won't change the temporary pointer created on the call side (the argument).

    sample(obj)
       // passes the object by *reference*. It denotes the object itself. The callee
       // has got a reference parameter.

    sample(obj_c);
       // also passes *by reference*. the reference parameter references the
       // same object like the argument expression.

    sample1(obj);
       // pass by value. The parameter object denotes a different object than the
       // one passed in.

我投票支持以下定义:

当且仅当被调用函数的相应参数具有引用类型 并且 引用参数直接绑定到参数表达式 (8.5.34) 时,参数 (1.3.1) 才通过引用传递。在所有其他情况下,我们都必须通过值传递。

这意味着以下内容是按值传递的:

 void f1(Object const& o);
f1(Object()); // 1

void f2(int const& i);
f2(42); // 2

void f3(Object o);
f3(Object());     // 3
Object o1; f3(o1); // 4

void f4(Object *o);
Object o1; f4(&o1); // 5

1 是按值传递,因为它不是直接绑定的。实现可以复制临时文件,然后将该临时文件绑定到引用。 2 是按值传递的,因为实现会初始化文字的临时值,然后绑定到引用。 3 是传值,因为参数没有引用类型。 4 出于同样的原因按值传递。 5 是传值,因为参数没有得到引用类型。以下情况通过引用传递(根据 8.5.34 和其他规则):

 void f1(Object *& op);
Object a; Object *op1 = &a; f1(op1); // 1

void f2(Object const& op);
Object b; f2(b); // 2

struct A { };
struct B { operator A&() { static A a; return a; } };
void f3(A &);
B b; f3(b); // passes the static a by reference

原文由 Johannes Schaub - litb 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题