前言:本文主要讲解C++语法中引用如何使用和使用时的一些技巧
基本语法
引用就是取别名
#include <iostream>
using namespace std;
int main()
{
int a = 10;
int& b = a;//给a取别名为b
cout << a << endl;
cout << b << endl;
return 0;
}
b的数据类型是:int&
在内存中,引用与原变量是同一块空间
引用的特性
1.引用必须初始化
int& b;
2.一个变量可以有多个引用
int a = 10;
int& b = a;
int& c = a;
int& d = a;
3.引用一旦初始化后,就不能在引用其他实体。
int a = 10;
int c = 12;
int& b = a;
//这是赋值?还是引用?
b = c;
//上面是赋值
引用和指针的权限问题
权限放大
const int a = 10;//用const修饰a后,a的权限为只读,不能修改a的值
int& b = a;//如果用b引用a后b的权限可以读和写
b引用a后权限放大,会报错
double a = 1.2;
int& b = a;
这种情况也权限放大
int x = 0, y = 1;
int& a = x + y;
//const int& a = x + y;如果这样写不会有权限放大的问题
将x+y的结果需要有临时变量来存储,再赋值给a,所以出现了 权限的放大
权限缩小
int a = 10;
const int& b = a;
a的权限:可读可写
b的权限:只读
权限缩小,不会报错
权限平移
const int a = 10;
const int& b = a;
a的权限:只读
b的权限:只读
权限平移,不会报错
总结,权限放大会有语法错误,权限的缩小和平移没有语法错误。
指针中的权限问题
权限放大
int a = 10;
const int* p1 = &a;
int* p2 = p1;
const修饰p1指向的空间为只读,p2的权限为可读可写,权限出现了放大,会有语法错误。
权限缩小
int a = 10;
int* p1 = &a;
const int* p2 = p1;
权限平移
int a = 10;
const int* p1 = &a;
const int* p2 = p1;
引用作函数参数
C语言下实现两个值的交换的函数
void Swap(int* a, int* b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
int main()
{
int a = 10;
int b = 11;
Swap(&a, &b);
return 0;
}
这里需要传指针,才能交换,否则就交换不了
C++环境下直接将引用作为函数参数也可以实现这个效果
void Swap(int& a, int& b)
{
int tmp = a;
a = b;
b = tmp;
}
int main()
{
int a = 10;
int b = 11;
Swap(a, b);
return 0;
}
引用与指针的不同点
C++中的引用不能完全代替指针,比如链表的实现,指针一旦初始化后就不能在引用其他实体,而链表的插入和删除都需要改变链表的指向。
程序为指针变量分配内存区域,而不为引用分配内存区域。
指针使用时要在前加 * ,引用可以直接使用。
引用在定义时就被初始化,之后无法改变;指针可以发生改变。 即引用的对象不能改变,指针的对象可以改变。
没有空引用,但有空指针。这使得使用引用的代码效率比使用指针的更高。因为在使用引用之前不需要测试它的合法性。相反,指针则应该总是被测试,防止其为空。
对引用使用“sizeof”得到的是变量的大小,对指针使用“sizeof”得到的是变量的地址的大小。
理论上指针的级数没有限制,但引用只有一级。即不存在引用的引用,但可以有指针的指针。
int **p //合法
int &&p //非法
++引用与++指针的效果不一样。
例如就++操作而言,对引用的操作直接反应到所指向的对象,而不是改变指向;而对指针的操作,会使指针指向下一个对象,而不是改变所指对象的内容。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/xsydalao/article/details/93623647
内联函数
频繁调用小函数会开辟栈帧,有性能的消耗,那么如何解决这个问题呢?
在C语言中,有宏函数,预处理是会将调用该函数的地方将函数展开,不会开辟栈帧。
在C++中有内联函数
关键字 inline
inline int Add(int x, int y)
{
int z = x + y;
return z;
}
建议编译器在程序中调用该函数时将函数直接展开,就不需要创建函数栈帧,减少了性能的消耗,
这仅仅是一个建议,编译器可能不采用。
内联函数的缺点
如果函数的实现复杂,且在被频繁调用在代码中被展开,就会是代码行数增多很多,也会导致最后生成的可执行文件大。
内联函数的定义与声明
文献来源于:inline内联函数(声明前加inline还是定义前加inline)_inline void-CSDN博客
关键字inline 必须与函数定义体放在一起才能使函数成为内联,仅将inline 放在函数声明前面不起任何作用。
如下风格的函数Foo 不能成为内联函数:
inline void Foo(int x, int y); // inline 仅与函数声明放在一起
void Foo(int x, int y){}
而如下风格的函数Foo 则成为内联函数:
void Foo(int x, int y);
inline void Foo(int x, int y) // inline 与函数定义体放在一起{}
所以说,inline 是一种“用于实现的关键字”,而不是一种“用于声明的关键字”。一般地,用户可以阅读函数的声明,但是看不到函数的定义。尽管在大多数教科书中内联函数的声明、定义体前面都加了inline 关键字,但我认为inline 不应该出现在函数的声明中。这个细节虽然不会影响函数的功能,但是体现了高质量C++/C 程序设计风格的一个基本原则:声明与定义不可混为一谈,用户没有必要、也不应该知道函数是否需要内联。
结语:希望本文能够让各位看官有所收获。