C语言中的引用是什么?

发布于 2024-09-14 08:35:40 字数 393 浏览 9 评论 0原文

我刚刚开始使用C++,遇到过一些参考资料,但还没有完全理解。

正如我读到的,引用是对象的替代名称。为什么要使用它而不是直接访问对象,因为对引用的任何操作都会直接反映在对象上......?

  1. 为什么以及何时使用它们?
  2. ist 是否像一个常量指针,每次使用时都会被引用......?

而且,它说

 double& dr = 1;  ----  says it is an error (some lavalue needed) 
 const double& cdr = 1;  ---- says it is ok. 

我没有正确理解它。所以请解释为什么会这样...

谢谢...:)

I have just started C++ and have come across references and have not understood completely.

References , as i read is an alternative name for an object.Why use that instead of directly accessing the object as any operation on references is directly reflected on the object ...?

  1. Why and when are they used ?
  2. Is ist like a constant pointer that is referenced each time it is used ... ?

And , it says

 double& dr = 1;  ----  says it is an error (some lavalue needed) 
 const double& cdr = 1;  ---- says it is ok. 

i dont understand it properly..So please explain why it is so ...

Thank You...:)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

岁月流歌 2024-09-21 08:35:59

传递对函数的引用,然后让函数使用该引用几乎就像将指针传递给函数,然后让函数取消引用该指针一样。在许多情况下,机器代码实现是相同的。不过,还是存在一些差异,尤其是在内联扩展的函数的情况下。如果变量通过引用传递给内联函数,则编译器在扩展函数时通常能够替换变量本身(即使存储在机器寄存器中)。相比之下,如果获取变量的地址并将其作为指向函数的指针传递,然后取消引用它,则编译器不太可能找出该优化,除非它不仅确定这一点 - 至少对于一个特定的扩展函数——指针将始终指向该变量,但指针不会在其他任何地方使用(如果指针在其他地方使用,则该变量不能保存在寄存器中)。

Passing a reference to a function and then having the function use the reference is almost like passing a pointer to the function and then having the function dereference the pointer. In many cases, the machine-code implementation will be identical. There are some differences, though, especially in the case of functions that get expanded inline. If a variable is passed by reference to an inline function, the compiler will often be able to substitute the variable itself--even if stored in a machine register--when expanding the function. By contrast, if one takes the address of a variable and passes that as a pointer to a function which then dereferences it, the compiler is less likely to figure out that optimization unless it determines not only that--at least for one particular expansion of the function--the pointer will always point to that variable, but also that the pointer will not be used anywhere else (if the pointer was used elsewhere, the variable could not be kept in a register).

剩余の解释 2024-09-21 08:35:58

引用的实用性在将参数传递给函数的上下文中最为明显。

即,

int a;

func 定义: void foo (int¶m) {param = 1;}

func 调用: foo(a);

“param”别名“a”的方式很干净,其意图很容易被该代码的读者以及编译器理解,当内联引用所需的任何额外内存分配时,编译器可能会进行优化。

Utility of references is most visible in the context of passing parameters to functions.

I.e,

int a;

func definition: void foo (int& param) {param = 1;}

func call: foo(a);

The way as 'param' aliases 'a' is clean and its intention is easily understood by a reader of this code as well as compiler that may optimize away when inlining any additional memory allocation needed for the reference.

何以心动 2024-09-21 08:35:56
double& dr = 1; // 1.0 would be more clear

无效,因为 1 被视为 const double 类型,因此如果您想要引用该变量,则需要引用 const double代码>所以

const double& dr = 1.0;

是正确的。

double& dr = 1; // 1.0 would be more clear

Is invalid because 1 is viewed to be of type const double so if you want a reference to that variable you need to have a reference to a const double so

const double& dr = 1.0;

Is correct.

十级心震 2024-09-21 08:35:54

引用是代表它们引用的另一个对象的语言实体。非常量引用是左值,必须使用左值进行初始化。它们的用途如下:

int& x=condition ? array[1] : array[2];
int& y=condition ? array[0] : array[3];
x+=y;
y=0;

当用作函数参数时,它们告诉调用者必须传递一个可能由函数写入的左值:

void set1(int& x) { x=1; }

int foo;
set1(foo); // ok, foo is 1
set1(foo+1); // not OK, not lvalue

另一方面,常量引用可以绑定到右值。在函数参数中,它们通常用于避免过多的复制:

void niceness(std::string s); // the string would be copied by its copy-ctor
void niceness(const std::string& s); // the caller's string would be used

请注意,这可能会也可能不会产生更快的代码。

当在普通代码中使用 const 引用时,它们也可以绑定右值,并且 作为一条特殊规则,它们延长了所绑定对象的生命周期。这就是您在代码中看到的:

const double& d=1; // OK, bind a rvalue to a const-ref
double& d=1; // Bad, need lvalue

所有引用都是多态的,就像指针一样:

class A { virtual void f(); }
class B : public A { void f(); }

B b;
A& ar=b;
ar.f(); // calls B::f()

并且所有引用都是别名,就像指针一样:

int f(int& a, const int& b)
{
  a=1;
  return b;
}

int x;
f(x, 42); // ==42, foo=1
x=42;
f(x, x); // ==1 (not 42), foo=1

References are language entitities that represent another object they refer to. Nonconst references are lvalues, and must be initialized with an lvalue. They can be useful like this:

int& x=condition ? array[1] : array[2];
int& y=condition ? array[0] : array[3];
x+=y;
y=0;

When used as a function parameter, they tell the caller he has to pass an lvalue that might be written to by the function:

void set1(int& x) { x=1; }

int foo;
set1(foo); // ok, foo is 1
set1(foo+1); // not OK, not lvalue

Const references, on the other hand, can be bound to rvalues. In function parameters, they are usually used to avoid excessive copies:

void niceness(std::string s); // the string would be copied by its copy-ctor
void niceness(const std::string& s); // the caller's string would be used

Note that this may or may not yield faster code.

When const-references are used in normal code, they can bind rvalues, too, and as a special rule, they extend the lifetime of the object they are bound to. This is what you saw in your code:

const double& d=1; // OK, bind a rvalue to a const-ref
double& d=1; // Bad, need lvalue

All references are polymorphic, like pointers:

class A { virtual void f(); }
class B : public A { void f(); }

B b;
A& ar=b;
ar.f(); // calls B::f()

and all references are aliases like pointers:

int f(int& a, const int& b)
{
  a=1;
  return b;
}

int x;
f(x, 42); // ==42, foo=1
x=42;
f(x, x); // ==1 (not 42), foo=1
当爱已成负担 2024-09-21 08:35:50

仔细阅读维基百科文章。总而言之,引用是指针的更友好版本,通常用于将对象作为引用传递到函数中,而不必担心空指针。

解释这个例子:


将数字1想象为一个变量。编译时,该数字被放入内存的全局部分,程序可以引用它,但修改。

所以它的类型是: const int

double &dr = 1 正在尝试分配 dr (对 double<的 引用/strong>) 到 const int 1。由于 1 是一个常量,编译器不允许您对其进行非常量引用。

在第二行中:

const double &dr = 1 尝试将 dr对 double 的常量引用)分配给 常量 int 1。这是可行的,因为引用也是const,因此可以指向const int

编辑
const int 在分配之前会转换为 const double

Give the wikipedia article a good read through. To sum it up, references are more friendly version of pointers which are commonly used to pass objects as references into functions without worrying about a null pointer.

To explain the example:


Think of the number 1 represented as a variable. When compiled, this number is put into the global section of the memory which can be referenced by the program, but not modified.

So it is of type: const int

double &dr = 1 is trying to assign dr (a reference to a double) to the const int 1. Since 1 is a constant, the compiler will not allow you to make a non-constant reference to it.

In the second line:

const double &dr = 1 is trying to assign dr (a constant reference to a double) the const int 1. This works because the reference is also const and therefore can point to a const int.

EDIT
The const int is converted to a const double before assigned.

春夜浅 2024-09-21 08:35:48

引用改进了语法,因此不需要指针取消引用。
假设 Base 是一个可能派生自的类:

void someFunction(Base b)
{
    b.function();
    // b is a copy of what was passed - probably performance issues
    // possible unintended object slicing - you only get the Base part of it
    // no virtual function call
    // no changes to b visible outside the function
}

void someFunction(Base* b)
{
    b->function();
    // a shortcut for (*b).function();
    // b is the same object that was passed to the function
    // possible virtual call
    // changes visible outside the function
}

void someFunction(Base& b)
{
    b.function();
    // b is the same object that was passed to the function
    // possible virtual call
    // changes visible outside the function
}

引用就像常量指针(不是指向常量的指针 - 即您可以更改对象,但不能更改您所指向的内容)。 const 引用是一个引用,通过它你可以做 const 对象可以做的事情。

引用也很好,因为不能有空引用

References improve the syntax, so no pointer dereference needed.
Assuming Base is a class that may be derived from:

void someFunction(Base b)
{
    b.function();
    // b is a copy of what was passed - probably performance issues
    // possible unintended object slicing - you only get the Base part of it
    // no virtual function call
    // no changes to b visible outside the function
}

void someFunction(Base* b)
{
    b->function();
    // a shortcut for (*b).function();
    // b is the same object that was passed to the function
    // possible virtual call
    // changes visible outside the function
}

void someFunction(Base& b)
{
    b.function();
    // b is the same object that was passed to the function
    // possible virtual call
    // changes visible outside the function
}

References are like constant pointers (NOT pointers to constants - i.e. you can change the object, but you can't change to what you're pointing). const reference is a reference through which you can do things that can be done on const object.

References are also good, because you can't have a null reference

枯叶蝶 2024-09-21 08:35:47

我同意你的看法。仅使用引用作为别名并不是很有用。
如果您将其视为不可变指针,则会更有用。但实际上没那么有用。

实际上,它用于定义干净的接口。例如,当您定义:

int foo(const int& param);

您说 param 是 foo 中的只读参数。

不要忘记您必须为引用分配一个值。

的信息,请参阅 C++ faqlite

有关更多my2c

I agree with you. using references as just an alias name is not very useful.
It is more useful if you consider it as an immutable pointer. But not that useful in fact.

Practically, it is used to define clean interfaces. For example when you define:

int foo(const int& param);

You say that param is a read-only parameter in foo.

Do not forget that you MUST assign a value to a reference.

See the C++ faqlite on references for more

my2c

无所谓啦 2024-09-21 08:35:46

引用基本上是一个看起来像对象的指针。尽管您可以费尽心思创建一个 NULL 引用,但获得 NULL 引用是非常非常困难的。

对于您的示例,1 是右值或结果。它只是一个临时变量,无法修改。因此你不能对它进行非常量引用。但是您可以对其进行常量引用。这意味着您无法更改引用的值。

下面是创建 NULL 引用的示例。不要这样做!

int * x = (int *)NULL;
int & y = *x;

A reference is basically a pointer that looks like an object. It is very very hard to get a NULL reference though you can go through hoops and create one.

With regards to your example, 1 is an rvalue or a result. It is just a temporary variable and can not be modified. Thus you can't take a non const reference to it. However you can take a const reference to it. This means you can't change the value of the reference.

Here is an example of creating a NULL reference. Don't do it!

int * x = (int *)NULL;
int & y = *x;
本宫微胖 2024-09-21 08:35:45

引用是最初在 C 代码中的另一种方式,就像这样

void fubarSquare(int *x){
  int y = *x;
  *x = y * y;
}

// typical invocation
int z = 2;
fubarSquare(&z);
// now z is 4

,在 C++ 中的引用则像这样 这

void fubarSquareCpp(int& x){
   x = x * x;
}

// typical invocation
int z = 2;
fubarSquareCpp(z);
// now z is 4

是一种使用按引用调用参数而不是使用 C 星号表示法的更简洁的语法方式/star 表示指针并作为按引用调用参数...以及直接在函数外部修改参数...

看看 Bjarne Stoustrap 的此处页面介绍了 C++ 的原理以及技术常见问题解答< a href="http://www2.research.att.com/~bs/bs_faq2.html" rel="nofollow noreferrer">此处

References are another way of what was originally in C code like this

void fubarSquare(int *x){
  int y = *x;
  *x = y * y;
}

// typical invocation
int z = 2;
fubarSquare(&z);
// now z is 4

with references in C++ it would be like this

void fubarSquareCpp(int& x){
   x = x * x;
}

// typical invocation
int z = 2;
fubarSquareCpp(z);
// now z is 4

It's a neater syntactical way of using a call-by-reference parameter instead of using the C's notation asterisk/star to indicate a pointer and as a call-by-reference parameter...and modifying the parameter directly outside of the function...

Have a look at Bjarne Stoustrap's page here which covers how C++ is and also here on the technical faq here

有深☉意 2024-09-21 08:35:44

为什么使用它而不是直接使用它
作为任何操作访问对象
参考文献直接反映在
物体...?

C++ 按值传递参数,这意味着如果您有一个函数,例如:

void foo(MyObject o) { ... }

默认情况下,C++ 将复制 MyObject不会直接使用传入的对象。所以,引用的一种用途是确保您正在处理同一个对象:

void foo(MyObject &o) { ...}

或者,如果您不修改 o

void foo(const MyObject &o) { ... }

Why use that instead of directly
accessing the object as any operation
on references is directly reflected on
the object ...?

C++ passes parameters by value, meaning if you have a function such as:

void foo(MyObject o) { ... }

By default C++ will make a copy of a MyObject, not directly use the object being passed in. So, one use of references is to ensure you are working on the same object:

void foo(MyObject &o) { ...}

Or, if you aren't modifying o:

void foo(const MyObject &o) { ... }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文