C++ 知识 字节序 一个字(32位 机器采用 32 bits 字长 4 bytes) 在内存中 大小端模式 大端法:大多数 IBM 机器, Internet 传输 是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放; 小端法:Intel 兼容机 是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低,和我们的逻辑方法一致。 变量 内存地址从高到低 左移与右移 逻辑右移,直接填充0; 算术右移,可能1可能0;右移采用哪种方式,取决于编译器。 有符号数尽可能不要右移,因为移走的位填充与符号位有关,负数填充1. 左移直接填充0。 数组初始化 记住三点: int 型数组全局数组,未初始化时,默认值都是 0;局部数组,未初始化时,默认值为随机的不确定的值;局部数组,初始化一部分时,未初始化的部分默认值为 0; char 型数组全局数组,未初始化的部分,默认值为 ‘ ’ ;局部数组,未初始化时,默认值不可预知。局部数组,初始化一部分后,未初始化部分默认值为 ‘ ’ ; double ,float 型数组全局数组,未初始化时,默认值都是 0.0;局部数组,未初始化时,默认值为随机的不确定的值;局部数组,初始化一部分时,未初始化的部分默认值为 0.0; bool 型数组全局数组,未初始化时,默认值都是 0;局部数组,未初始化时,默认值为 204;局部数组,初始化一部分时,未初始化的部分默认值为 0; 原文链接:【编程语言】C++中未初始化的数组的默认值问题_机灵鹤的博客-CSDN博客_c++数组默认值 for 循环访问二维数组 Tips for row: for column 在一个小的时间窗口内,访问的地址变量越接近,执行速度越快。按行存储一般来说将长的循环放在内层,短的循环放在外层,减少循环次数。 vector vector 实际上面向对象的动态数组,可动态扩容 capacity 查看容量 size 查看当前存储的个数 insert 任意位置插入 erase 任意位置删除 字符串 字符串变量与常量 字符串变量 字符串是以空字符‘\0’结束的字符数组空字符‘\0′ 自动添加到祖父穿的内部表示中在声明字符串变量时,应该为这个空结束符’\0′ 预留一个额外素的空间, “”表示字符串, ‘’表示字符。 字符串常量 字符串常量是一对双引号括起来的字符序列字符串中的每个字符作为一个素存储 字符串的指针表示方法 char* ptr = “hello”; char ptr2[10] = {“hello”}; ptr地址可变, ptr2的地址不可变; 如果指向的是字符串常量,ptr[index]不可; 如果重新指向一个字符数据, ptr[index]可以改变, 即取决于所指区间的存储区域是否可变;ptr2[index]可变。 字符串常见操作 string 字符串 C++ 标准库中提供了string 类型专门表示字符串 左值与右值 概念左值 编译器为其单独分配了一块存储空间,可以取其地址的,左值一般放置在等号左边右值 数据本身,不能取到其自身地址,右值只能赋值运算符的右边, 右值一般称之为临时对象& 变量名 是一个右值,因为内部取地址到一个临时的内存空间中,但是临时的内存空间无法取地址 指针 内存结构 网络存储(容量大, 访问速度慢)本地磁盘 内存(不能断电)L2 cache(SRAM)L1 cache(SRAM)寄存器 从上往下,访问速度快,但是容量越小,造价成本高 内存 有多个内存单组成, 每个内存单都进行了编号,编号就是内存地址,决定了内存单在内存的位置, C++编译器通过变量名字来访问这些内存位置 数组指针与指针数组 指针数组 T* t[]; // 存放的指针,实际上一个数组, 数组的素是指针 数组指针 T(*t)[]; // 一个指针,指向数组 const pointer 与 pointer to const 规则: 看左侧符号,左侧没有看右侧符号 二级指针 野指针 NULL 指针 特殊指针变量,表示不指向任何东西初始化时与释放时,可使用访问指针时,可先判断是否为NULLC 语言中 #define NULL ((void*)0)C++ 中 #define NULL 0C++11 中使用 nullptr 代替(void*)0, NULL 则只表示0 指针的基本运算 无论是char*, int* , 其实指针占用4字节,16进制的整型数 存储 存储区域划分 全局初始化区,全局未初始化区(BSS),全局(静态)初始化区(静态变量)代码区堆栈常量区 全局未初始化区,其实内部变量都是0,只做标记,不涉及存储
堆 程序员自己接管内存的分配与释放 程序通常牵涉三个内存管理器1. 分配某个大小的内存块 2. 释放一个之前分配的内存块 3. 垃圾收集操作,寻找不在使用的内存块并予以释放 C++ 前两件事情, java做了1.3两件事 资源管理方案-RAII(Resource Acquisition Is Initialization) 依托栈和析构函数堆所有资源——包括堆在内的内存进行管理。对RAII的使用,C++ 不需要垃圾回收机制,也能有效地对内存进行管理。 RAII 有些比较成熟的智能指针代表:std::auto_ptr, boost::shared_ptr C++ 种集中变量的对比 栈区堆区作用域函数体内,语句块{}作用域在整个程序范围内,由new, malloc, delete, free结束编译期间大小确定可确定运行期间确定大小范围windows: 1Mlinux:8M或10M所有系统的堆内存上限接近内存的总大小内存分配方式高地址到低地址地址由低到高增加内容是否可变可变可变 全局静态区常量存储区存储内容全局变量, 静态变量常量编译期间大小是否确定确定确定内容是否可变可变不可变 内存泄露 已动态分配的堆内存由于某种原因程序未释放或者无法释放造成系统内存浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。 排查方式,无法通过编译识别,只能在程序运行过程中判断 使用指针容易内存泄露,所以可以使用智能指针和引用 智能指针 unique_ptr, shared_ptr, weak_ptr 对象的所有权,声明周期 auto_ptr 由new expression 对象,在auto_ptr对象销毁时,所管理的对象自动被delete掉 所有权转移:不它传递给另外的指针,原来的指针不再拥有这个对象,再拷贝/赋值过程中,直接剥夺原对象内存的控制权,转交给新对象,然后将原指针置为nullptr. 栈or 堆?? unique_ptr unique_ptr 专属所有权,智能被一个对象持有,不支持赋值和复制。 移动语义:unique_ptr禁止了拷贝语义,但是能够转移所有权, 移动语义,使用std::move()控制所有权的转移。 shared_ptr 通过引用计数,共享一个对象 为了解决auto_ptr在对象所有权上的局限性,在使用引用计数的机制上提供了可以共享所有权的指针,需要额外的开销(空间), 去管理引用计数。 当对象引用计数为0时, 该对象没有被使用,进行析构。 循环引用 对象之间相互引用,循环应用导致堆的内存无法正常回收,造成内存泄露。 weak_ptr 目的,为了解决循环引用的问题。 采用观察者模式, weak_ptr是弱指针, 只能对shared_ptr进行引用,而不改变其引用计数的个数。 当被观察值 shared_ptr 失效后,相应的weak_ptr也失效。 引用 变量的别名(特殊的不允许修改的指针?) 一个引用永远指向它初始化的那个对象, 必须初始化。 有了指针为了还需要引用 为了支持函数运算符重载 有了引用为什么还需要指针 因为要兼容C语言 对于函数来说, 内置基础类型(int, double等),传值更高效 在面向对象中自定义类型而言, 使用const引用更高效(const 不改变值, 引用别名,节省空间)
2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/57617.html