欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C++ 基础 引用

程序员文章站 2022-06-27 14:17:31
1.引用的本质 int b = 10; int &a = b; 等效于: int * const a = &b; 由于 a 是 const声明,所以一旦定义无法修改,所以要在定义时就要赋初值。 实际使用时: a = 10; ==> *b = 10; 2. 引用于函数结合 (1)引用做函数参数 int ......

1.引用的本质

  int b = 10;

  int &a = b;

  等效于:

  int * const a = &b;

  由于 a 是 const声明,所以一旦定义无法修改,所以要在定义时就要赋初值。

  实际使用时:

  a = 10;   ==> *b = 10;

 

2. 引用于函数结合

(1)引用做函数参数

int func(int &a)

{

   ...

}

使用时:

int b = 10; 

func(b);

为了分析语法,将其转换为指针,编译器在实参给形参赋值时:

int &a = b;   ===>   int *const a = &b;

实际使用:

a = 10; ===> *b = 10;

所以实现了间接赋值。

 

(2)引用做函数返回值

int &func()
{
   int ret = 10;
   return ret;
}

int main()
{
int a = func(); // gcc 中,这里出现段错误
int &b = func();
cout << a << endl;
cout << b << endl; // gcc 中,这里段错误
}

  在 vs 中,debug版本和 release版本的输出不同。

  所以上面的代码是错误的。

  分析原因:

  int a = func();  ==>  

          int &tmp = ret;  === >  int *const tmp = &ret;

          a = tmp;       ===>  a = *(&ret);

  其中 tmp 是 隐藏变量,一般在寄存器中。

  由于 函数返回后,局部变量 ret 空间释放,所以对无效空间的访问是未知的。

 int &b = func(); ==>

         int &tmp = ret;   ===> int *const tmp = &ret;

         int &b = tmp;     ===> int *const b = tmp;  ==>  int *const b = &ret;

 可以看出这里不存在非法地址访问,所以这句不会报错。

  cout << b << endl; ===> cout << *(&ret) << endl; 

  这里是非法地址访问。报错

  由于上面的非法地址访问的本质原因是栈空间的释放,所以如果变量的存储类在堆或数据段就不会有错。

 

3. 引用与指针

(1)引用指针

  int &b = c;

  int & * a = &b;

  上面的表达式是错误的,因为 指针不能指向引用,原因是 c++之父 不希望 引用和指针一样出现多级引用,同理也没有 引用的引用。

(2)指针引用

 int *b = &c;

int * & a = b;

  这是成立的,相当于:

int * * const a = &b;

 

4. 引用与 const 

(1)使用变量初始化常引用

int a = 10;

const int &b = a;

a = 11;  

b = 12;  // 错误

通过常引用赋予变量只读属性。

(2)使用字面量初始化常引用

int &a = 10;    // 错误,因为字面量没有地址,无法引用

const int &b = 10;  

常引用可以引用字面量,当常引用引用字面量时,c++编译器为字面量分配空间,并让常引用符号作为该空间的别名。