首页 / C++ / C++深度解析(3)—布尔类型和引用
C++深度解析(3)—布尔类型和引用
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了C++深度解析(3)—布尔类型和引用,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含5972字,纯文字阅读大概需要9分钟。
内容图文
![C++深度解析(3)—布尔类型和引用](/upload/InfoBanner/zyjiaocheng/756/6e67f399fb0e42fd87cf54b4e2f072ee.jpg)
1.布尔类型
1.1 布尔类型
- C++中的布尔类型
- C++在C语言的基本类型系统之上增加了bool
- C++中的bool可取的值只有true和false
- 理论上bool只占用一个字节
- true代表真值,编译器内部用1来表示
- false代表非真值,编译器内部用0来表示
1.2 布尔类型的值
- bool类型只有true(非0)和false(0)两个值
- C++编译器会将非0值转换为true,0值转换为false
#include <stdio.h>
int main(int argc, char *argv[])
{
int a;
bool b = true;
printf("b = %d, sizeof(b) = %d\n", b, sizeof(b));
b = 3;
a = b;
printf("a = %d, b = %d\n", a, b);
b = -5;
a = b;
printf("a = %d, b = %d\n", a, b);
a = 10;
b = a;
printf("a = %d, b = %d\n", a, b);
b = 0;
printf("b = %d\n", b);
printf("Press enter to continue ...");
getchar();
return 0;
}
- 运行结果
1.3 布尔类型
- 布尔类型是C++中的基本数据类型
- 可以定义bool类型的全局变量
- 可以定义bool类型的常量
- 可以定义bool类型的指针
- 可以定义bool类型的数组
2.三目运算符
- C++对三目运算符进行了升级
- 下面的代码正确吗?
int?a?=?1;??
int?b?=?2;??
??
(a < b ? a : b)?=?3;??
??
printf("a?=?%d,b?=?%d\n",?a,?b);??
- gcc编译不通过,g++编译通过
- 当改为:(a < b ? a : 2)= 3时,g++也编译不通过
- 总结:
- C语言中的三目运算符返回的是变量值
- 不能作为左值使用
- C++中的三目运算符可直接返回变量本身
- 既可作为右值使用,又可作为左值使用
- 注意:
- 三目运算符可能返回的值中如果有一个是常量值,则不能作为左值使用。
3.C++中的引用
3.1 变量名回顾
- 变量是一段实际连续存储空间的别名
- 程序中通过变量来申请并命名存储空间
- 通过变量的名字可以使用存储空间
3.2 C++中的引用
- 引用可以看作一个已定义变量的别名
- 引用的语法:Type& name = var;
#include <stdio.h>
int main(int argc, char *argv[])
{
int a = 4; // a是4个字节连续存储空间的别名
int &b = a; // b是a的别名,指向a
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;
}
- 运行结果
- 注意:普通引用在定义时必须用同类型的变量进行初始化。
3.3 引用和指针对比(引用类型作形参)
- 传递引用给函数与传递指针的效果是一样的,形参变化实参也发生变化。
- 引用类型作形参,在内存中并没有产生实参的副本,它直接对实参操作;而一般变量作参数,形参与实参就占用不同的存储单元,所以形参变量的值是实参变量的副本。因此,当参数传递的数据量较大时,用引用比用一般变量传递参数的时间和空间效率都好。
- 指针参数虽然也能达到与使用引用的效果,但在被调函数中需要重复使用“*指针变量名”的形式进行运算,这很容易产生错误且程序的阅读性较差;另一方面,在主调函数的调用点处,必须用变量的地址作为实参。
// 引用
#include <iostream>
using namespace std;
void swap(float &m, float &n)
{
float temp;
temp = m;
m = n;
n = temp;
}
void main()
{
float a, b;
cin >> a >> b;
swap(a, b);
cout << a << endl << b << endl;
}
// 指针
#include <iostream>
using namespace std;
void swap(float *m, float *n)
{
float *temp;
temp = m;
m = n;
n = temp;
}
void main()
{
float a, b, *p1, *p2;
cin >> a >> b;
p1 = &a;
p2 = &b;
swap(p1, p2);
cout << a << endl << b << endl;
}
3.4 const引用
- 在C++中可以声明const引用
- const Type& name = var ;
- const引用让变量拥有只读属性
void swap(int* a, int* b)
{
int a= 4;
const int &b = a;
int *p = (int *)&b;
b = 5; // Error , 只读变滥
*p = 5; // Ok, 修改变量a的值
}
- 可以a=5;因为const只是告诉编译器, b不能出现在赋值符号左边
#include <stdio.h>
int main()
{
const int i = 0;
const int &a = i;????//直接用i的空间
printf("%p", &i);
printf("%p", &a);
return 0;
}
- 当使用常量对const引用进行初始化时,C++编译器会为常量值分配空间,并将引用名作为这段空间的别名
- 运行结果:
3.5 思考
- 引用有自己的存储空间吗?
#include <stdio.h>
struct TRef
{
int &a;
int &b; // 引用在C++中的内部实现是一个常指针,有自己的存储空间
//int *const a;
//int *const b;
};
int main(int argc, char *argv[])
{
printf("sizeof(TRef) = %d\n", sizeof(TRef));
printf("Press enter to continue ...");
getchar();
return 0;
}
- 运行结果
- 引用在C++中的内部实现是一个常指针,有自己的存储空间
3.6 引用的本质
- 引用在C++中的内部实现是一个指针常量
- 注意:
- C++编译器在编译过程中用指针常量作为引用的内部实现,
- 因此引用所占用的空间大小与指针相同。
- 从使用的角度,引用只是一个别名,C++为了实用性而隐藏了引用的存储空间这—细节。
#include <stdio.h>
struct TRef
{
int &a ;
int &b;
int &c;
};
int main(int argc, char *argv[])
{
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;
}
- 运行结果
- 栈的生长方向自上向下的
4 小结
- 引用作为变量别名而存在旨在代替指针
- const引用可以使得变量具有只读属性
- 引用在编译器内部使用指针常量实现
- 引用的最终本质为指针
- 引用可以尽可能的避开内存错误
5.疑难解答
- 引用与指针有什么关系? 如何理解"引用的本质就是指针常量" ?
- 指针是—个变量
- 值为—个内存地址,不需要初始化,可以保存不同的地址 ;
- 通过指针可以访问对应内存地址中的值;
- 指针可以被const修饰成为常量或者只读变量 ;
- 引用只是—个变量的新名字
- 对引用的操作(赎值,取地址等)都会传递到代表的变量上
- const引用使其代表的变量具有只读属性
- 引用必须在定义时初始化,之后无法代表其它变量
- 从使用C++语言的角度来看
- 引用与指针没有任何的关系
- 引用是变量的新名字,操作引用就是操作对应的变量
- 从C++编译器的角度来看
- 为了支持新概念“引用”必须要—个有效的解决方案
- 在编译器内部,使用指针常量来实现“引用”
- 因此“引用”在定义时必须初始化
- 在工程项目开发中
- 当进行C++编程时,直接站在使用的角度看待引用,与指针毫无关系,引用就是变量的别名
- 当对C++代码进行调试分析时,—些特殊情况,可以考虑站在 C++编译器的角度看待引用
- 下面的代码有问题吗?
int a= 1;
int b = 2;
int *pc= new int(3);
int &array[] = {a, b, *pc};
- 实例分析
#include <stdio.h>
int a = 1;
struct SV
{
int &x;
int &y;
int &z;
};
int main()
{
int b = 2;
int *pc = new int(3);
SV sv = {a, b, *pc};
// int& array[] = {a, b, *pc}; // &array[1] - &array[0] = ? Expected ==> 4
printf("&sv.x = %p\n", &sv.x);
printf("&sv.y = %p\n", &sv.y);
printf("&sv.z = %p\n", &sv.z);
delete pc;
return 0;
}
- 运行结果
- 去掉注释:1>e:\cp_projects\c++面向对象编程\demo_1\c++中的引用\main.cpp(17): error C2234: “array”: 引用数组是非法的
- 所以C++不支持引用数组
内容总结
以上是互联网集市为您收集整理的C++深度解析(3)—布尔类型和引用全部内容,希望文章能够帮你解决C++深度解析(3)—布尔类型和引用所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。