深圳网站设计兴田德润简介,企业网站建设怎么样做会计分录,亚圣信息科技做网站怎么样,灵璧零度网站建设一、左值与右值
左值#xff1a;编译器为其单独分配了一块存储空间#xff0c;可以取其地址的#xff0c;可以放在赋值运算符左边
右值#xff1a;数据本身。不能取到其自身地址#xff0c;只能赋值运算右边 左值最常见的情况如西数和数据成员的名字 右值是没有标识符、…一、左值与右值
左值编译器为其单独分配了一块存储空间可以取其地址的可以放在赋值运算符左边
右值数据本身。不能取到其自身地址只能赋值运算右边 左值最常见的情况如西数和数据成员的名字 右值是没有标识符、不可以取地址的表达式一般也称之为临时对象 二、指针
1、指针的概念
1内存单元内容与地址
内存由很多内存单元组成。这些内存单元用于存放各种类型的数据
计算机对内存的每个内存单元都进行了编号这个编号就称为内存地址地址决定了内存单元在内存中的位置。
C的编译器让我们通过名字指针变量来访问这些内存位置
2指针的定义
指针本身就是一个变量其符合变量定义的基本形式它存储的是值的地址
对类型TT*是“到T的指针”类型。一个类型为T*的变量能保存一个类型T的对象的地址 指针变量是一个专门用来记录变量的地址的变量通过指针变量可以间接的另一个变量的值 3间接访问操作
通过一个指针访问它所指向地址的过程称为间接访问或引用指针
这个用于执行间接访问的操作符是单目操作符*
cout *d endl;2、指针数组与数组指针
指针的数组T* t[]
数组的指针T(*t)[] []优先级比较高 3、const与指针
关于const修饰的部分
看左侧最近的部分如果左侧没有则看右侧
4、二级指针
*操作符具有从右向左的结合性
**这个表达式相当于*(*C)从内向外逐层求值
int a 123;
int* b a;
int** C b;cout a *b **c endl;5、NULL指针
NULL指针一个特殊的指针变量表示不指向任何东西 对于一个指针如果已经知道将被初始化为什么地址那么请 赋给它这个地址值否则请把它设置为NULL 在对一个指针进行间接引用前请先判断这个指针的值为否为NULL 6、野指针
野指针未初始化和非法的指针
int *a;
*a 12; // 指针未初始化杜绝“野”指针指向〝垃圾〞内存的指针。if等判断对它们不起作用因为 没有置NULL
指针变量没有初始化已经释放不用的指针没有置NULL如delete和free之后的指针指针操作超越了变量的作用范围
三、c内存布局
1、存储区域划分 2、堆heap
利用堆(heap)空间动态分配资源
动态内存具有不确定性C让程序员完全接管内存的分配释放
3、动态分配与回收
程序通常需要牵涉到三个内存管理器的操作
分配一个某个大小的内存块释放一个之前分配的内存块垃圾收集操作寻找不再使用的内存块并予以释放这个回收策略需要实现性能、实时性、额外开销等各方面的平衡很难有统一和高效的做法 C做了1、2Java做了1、3 4、RAII
RAII (Resource Acquisition Is Initialization)
C所特有的资源管理方式。有少量其他语言如D、Ada 和Rust也采纳了 RAll但主流的编程语言中C是唯一一个依赖 RAII来做资源管理的
RAIl 依托栈和析构函数来对所有的资源包括堆内存在内进行管理。对 RAII 的使用使得 C不需要类似于 Java 那样的垃圾收集方法也能有效地对内存进行管理。RAIl 的存在也是垃圾收集虽然理论上可以在 C使用但从来没有真正流行过的主要原因
RAII有些比较成熟的智能指针代表
5、不同变量的对比
1栈和堆中的变量
栈(stack)区堆(heap)区作用域函数体内语句块{}作用域整个程序范围内new,malloc开始delete,free结束编译期间大小确定变量大小范围确定变量大小范围不确定需要运行期确定大小范围Windows系统默认栈大小是1Mlinux常见默认的栈大小是8M或10M (ulimit-s)所有系统的堆空间上限是接近内存虚拟内存的总大小的一部分被OS占用内存分配方式地址由高到低减少地址由低到高增加内容是否可变可变可变
2全局静态存储区和常量存储区的变量
全局静态存储区常量存储区存储内容全局变量静态变量常量编译期间大小是否确定确定确定内容是否可变可变不可变
5、内存泄露
内存泄漏程序中己动态分配的堆内存由于某种原因程序末释放或无法释放。造成系统内存的浪费导致程序运行速度减慢甚至系统崩溃等严重后果
五、智能指针
1、auto_ptr
auto_ptr在c17中移除
特点由new expression 获得对象在auto_ptr对象销毁时他所管理的对象也会自动被 delete掉
所有权转移不小心把它传递给另外的auto_ptr原来的指针就不再拥有这个对象了。在拷贝或赋值过程中会直接剥夺指针对原对象对内存的控制权转交给新对象然后再将原对象指针置为nullptr
2、unique_ptr
特点专属所有权所以unique_ptr管理的内存只能被一个对象持有不支持复制和赋值
移动语义unique_ ptr禁止了拷贝语义但提供了移动语义即可以使用std::move()进行控制所有权的转移
3、shared_ptr
shared_ptr通过一个引用计数共享一个对象。当引用计数为0时该对象没有被使用可以进行析构
shared_ptr是为了解决auto_ptr在对象所有权上的局限性在使用引用计数的机制上提供了可以共享所有权的智能指针但需要额外的开销 循环引用引用计数会带来循环引用的问题 循环引用会导致堆里的内存无法正常回收造成内存泄漏 4、weak_ptr
weak_ptr 被设计为与shared_ptr共同工作以一种观察者模式工作
作用是协助 shared_ptr 工作可获得资源的观测权像旁观者那样观测资源的使用情况
观察者意味着weak_ptr只对shared_ptr进行引用而不改变其引用计数。当被观察的shared_ptr失效后相应的weak_ptr也相应失效
六、引用
1、引用概述
引用一种特殊的指针不允许修改的指针
引用的基本使用可以认为是指定变量的别名使用时可以认为时变量本身
int x1 1,x2 3:
int rx x1;
rx 2;
cout x1 endl; //2
cout rx endl; //2
rx x2;
cout ×1 endl; //3
cout ry endl; //32、引用存在的意义
有了指针为什么还需要引用为了支持函数运算符重载
有了引用为什么还需要指针为了兼容C语言
3、补充
对内置基础类型如int,double等而言在两数中传递时pass by value 更高效
对面向对象中自定义类型而言在函数中传递时pass by reference to const更高效