一、对数组的引用
const int n = 10; int ar[n] = {12,23,34,45,56,67,78,89,100}; 描述数组:类型加上原始空间大小。 int &ra = ar[1]; int &br = ar;//error int (&br)[n] = ar;//okint *pa[10]; int &pr[10];//error;为什么不能编译成功
-
引用数组的概念:在 C++ 中,引用是一个别名,它必须被初始化以指向一个已经存在的对象。引用本身不是一个对象,它不能“存储”值,而是直接引用另一个对象的值。因此,引用类型不能用作数组的元素类型,因为数组的元素需要在数组创建时被默认初始化(如果它们没有显式初始化),而引用类型不能被默认初始化。
-
初始化问题:当声明一个数组时,数组的每个元素都需要被初始化(除非它们被显式地标记为未初始化,例如在某些类型的动态分配中)。然而,对于引用类型的数组,每个元素都需要一个已存在的对象来引用,这在数组声明时通常是不可能的,因为编译器不知道要引用哪些具体的对象。
-
编译器的限制:由于上述原因,C++ 标准不允许创建引用类型的数组。编译器在遇到这样的声明时会报错,因为它违反了引用的基本规则和数组的内存管理需求。
二、对指针的引用
int a = 10, b = 20; int *p = &a; //p是a指针,保存a的地址 int *s = p; //s是p的指针,保存p的地址 int *&rp = p;//rp是指针的引用,即是p的别名 *rp = 100;//通过解引用修改的是a的值 rp = &b;将p保存的地址修改为b的地址
三、例题,将指针,引用,const融合起来,分析
int main() { int a = 10, b = 20; int* const p = &a; int* s1 = p; const int *s2 = p; int* const s3 = p; const int* const s4= p; }
这是之前做过的一个例题,但是分析结果是所有都能编译通过,因为所有表达式都没有去试图修改p自身的值
如果改型为下述,分析结果
int main() { int a = 10, b = 20; int* const p = &a; int* &s1 = p; const int *&s2 = p; int* const &s3 = p; const int* const &s4= p; }
我们定义了一个常性指针,即p自身的值不能修改,所有试图能够修改p自身值的定义都不能被编译通过,接下来逐个分析:
①定义s1是p指针的引用,即s1是p的别名,如果修改s1自身,就会试图修改p的值,所以不能编译通过;
②定义s2是一个指向常量的指针的引用,仍然是p的别名,但是这个别名指向的位置是常性的,这意味着通过 s2,不能修改 p
指向的值,但可以让 s2指向另一个地址,即可以通过s2修改p的值,所以不能编译;
③定义s3作为一个常性指针的引用,即不可以通过s3改变p的值,但可以改变p指向的值,合法;
④s4是一个常性的指向常量的指针的引用,既不能修改 s4 指向的地址,也不能修改 s4指向的值。
四、总结
- 指针与引用的区别:
- 指针是一个变量,存储了另一个变量的内存地址。指针可以被重新赋值以指向其他对象,也可以进行算术运算。
- 引用是一个别名,它必须被初始化以指向一个已经存在的对象,并且在初始化后不能改变其指向。引用更直观,更安全。
- 引用数组的概念与限制:
- 在C++中,不允许创建引用类型的数组,因为数组的每个元素需要在创建时被初始化,而引用类型不能被默认初始化。
- 每个引用元素都需要引用一个已经存在的对象,这在数组声明时通常是不可能的。
- 指针的引用:
- 引用指针(即指针的引用)是合法的,并且可以用于改变指针所指向的地址。
- 例如,
int *&rp = p;
使得rp
成为p
的别名,通过rp
可以修改p
所指向的地址。
- const与指针、引用的结合:
const int* p;
:p
是一个指向常量的指针,可以通过p
读取所指向的值,但不能通过p
修改所指向的值。int* const p = &a;
:p
是一个常性指针,指向int
类型变量a
,p
本身的值(即它所存储的地址)不能被修改,但可以通过p
修改所指向的int
值。- 当
const
与指针的引用结合时,需要特别注意指针本身的常性(即指针的值是否能被修改)以及指针所指向对象的常性(即所指向的值是否能被修改)。
- 常见误区分析:
- 试图让非常性指针的引用指向常性指针是错误的,因为这会允许通过引用(一个非常性指针的引用)来“修改”(即重新赋值)常性指针所指向的地址。
- 指向常量的指针的引用(即使该引用本身不是常性的)也不能用于改变常性指针所指向的地址,因为常性指针的值本身是不能被修改的。这里的错误在于混淆了指针的常性和所指向对象的常性。
- 常性指针的引用是合法的,它允许通过引用(实际上是常性指针的别名)来访问或修改常性指针所指向的值,但不能改变常性指针所指向的地址。
- 指向常量的常性指针的引用是最严格的,既不能改变所指向的地址,也不能修改所指向的值。