究竟有什么区别&QUOT的差异;参照&QUOT通过;在C和C ++中? [英] What exactly is the difference between "pass by reference" in C and in C++?

查看:278
本文介绍了究竟有什么区别&QUOT的差异;参照&QUOT通过;在C和C ++中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

短语按引用传递所使用的C和C ++开发人员的一致好评,但他们似乎被用来意味着不同的事情。究竟是什么在每种语言模棱两可这句话有什么区别?

The phrase "pass by reference" is used by C and C++ developers alike but they appear to be used to mean different things. What exactly is the difference between this equivocal phrase in each language?

推荐答案

有已经处理通过引用传递的区别问题和值传递。从本质上说,按值传递参数给函数意味着函数都会有自己的说法副本 - 它的的复制。修改该副本不会修改原始的对象。但是,通过引用传递时,函数内部的参数的的中传递相同的对象 - 在函数中的任何更改将被外面看到

There are questions that already deal with the difference between passing by reference and passing by value. In essence, passing an argument by value to a function means that the function will have its own copy of the argument - its value is copied. Modifying that copy will not modify the original object. However, when passing by reference, the parameter inside the function refers to the same object that was passed in - any changes inside the function will be seen outside.

不幸的是,有两种方式短语按值传递和按引用传递用于这可能会导致混乱。我相信这是为什么指针和引用是很困难的新的C ++程序员采用,尤其是当他们来自于C语言背景。

Unfortunately, there are two ways in which the phrases "pass by value" and "pass by reference" are used which can cause confusion. I believe this is partly why pointers and references can be difficult for new C++ programmers to adopt, especially when they've come from a background in C.

在C,一切都按值在技术意义上通过。也就是说,无论你给作为参数传递给一个函数,它会被复制到该功能。例如,调用一个函数无效美孚(INT)富(X)拷贝的价值 X 富。这可以在一个简单的例子可以看出:

In C, everything is passed by value in the technical sense. That is, whatever you give as an argument to a function, it will be copied into that function. For example, calling a function void foo(int) with foo(x) copies the value of x as the parameter of foo. This can be seen in a simple example:

void foo(int param) { param++; }

int main()
{
  int x = 5;
  foo(x);
  printf("%d\n",x); // x == 5
}

的值x 复制到和副本递增。在 X 继续拥有其原始值。

The value of x is copied into foo and that copy is incremented. The x in main continues to have its original value.

我敢肯定,你知道,对象可以是指针类型。例如,为int * P 定义 P 作为一个指向 INT 。要注意的是以下code引入两个对象是很重要的:

As I'm sure you're aware, objects can be of pointer type. For example, int* p defines p as a pointer to an int. It is important to note that the following code introduces two objects:

int x = 5;
int* p = &x;

首先是类型 INT 和值为 5 。第二种类型是为int * 和它的值是第一个对象的地址。

The first is of type int and has the value 5. The second is of type int* and its value is the address of the first object.

在传递一个指向函数的指针,你还在按值传递的。它包含的地址被复制到功能。修改指针的函数内不会改变指针函数外 - 但是,修改的它指向的对象,以的将改变函数外部的对象。但是,为什么?

When passing a pointer to a function, you are still passing it by value. The address it contains is copied into the function. Modifying that pointer inside the function will not change the pointer outside the function - however, modifying the object it points to will change the object outside the function. But why?

由于两个指针具有相同的值总是在相同的对象(它们包含相同的地址)点,来可以访问正在被指向的对象,并通过这两个修改。这使得已通过有针对性的参考对象的语义,虽然没有引用过实际存在的 - 目前根本是没有C.参考看看更改例如:

As two pointers that have the same value always point at the same object (they contain the same address), the object that is being pointed to may be accessed and modified through both. This gives the semantics of having passed the pointed to object by reference, although no references ever actually existed - there simply are no references in C. Take a look at the changed example:

void foo(int* param) { (*param)++; }

int main()
{
  int x = 5;
  foo(&x);
  printf("%d\n",x); // x == 6
}

我们可以路过时说,为int * 成一个功能,即在 INT 它指向的是通过通过参考,但在真理的 INT 从来没有真正随时随地通过在所有 - 只有指针被复制到的功能。这给我们通俗 1 的按值传递和按引用传递的含义。

We can say when passing the int* into a function, that the int it points to was "passed by reference" but in truth the int was never actually passed anywhere at all - only the pointer was copied into the function. This gives us the colloquial1 meaning of "pass by value" and "pass by reference".

该术语的使用由标准中的术语备份。当你有一个指针类型,它指向的类型被称为它的引用类型的。也就是说,引用类型为int * INT

The usage of this terminology is backed up by terms within the standard. When you have a pointer type, the type that it is pointing to is known as its referenced type. That is, the referenced type of int* is int.

A 指针类型的可从函数类型,对象类型,或不完整的派生
  类型,叫做引用类型

A pointer type may be derived from a function type, an object type, or an incomplete type, called the referenced type.

虽然一元 * 运算符(如 * P )被称为标准间接,它是通常也被称为解除引用的指针。这进一步促进了按引用传递,在C的概念。

While the unary * operator (as in *p) is known as indirection in the standard, it is commonly also known as dereferencing a pointer. This further promotes the notion of "passing by reference" in C.

C ++采用了许多原有的语言功能从C.其中是指针,因此仍然可以使用按引用传递这一口语化的形式 - * P 是还是取消引用 p 。但是,使用期限将是混乱的,因为C ++引入了一项功能,C没有:真正通过能力的引用

C++ adopted many of its original language features from C. Among them are pointers and so this colloquial form of "passing by reference" can still be used - *p is still dereferencing p. However, using the term will be confusing, because C++ introduces a feature that C doesn't have: the ability to truly pass references.

A型后跟一个符号是一个的引用类型 2 。例如, INT和放大器; 是一个参考 INT 。传递参数给需要引用类型的函数时,对象是真正按引用传递。有没有指针参与其中,没有对象的复制,什么都没有。该函数中的名称实际上是指正是在传递同一个对象要与上面的例子对比:

A type followed by an ampersand is a reference type2. For example, int& is a reference to an int. when passing an argument to a function that takes reference type, the object is truly passed by reference. There are no pointers involved, no copying of objects, no nothing. The name inside the function actually refers to exactly the same object that was passed in. To contrast with the example above:

void foo(int& param) { param++; }

int main()
{
  int x = 5;
  foo(x);
  std::cout << x << std::endl; // x == 6
}

现在的函数有一个参数,它是引用到 INT 。现在,路过时 X 参数指的是precisely同一个对象。递增参数对的 X 价值的明显的变化,现在 X 的值是6。

Now the foo function has a parameter that is a reference to an int. Now when passing x, param refers to precisely the same object. Incrementing param has a visible change on the value of x and now x has the value 6.

在这个例子中,没有什么是按值传递。没有被复制。不像C,其中引用传递真的只是按值传递一个指针,在C ++中,我们可以真正按引用传递。

In this example, nothing was passed by value. Nothing was copied. Unlike in C, where passing by reference was really just passing a pointer by value, in C++ we can genuinely pass by reference.

由于在本任期潜在歧义按引用传递,这是最好的时候,使用的是引用类型,只使用它的C ++的上下文。如果你正在传递一个指针,你是不是通过引用传递,你是按值传递的指针(即,当然,除非你是传递一个参考的指针如为int *&放大器; <! / code>)。您可能,但是,遇到的按引用传递时,正在使用指针,用途,但现在至少你知道什么是真正发生的事情。

Because of this potential ambiguity in the term "pass by reference", it's best to only use it in the context of C++ when you are using a reference type. If you are passing a pointer, you are not passing by reference, you are passing a pointer by value (that is, of course, unless you are passing a reference to a pointer! e.g. int*&). You may, however, come across uses of "pass by reference" when pointers are being used, but now at least you know what is really happening.

其他编程语言的事情进一步复杂化。在有些国家,如Java,每次你有变量被称为引用对象(不一样的C ++中的引用,更像是一个指针),但是这些引用是按值传递。因此,即使你似乎通过引用传递给函数,你实际上做的是通过复制值的引用到函数。当你分配一个新的对象来传入的引用在C ++中引用传递这细微的差别是注意到了:

Other programming languages further complicate things. In some, such as Java, every variable you have is known as a reference to an object (not the same as a reference in C++, more like a pointer), but those references are passed by value. So even though you appear to be passing to a function by reference, what you're actually doing is copying a reference into the function by value. This subtle difference to passing by reference in C++ is noticed when you assign a new object to the reference passed in:

public void foo(Bar param) {
  param.something();
  param = new Bar();
}

如果你调用Java中这个功能,传递键入酒吧的一些对象,调用 param.something()你会传入同一个对象上调用,这是因为你在你的对象引用传递。不过,即使新的酒吧分配给参数,在函数外的对象仍然是老一套的对象。新一从未从外部看到。这是因为 foo的内部参考被重新分配给新的对象。这种重新分配的引用是不可能的C ++引用。

If you were to call this function in Java, passing in some object of type Bar, the call to param.something() would be called on the same object you passed in. This is because you passed in a reference to your object. However, even though a new Bar is assigned to param, the object outside the function is still the same old object. The new one is never seen from the outside. That's because the reference inside foo is being reassigned to a new object. This kind of reassigning references is impossible with C++ references.

1 通过口语化,我的意思并不是暗示的按引用传递的C意思是比C ++的意思,只是C ++确实有引用类型的任何真实的少等你真正通过的参考的传递。的C意思是在什么真正的按值传递是一种抽象。

1 By "colloquial", I don't mean to suggest that the C meaning of "pass by reference" is any less truthful than the C++ meaning, just that C++ really does have reference types and so you are genuinely passing by reference. The C meaning is an abstraction over what is really passing by value.

2 当然,这些都是左值引用,我们现在有右值引用过C ++ 11。

2 Of course, these are lvalue references and we now have rvalue references too in C++11.

这篇关于究竟有什么区别&QUOT的差异;参照&QUOT通过;在C和C ++中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆