指针变量和引用变量之间的区别是什么?
当前回答
指针(*)的基本含义是“地址处的值”,这意味着您提供的任何地址都将在该地址处给出值。一旦你改变了地址,它将给出新的值,而引用变量用于引用任何特定的变量,将来不能改变为引用任何其他变量。
其他回答
实际上,引用并不像指针。
编译器保持对变量的“引用”,将名称与内存地址相关联;这是编译时将任何变量名转换为内存地址的工作。
创建引用时,只告诉编译器为指针变量指定了另一个名称;这就是为什么引用不能“指向null”,因为变量不能是,也不能是。
指针是变量;它们包含其他变量的地址,或者可以为空。重要的是指针有一个值,而引用只有一个引用的变量。
现在对真实代码进行一些解释:
int a = 0;
int& b = a;
在这里,您没有创建另一个指向;您只需将另一个名称添加到内存内容中,该内存内容的值为a。该内存现在有两个名称,a和b,可以使用任一名称对其进行寻址。
void increment(int& n)
{
n = n + 1;
}
int a;
increment(a);
当调用函数时,编译器通常为要复制到的参数生成内存空间。函数签名定义了应该创建的空间,并给出了应该用于这些空间的名称。将参数声明为引用只是告诉编译器使用输入变量内存空间,而不是在方法调用期间分配新的内存空间。说你的函数将直接操作在调用作用域中声明的变量似乎很奇怪,但请记住,在执行编译代码时,没有更多的作用域;只有普通的平面内存,函数代码可以处理任何变量。
现在,在某些情况下,编译器在编译时可能无法知道引用,例如使用外部变量时。因此,在底层代码中,引用可以实现为指针,也可以不实现为指针。但在我给你的例子中,它很可能不会用指针实现。
如果你不熟悉以抽象的甚至学术的方式学习计算机语言,那么语义上的差异可能会显得深奥难懂。
在最高级别上,引用的概念是它们是透明的“别名”。你的计算机可能会使用一个地址来使它们工作,但你不必担心:你应该将它们视为现有对象的“另一个名称”,语法反映了这一点。它们比指针更严格,因此编译器可以在您将要创建悬挂引用时比在您将创建悬挂指针时更可靠地警告您。
除此之外,指针和引用之间当然还有一些实际差异。使用它们的语法明显不同,您不能“重新定位”引用、引用虚无或引用指针。
我觉得还有一点还没有在这里讨论。
与指针不同,引用在语法上等同于它们所引用的对象,即可以应用于对象的任何操作都适用于引用,并且具有完全相同的语法(当然,初始化是例外)。
虽然这可能看起来很肤浅,但我认为这一特性对于一些C++特性来说至关重要,例如:
模板。因为模板参数是鸭子类型的,所以类型的语法财产才是最重要的,所以通常同一个模板可以同时用于T和T&。(或std::reference_wrapper<T>,它仍然依赖于隐式转换至T&)覆盖T&和T&&的模板更为常见。L值。考虑语句str[0]=“X”;如果没有引用,它只适用于c字符串(char*str)。通过引用返回字符允许用户定义的类具有相同的符号。复制构造函数。从语法上讲,将对象传递给复制构造函数是有意义的,而不是传递给对象的指针。但复制构造函数无法按值获取对象,这将导致对同一复制构造函数的递归调用。这将引用作为此处的唯一选项。操作员过载。通过引用,可以在保留相同的中缀符号的同时,将间接指向引入运算符调用,例如运算符+(const T&a,const T&b)。这也适用于常规重载函数。
这些点赋予了C++和标准库相当大的一部分权力,因此这是参考文献的一个重要属性。
指针是保存另一个变量的内存地址的变量,其中引用是现有变量的别名。(已存在变量的另一个名称)
1.指针可以初始化为:
int b = 15;
int *q = &b;
OR
int *q;
q = &b;
其中作为参考,
int b=15;
int &c=b;
(在一个步骤中声明和初始化)
指针可以分配给null,但引用不能可以对指针执行各种算术运算,而没有所谓的参考算术。指针可以重新分配,但引用不能指针在堆栈上有自己的内存地址和大小,而引用共享相同的内存地址
除了语法糖,引用是常量指针(而不是指向常量的指针)。在声明引用变量时,必须确定它所指的内容,以后不能更改它。
更新:现在我再考虑一下,有一个重要的区别。
常量指针的目标可以通过获取其地址并使用常量转换来替换。
引用的目标不能以UB以外的任何方式替换。
这应该允许编译器对引用进行更多优化。