网站运营与规划,阳江房产网资讯,域名的注册方式,互联网营销案例分析目录 引用的概念和定义引用的特性引用的使用const引用指针和引用的关系引用的实际作用inlinenullptr 引用的概念和定义
在语法上引用是给一个变量取别名#xff0c;和这个变量共用同一块空间#xff0c;并不会给引用开一块空间。
取别名就是一块空间有多个名字
类型 … 目录 引用的概念和定义引用的特性引用的使用const引用指针和引用的关系引用的实际作用inlinenullptr 引用的概念和定义
在语法上引用是给一个变量取别名和这个变量共用同一块空间并不会给引用开一块空间。
取别名就是一块空间有多个名字
类型 引用别名 引用对象
int main()
{int a 2;int b a;int c a;int d b;//对d取别名d是b的别名b是a的别名d就是a的别名b;cout a endl;cout b endl;cout c endl;cout d endl;// 都是3//这就说明了b、c、d都是a的别名和a共用同一块空间return 0;
}
引用的特性
1.引用在定义时必须初始化必须说明是谁的引用 不说明是谁的引用会报错 2.一个变量可以有多个引用给别名取别名 3.引用一旦引用一个实体再不能引用其他实体 引用不能改变指向 1,2点比较简单现在对第三点说明一下
链表要改变指向要用二级指针
int main()
{int a 2;int b a;int d 20;b d;//这里是赋值不是引用b不是d的引用d;//对da和b并不改变也说明了b不是d的引用//b本来是a的引用并不能改变成b是d的引用说明引用不能改变指向//后面也会介绍return 0;
}引用的使用
1.引用做传参和做返回值
提高效率减少拷贝引用对象改变同时被引用对象改变
比如传值调用传一个值x,函数中a拿到的是x的一份临时拷贝而如果用引用就减少了拷贝提高了效率因为a是x的别名就是给本身取了另一个名字
引用对象改变同时被引用对象改变 x,a也你的别名改变了你本身也会改变
void f1(int x)
{x;
}int main()
{int a 0;f1(a);return 0;
}引用做返回值 1.int 做返回时返回一个数值不是直接返回而是会生成一份临时变量再返回临时变量具有常性不能被改变
2.int 做返回时生成一个它的引用再返回它的引用数组在堆上出函数不销毁返回数组中的引用出函数改变数组中的某个值
const引用
注意权限放大和缩小只存在指针和引用里面 权限不能放大可以缩小
1.权限放大
const int a 10;//只读不能写修改
int ra a;//可以读可以写权限放大
//正确写法
const int ra a;const int a 10;//可读不可写
int ra a;
//权限放大
const int ra a;const int a 10;
int rd a;
//a只读a的值拷贝进rd中a一个空间rd又是一个空间
//rd可读可写,这只是一个拷贝不是权限放大
//权限放大只存在指针和引用中2.权限缩小
int b 20;
const int rb b;b;//21本身权限不缩小
rb;//不能够改变只是它的引用权限缩小了3. 产生临时对象 临时对象具有常性 表达式运算
int a 10;
const int rc 30;
const int rd (a30);函数传值返回
int fun(int a)
{a;return a;
}类型的隐式转换
double d 2.32;
int i d;
const int ri d;
//double类型转化为int时会把整型部分放入临时变量中指针和引用的关系
指针和引用互相不可替代
引用取别名不开空间指针存一个变量的地址要开空间引用必须初始化指针建议初始化但是语法上不是必须的指针可以先定义后面把一个变量的地址放入指针中引用只能引用一个对象而不能再引用其他对象而指针可以不断改变指向引用可以直接访问指向对象指针必须解引用才能访问指向对象引用和指针的sizeof含义不同引用sizeof是引用类型的大小指针32位平台下是4个byte,64位平台下是8个byte引用不容易出现空引用和野引用指针容易出现空指针和野指针
野引用
int func()
{int a 0;return a;//会产生一个别名返回它的一个别名//出函数别名销毁它的引用销毁//再去找它的引用就是野引用
}空引用
int* ptr NULL:
int rb *ptr;
//空引用可以通过编译
rb;
return 0;
//rb是对空引用的使用
//对空引用的使用不会返回0会返回一个负数异常返回表面上是对ptr这个空指针解引用实际上它的汇编代码并不解引用而是把ptr的地址放入一个寄存器中再把寄存器中的地址给rb这个别名引用的底层是指针
引用的实际作用
以前交换两个值用传地址的方式 swap(a,b); 现在有了引用可以用swap(a,b); 在主函数中调用函数不用取地址传参过去的函数定义用引用接收void swap(int x,int y),可以不用指针接收而且不用解引用那么麻烦
但是链表中的二级指针LTNode* ! LTNode,指针不能用引用替代掉C的引用不能替代指针因为引用不能改变指针的指向链表要改变指针的指向用二级指针LTNode* LTNode** ,引用的底层可以理解为指针
引用的实际作用体现在传参里面 使用函数模板T可以是任意类型
templateclass T
void func(const T val)
{//...const 对象常量-具有常性临时变量-具有常性普通变量-可以权限缩小
}inline
用inline修饰的函数叫内联函数C在调用的地方直接展开内联函数就不需要建立栈桢了这样可以提高效率
C的inline为了替代C语言的宏函数而设计出来的宏函数也不建立栈桢#define 定义的宏函数是一个宏直接展开你的代码过大不会帮你展开比如递归层次太深会造成可执行程序变大内存占用变大编译器会帮你展开代码短小重复的代码比如swap交换两个数的值的代码inline不建议声明和定义分离到两个文件分离会导致链接错误因为inline展开函数定义文件的地址会消失导致找不到函数定义只有声明所以定义和声明应该在同一个文件在调用的地方展开会直接执行vs下默认不展开内联函数找到项目属性做以下设置
//内联函数
inline int Add(int x,int y)
{int ret x y;return ret;
}未展开内联函数 call跳转地址建立栈桢 展开内联函数 不跳转直接在调用的地方展开函数逻辑
nullptr
nullptr是关键字 nullptr是C中的空指针专门用来表示空指针nullptr只能隐式类型的转换成其他类型的指针形式不能转化成其他类型比如int
C语言中的 void*0可以隐式类型转为int和int或其他类型C用这套在传参中也是不确定的会传整型又会传指针 C的NULL是0传参中一个函数的参数是int,另一个函数的参数是int,那么会执行第一个函数C中的NULL指针类型又是整型0,这样比较模糊所以空指针用nullptr表示nullptr也是0但它只有指针形式
void func(int* a)
{}//1
void func(int a)
{}//2
int main()
{func(0);//2func(NULL);//2func((void*)0);//会隐式类型转化int或int*不确定走哪个//这样说C走不了空指针了所以定义一个nullptr表式空指针return 0;
}#define NULL 0 C
#define NULL ((void*)0) C