指针变量和引用变量之间的区别是什么?
当前回答
这是基于教程。所写内容更清楚:
>>> The address that locates a variable within memory is
what we call a reference to that variable. (5th paragraph at page 63)
>>> The variable that stores the reference to another
variable is what we call a pointer. (3rd paragraph at page 64)
简单地记住,
>>> reference stands for memory location
>>> pointer is a reference container (Maybe because we will use it for
several times, it is better to remember that reference.)
此外,我们可以参考几乎任何指针教程,指针是指针算术支持的对象,它使指针类似于数组。
看看下面的陈述,
int Tom(0);
int & alias_Tom = Tom;
alias_Tom可以理解为变量的别名(与typedef不同,typedef是一种类型的别名)Tom。忘记这种说法的术语也是可以的,即创建一个对汤姆的引用。
其他回答
此外,作为内联函数的参数的引用的处理方式可能与指针不同。
void increment(int *ptrint) { (*ptrint)++; }
void increment(int &refint) { refint++; }
void incptrtest()
{
int testptr=0;
increment(&testptr);
}
void increftest()
{
int testref=0;
increment(testref);
}
许多编译器在内联指针版本1时实际上会强制写入内存(我们显式地获取地址)。然而,他们会将引用保留在更优化的寄存器中。
当然,对于未内联的函数,指针和引用生成相同的代码,如果函数未修改和返回内部函数,则通过值传递内部函数总是比通过引用传递内部函数更好。
虽然引用和指针都用于间接访问另一个值,但引用和指针之间有两个重要的区别。第一个是引用总是引用一个对象:在没有初始化引用的情况下定义引用是错误的。赋值行为是第二个重要区别:赋值给引用会更改引用绑定的对象;它不会将引用重新绑定到另一个对象。初始化后,引用始终引用同一基础对象。
考虑这两个程序片段。首先,我们将一个指针分配给另一个指针:
int ival = 1024, ival2 = 2048;
int *pi = &ival, *pi2 = &ival2;
pi = pi2; // pi now points to ival2
在赋值ival之后,pi所寻址的对象保持不变。赋值会更改pi的值,使其指向不同的对象。现在考虑一个分配两个引用的类似程序:
int &ri = ival, &ri2 = ival2;
ri = ri2; // assigns ival2 to ival
此赋值更改了ri引用的值ival,而不是引用本身。赋值后,两个引用仍然引用其原始对象,并且这些对象的值现在也相同。
除了这里的所有答案,
可以使用引用实现运算符重载:
my_point operator+(const my_point& a, const my_point& b)
{
return { a.x + b.x, a.y + b.y };
}
使用参数作为值将创建原始参数的临时副本,而使用指针将不会调用此函数,因为指针算法。
实际上,引用并不像指针。
编译器保持对变量的“引用”,将名称与内存地址相关联;这是编译时将任何变量名转换为内存地址的工作。
创建引用时,只告诉编译器为指针变量指定了另一个名称;这就是为什么引用不能“指向null”,因为变量不能是,也不能是。
指针是变量;它们包含其他变量的地址,或者可以为空。重要的是指针有一个值,而引用只有一个引用的变量。
现在对真实代码进行一些解释:
int a = 0;
int& b = a;
在这里,您没有创建另一个指向;您只需将另一个名称添加到内存内容中,该内存内容的值为a。该内存现在有两个名称,a和b,可以使用任一名称对其进行寻址。
void increment(int& n)
{
n = n + 1;
}
int a;
increment(a);
当调用函数时,编译器通常为要复制到的参数生成内存空间。函数签名定义了应该创建的空间,并给出了应该用于这些空间的名称。将参数声明为引用只是告诉编译器使用输入变量内存空间,而不是在方法调用期间分配新的内存空间。说你的函数将直接操作在调用作用域中声明的变量似乎很奇怪,但请记住,在执行编译代码时,没有更多的作用域;只有普通的平面内存,函数代码可以处理任何变量。
现在,在某些情况下,编译器在编译时可能无法知道引用,例如使用外部变量时。因此,在底层代码中,引用可以实现为指针,也可以不实现为指针。但在我给你的例子中,它很可能不会用指针实现。
引用不是给某些内存的另一个名称。它是一个不可变的指针,在使用时会自动取消引用。基本上归结为:
int& j = i;
它内部变成
int* const j = &i;