- C++中的bool类型
*C++在C语言的基本类型上增加了bool
*C++中的bool可取的值只有true和false
*理论上bool只占用一个字节
·如果多个bool变量定义在一起,可能会各占一个bit,这取决于编译器的实现(在一个字节中各占一个 bit)
注意:
true代表真值,编译器内部用1表示
false代表非真值,编译器内部用0来表示 - bool类型只有true(非0)和false(0)两个值
*C++编译器会在赋值时将非0值转换为true,0值转换为false
- C语言中的三目运算符返回的是变量值,不能作为左值使用
- C++中的三目运算符可直接返回变量本身,因此可以在程序任何地方出现
注意:三目运算符可能返回的值中如果有一个是常量值,则不能作为左值使用
变量名的回顾
*变量是一段实际连续存储空间的别名
*程序中通过变量来申请并命名存储空间
*通过变量的名字可以使用存储空间
思考:对于一段存储空间只能有一个变量名吗?
答:可以有多个变量名在C++中新增加了引用的概念
*引用可以看作一个已定义变量的别名
*引用的语法:
Type& name = var;
int main()
{
int a = 4;
int& b = a; // 为变量a取一个别名b
b = 5;
printf("%d\n",a);
printf("%d\n",b); //发现打印出a与b的值是相同的
printf("%d\n",&a);
printf("%d\n",&b); //发现打印出a与b的地址相同
return 0;
}
注意:普通引用在声明时,必须用其他的变量进行初始化(不能用常量进行初始化)
- 引用的意义
*引用作为其他变量的别名而存在,因此在一些场合可以代替指针
*引用相对于指针来说具有更好的可读性和实用性
swap函数的实现对比:
①
void swap(int& a,int& b)
{
int t = a;
a = b;
b = t;
}
swap(a,b);
②
void swap(int* pa,int* pb)
{
int t = *pa;
*pa = *pb;
*pb = t;
}
swap(&a,&b);
注意:引用作为函数参数声明时不用进行初始化
理解:对①开始存在疑惑,觉得swap(a,b);复制了a,b的值到函数中,而没有改变真正的a,b的值,此理解有误。对①来说swap(a,b);发送了a与b的变量名到函数中为函数中的参数取名,则void swap(int& ,int& b)中的a,b是参数。这个函数是能够操作a,b的存储空间内的值来改变a,b的值的
补充③
void swap(int a,int b)
{
int t = a;
a = b;
b = t;
}
swap(a,b);
这个不能实现a,b值的交换,原因在上述“理解”中已写明
- const引用
*在C++中可以声明const引用
*const Type& name = var;
*const引用让变量拥有只读属性
int main()
{
int a = 4;
const int& b = a;
int* p = (int *)&b;
//b = 5; //如果这一行开启,发现编译不通过,因为const引用让变量拥有只读属性
//*p = 5; //如果这一行开启,发现a,b的值为5
//可以发现const引用只是让变量拥有只读属性而不是将变量放入常量表,因此只具有让变量不能成为左值的功能
printf("%d\n",a);
printf("%d\n",b);
return 0;
}
理解:在C++中,对比const常量和const引用。C++中,const引用的功能好像是是把这个变量故意变成C语言中的功能(C语言中const变量只具有不能成为左值的功能,但是还是可以通过指针解引用的方式改变这个变量的值)。C++中const常量是真的把一个变量变成一个不可改变的(在C++与C的关系里有详细说明)
- 当使用常量对const引用进行初始化时,C++编译器会为常量值分配空间,并将引用名作为这段空间的别名
int main()
{
const int&b = 1;
int* p = (int *)&b;
// b = 5;
*p = 5;
printf("%d\n",b);
return 0;
}
注意:使用常量对const引用初始化后将生成一个只读变量
提出一个问题:
引用有自己的存储空间吗?
struct TRef
{
int& a;
int& b;
};
int main()
{
printf("sizeof(TRef) = %d\n",sizeof(TRef)); //打印出8个字节的存储空间
return 0;
}
- 引用在C++中的内部实现时一个常指针
Type& name ↔Type* const name
注意:
C++编译器在编译过程中使用常指针作为引用的内部实现,因此引用所占用的空间大小与指针相同。
从使用的角度,引用会让人误会其只是一个别名,没有自己的存储空间。这是C++为了实用性而做出的细节隐藏。
void f(int& a) void f(int * const a)
{ {
a = 5; ↔ *a = 5;
} }
- 当函数返回值为引用时
*若返回栈变量
· 不能称为其他引用的初始值
· 不能作为左值使用
(理解:在函数结束的时候,这一块内存被释放,所以不能使用)
*若返回静态变量或全局变量
· 可以成为其他引用的初始值
· 既可作为右值使用,也可作为左值使用
(理解:同上做对比,这一块内存未被释放,所以可以使用)
- C++对三目运算符做了什么?
*当三目运算符的可能返回值都是变量时,返回的是变量引用
*当三目运算符的可能返回值中有常量时,返回的是值
int a = 1;
int b = 2;
(a<b?a:b) = 3;//正确,返回的是a或b的引用,可以作为右值使用
(a<b?1:b) = 3;//错误,可能返回中有常量,返回的是值,不能作为右值使用
小结
- bool类型是C++新增加的基础类型,其值只能是true和false
- C++中的引用可以看作变量的别名来使用
- C++中的常引用可以使得一个变量拥有只读属性(理解:const引用把const常量的功能退回到C语言的时候)
- C++中的常引用可以用常量初始化而得到一个只读变量
- C++引用的本质是一个指针常量
课后习题:
待完成