第2节 C++ 中的引用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/pt_raspi_fresher/article/details/88201031

-------------------------------------资源来源于网络,仅供自学使用,如有侵权,联系我必删.

第一:

 C++ 中的布尔类型
     C++ 在C C 语言的基本类型系统之上增加了 bool
     C++ 中的 bool 可取的值只有 true 和 false
     理论上 bool 只占用一个字节,
       •  如果多个 bool 变量定义在一起,可能会各占一个 bit ,这取决于编译器的实现

Tip:
true 代表真值,编译器内部用 1  来表示
false 代表非真值,编译器内部用 0  来表示

下面的代码输出什么?

#include <stdio.h>

int main(int argc, char *argv[])
{
    int a;
    bool b = true;  //bool是关键字
    
    printf("b = %d, sizeof(b) = %d\n", b, sizeof(b));//ture为1   大小1字节
    //bool类型赋值时,非0赋值1;为0赋值0
    b = 3;
    a = b;
    
    printf("a = %d, b = %d\n", a, b);//  1   1
    
    b = -5;
    a = b;
    
    printf("a = %d, b = %d\n", a, b);//  1   1
    
    a = 10;
    b = a;
    
    printf("a = %d, b = %d\n", a, b);// 10  1
    
    b = 0;
    
    printf("b = %d\n", b); //0
    
    printf("Press enter to continue ...");
    getchar();	
    return 0;
}

第二:

 bool 类型只有 true (非0)和 false (0 )两个值
  C++ 编译器会在赋值时将非0 值转换为 true , 0 值转换为false

#include <stdio.h>

int main(int argc, char *argv[])
{
    bool b = false;
    
    printf("b = %d\n", b);
    
    b++;//赋值等于1
    
    printf("b = %d\n", b);
    
    b = b + 1;//赋值大于1则为1
    
    printf("b = %d\n", b);
    
    printf("Press enter to continue ...");
    getchar();	
    return 0;
}

第三:

 三目运算符的升级

下面的代码正确吗?如果正确输出什么?

#include <stdio.h>

int main(int argc, char *argv[])
{
    int a = 1;
    int b = 2;
    
    //在C里面这里三目运算符不能作为左值,会报错
    //在C++里面,三目运算符里面全部为变量则可以使用
    (a < b ? a : b) = 3;
    
    printf("a = %d, b = %d\n", a, b);
    
    printf("Press enter to continue ...");
    getchar();	
    return 0;
}

  C  语言中的三目运算符返回的是变量值不能作为左值使用
  C++ 中的三目运算符可直接返回变量本身,因此可以出现在程序的任何地方
  注意:
     三目运算符可能返回的值中如果有一个是常量值,则不能作为左值使用

第四:

 变量名回顾
•  变量是一段实际连续存储空间的别名
•  程序中通过变量来申请并命名存储空间
•  通过变量的名字可以使用存储空间

  在 C++ 中新增加了引用的概念
  引用可以看作一个已定义变量的别名
  引用的语法: Type& name =   var; 

#include <stdio.h>

int main(int argc, char *argv[])
{
    int a = 4;
    int& b = a;//引用声明,此时用另外的变量b进行初始化
    //int& b = 5;   //这里用常量进行初始化,是错误的,编译不过!!!!
    
    b = 5;
    
    printf("a = %d\n", a);
    printf("b = %d\n", b);
    printf("&a = %08X\n", &a);
    printf("&b = %08X\n", &b);
    
    printf("Press enter to continue ...");
    getchar();	
    return 0;
}

Tip:
普通引用在声明时必须用其它的变量进行初始化。

第五:

  引用的意义
  引用作为其它变量的别名而存在,因此在一些场合可以代替指针
  引用相对于指针来说具有更好的可读性和实用性
swap函数的实现对比:

#include <stdio.h>

void swap(int& a, int& b)
{
    int t = a;
    a = b;
    b = t;
}

int main(int argc, char *argv[])
{
    int a = 4;
    int b = 5;
    
    swap(a, b);
    
    printf("a = %d\n", a);
    printf("b = %d\n", b);
    
    printf("Press enter to continue ...");
    getchar();	
    return 0;
}

Tip:
引用作为函数参数声明时不进行初始化

第六:

  const 引用

  在 C++ 中可以声明 const 引用
  const Type& name =  var ;
  const引用让变量拥有只读属性

#include <stdio.h>

int main(int argc, char *argv[])
{
    int a = 4;
    const int& b = a;
    int* p = (int*)&b;
    
    //b = 5;//b为只读变量不能作为左值使用
    
    *p = 5;
    
    printf("a = %d\n", a);
    printf("b = %d\n", b);
    
    printf("Press enter to continue ...");
    getchar();	
    return 0;
}

第七:

  当使用常量对 const 引用进行初始化时, C++ 编译器会为常量值分配空间,并将引用名作为这段空间的别名

#include <stdio.h>

int main(int argc, char *argv[])
{
    const int& b = 1;//b常引用,只读变量
    int* p = (int*)&b;//只读变量b
    
    //b = 5;
    
    *p = 5;
    
    printf("b = %d\n", b);
    
    printf("Press enter to continue ...");
    getchar();	
    return 0;
}

Tip:
使用常量对 const引用初始化后将生成一个只读变量

第八:

引用有自己的存储空间吗?

#include <stdio.h>

struct TRef
{
    int& a;//int* const a
    int& b;//int* const b
};

int main(int argc, char *argv[])
{
    printf("sizeof(TRef) = %d\n", sizeof(TRef));//32位机是4个字节(8)   64位机是8个字节(16)
    
    printf("Press enter to continue ...");
    getchar();	
    return 0;
}

  引用在 C++ 中的内部实现是一个常指针
       Type& name <- -> Type*   const name

Improtance :
 C++ 编译器在编译过程中使用常指针作为引用的内部实现,因此引用所占用的空间大小指针相同
 从使用的角度,引用会让人误会其只是一个别名,没有自己的存储空间。这是 C++为了实用性而做出的细节隐藏

#include <stdio.h>

struct TRef
{
    int& a;
    int& b;
    int& c;
};

int main(int argc, char *argv[])
{
    //rA 和  abc 在内存上没有交集,独立存在,有自己的内存空间
    int a = 1;
    int b = 2;
    int c = 3;
    TRef rA = {a, b, c};
    
    printf("&a = %08X\n", &a);
    printf("&b = %08X\n", &b);
    printf("&c = %08X\n", &c);
    printf("&rA = %08X\n", &rA);
    printf("sizeof(TRef) = %d\n", sizeof(rA));
    
    printf("Press enter to continue ...");
    getchar();	
    return 0;
}

第九:

 当函数返回值引用
      若返回栈变量
         •  不能成为其它引用的初始值
         •  不能作为左值使用
     若返回静态变量全局变量
        •  可以成为其他引用的初始值
        •  即可作为右值使用,也可作为左值使用

引用返回值示例

#include <stdio.h>

int& f()
{
    static int a = 0;
    
    return a;//返回值为静态局部变量
}

int& g()
{
    int a = 0;
    
    return a;//返回值为局部变量
}

int main()
{
    int a = g();
    int& b = g();//返回随机值
    
    f() = 10;//静态局部变量赋值
    
    printf("a = %d\n", a);
    printf("b = %d\n", b);
    printf("f() = %d\n", f());
    
    printf("Press enter to continue ...");
    getchar();	
    return 0;
}

第十:

 C++ 对三目运算符做了什么?
  当三目运算符的可能返回都是变量时,返回的是变量引用
 当三目运算符的可能返回中有常量时,返回的是值

小结

  bool 类型是 C++ 新增加的基础类型,其值只能是 true 和 false
  C++ 中的引用可以看作变量的别名来使用
  C++ 中的常引用可以使得一个变量拥有只读属性
  C++ 中的常引用可以用常量初始化而得到一个只读变量
  C++ 中引用的本质是一个指针常量

猜你喜欢

转载自blog.csdn.net/pt_raspi_fresher/article/details/88201031