
C/C++
C与C++学习记录
854bd5138e0a3d23
这个作者很懒,什么都没留下…
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
哈希表的C++实现
【代码】哈希表的C++实现。原创 2022-10-10 17:02:33 · 1486 阅读 · 0 评论 -
平衡二叉搜索树的C++实现
该模板类实现了平衡二叉搜索树的操作,其搜索的效率高达log2。原创 2022-10-05 22:08:31 · 337 阅读 · 0 评论 -
动态字符串的实现
【代码】动态字符串的实现。原创 2022-10-05 22:03:48 · 252 阅读 · 0 评论 -
双向循环队列的C++实现
双向循环队列的特点是两头都可以进行插入和删除操作。原创 2022-10-05 22:02:17 · 539 阅读 · 0 评论 -
双向循环链表的C++实现
【代码】双向循环链表的C++实现。原创 2022-10-05 22:05:25 · 629 阅读 · 0 评论 -
C++的delete与delete[]剖析
如果说把delete[]换成了delete的情况下, 由于delete后面需要接析构地址,根据析构地址再从上面的堆表中寻找信息来进行析构, 它不会把pt0指向的位置往边上挪动,指哪里用哪里,而pt0指针指向的不是堆的开始位置, 即。假如说,我们把delete指向的内容,经过人工干预指向对应的地址会怎么样?这么做虽然main函数中的delete调用成功了,但当其调用析构函数内部时,由于delete (pt0 - 1)把指向的内容时0x0a, 所以内部释放时肯定会出问题。来执行析构的所以没有问题。原创 2022-08-25 14:53:41 · 509 阅读 · 0 评论 -
C++如何利用成员函数修改this指针的值
由于C++中类内的成员函数使用的是__thiscall的方式传递this指针, 即this指针通过ecx寄存器保存带入函数, 所以想要在成员函数内修改this指针的值就必须修改调用方式,将调用方式修改成__stdcall或者__cdecl的形式, 这样this指针就会被压入栈帧, 通过传入参数就可以修改this指针。发现修改的内容是另一个对象的成员变量。原创 2022-08-25 11:33:47 · 877 阅读 · 0 评论 -
C++如何不通过语法调用成员函数
可以通过成员函数指针来调用, 先来介绍一下成员函数指针,其与函数指针基本一致,只是要添加作用域运算符。原创 2022-08-25 11:00:29 · 495 阅读 · 0 评论 -
C语言实现贪吃蛇
【代码】C语言实现贪吃蛇。原创 2022-08-24 14:39:03 · 352 阅读 · 0 评论 -
C语言中使用结构体(struct)模仿共用体(union)
1. 普通的模仿方式#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>#include <stdlib.h>#define TYPE_INT 0#define TYPE_FLOAT 1#define TYPE_CHAR 2#define TYPE_TEXT 3struct tagScore{ int iType; int iPoint; float fPoint; char cLevel; char s原创 2021-02-19 14:33:20 · 291 阅读 · 0 评论 -
异或加密工具类
写了一个异或加密工具类调用加密字符串 直接加密文件#define _CRT_SECURE_NO_WARNINGS#include <iostream>using namespace std;class Encrypt{public: // 构造函数 Encrypt(); Encrypt(char *pContent, unsigned char ucKey = 'x'); // 拷贝构造函数 Encrypt(const Encrypt& e); //原创 2021-02-13 14:54:42 · 1321 阅读 · 0 评论 -
C++细节笔记14
1. 基本的文件IO方式#include <iostream>#include <fstream>#include <cstdlib>using namespace std;int main(){ fstream fs; fs.open("1.txt", ios_base::in | ios_base::out); if (!fs.is_open()) { cout << "打开文件失败!" << endl;原创 2021-02-10 06:34:50 · 215 阅读 · 0 评论 -
C++细节笔记13
模拟智能指针的行为#include <iostream>#include <cstdlib>using namespace std;class CFoo{public: CFoo() { cout << "CFoo构造函数调用" << endl; } ~CFoo() { cout << "CFoo析构函数调用" << endl; } void Test() { cout <<原创 2021-02-08 15:46:08 · 150 阅读 · 3 评论 -
C++细节笔记12
1. 函数模板作用解决重复代码冗余问题2. 隐式与显式实例化隐式实例化显式实例化注意,模板只有在使用时才会实例化, 在VC++6.0中甚至都不会检查其语法,也就是说直到运行才会发现该语法错误模板特例其特点是:template<>中没有类型 在函数实现中指定类型调用方法如下:3. 类模板类成员函数模板类成员函数模板不允许隐式实例化, 需要显示指明类型但是只需要在定义时显式指明一次即可,后面调用无需指明类模板中类型与原创 2021-01-23 17:41:08 · 195 阅读 · 0 评论 -
C++细节笔记11
1. final关键字final关键字在继承中产生作用,父类虚函数使用了final后,子类无法重写该虚函数2. 运算符重载作用: 提高代码可读性,提高类的易用性使用重载的两种方法:运算符重载的原则:1. 运算符重载不能改变运算符原有使用方式 2. 运算符重载不能改变原有运算符意义关于赋值运算符如果自己没有实现,则编译器会提供一个默认的赋值运算符重载,其直接进行浅拷贝操作经验建议: 一个类要至少实现如下三个, 目的是为了消除编译器实现默认类函数的机会实现默认构造原创 2021-01-20 16:13:22 · 121 阅读 · 0 评论 -
C++细节笔记7(补充拓展)
拷贝构造当类没有实现拷贝构造的时候,编译器会提供一个默认的拷贝构造 默认拷贝构造即内存拷贝(通过memcpy拷贝也就是浅拷贝) 当类提供了拷贝构造时,则调用提供的拷贝构造拷贝构造的时机对象传参, 比如调用void Test(ClassName buf)时形参需要传入ClassName的类对象,其实际上就是拷贝构造 使用对象构造对象, 比如下面的例子ClassName obj1; // 默认无参构造函数ClassName obj2(obj1); // 显式调用了拷贝构造返回值返回类原创 2021-01-20 13:35:35 · 242 阅读 · 0 评论 -
C++函数指针与成员函数指针(补)
1. 函数指针直接使用通过typedef使用, 当使用了typedef后,函数指针名就变成了一个专门的函数类型名,可以直接使用该名称定义该类型的函数指针2. 成员函数指针首先来看一个例子:这里出了问题,要求加上&符号,而单纯的函数指针没有这种强制要求,来看下:加上了&后还是有问题,显示类型不匹配,这里需要加上类作用域:加上作用域后,成员函数指针已没有问题了,但调用的时候出现问题,来看一下正确的使用方法:上面使用了两种,一种是成员函数指针定义原创 2021-01-20 13:30:01 · 278 阅读 · 1 评论 -
C++细节笔记10(上)
总结下C++各种情况下的内存排布:1. 单个类情况: 类内成员属性按顺序在内存中排布,与构造或赋值顺序无关2. 单个类有虚函数情况: 多了一个虚表指针并排在最低地址, 属性依次往后排列3. 单继承情况: 父类成员在低地址,子类成员在高地址依次排列4. 单继承带虚函数(子类未实现)情况: 继承父类虚表指针并排在最低地址处,其余与单继承一致5. 单继承带虚函数(子类实现)情况: 子类自己生成虚表并将指向虚表的虚表指针并排在最低地址处,其余与单继承一致原创 2021-01-03 10:41:24 · 125 阅读 · 0 评论 -
C++细节笔记9
1. 编译器添加默认构造函数的时机父类有构造,子类没有,编译器会为子类提供一个默认构造函数 类成员对象有构造,自己没有,编译器会提供一个默认构造函数 类中有虚函数, 按需求决定是否提供 单独类中没有构造,编译器提供默认构造2. 抽象类(含有纯虚函数的类)虚函数后添加=0, 即纯虚函数,纯虚函数没有函数体 含有纯虚函数的类叫做抽象类,其不能实例化对象 如果子类没有实现父类的纯虚函数,则子类也是抽象类 纯虚析构函数是个特例,其可以实现函数体抽象类也被称为规范化接口,其可以强迫子类必须实现原创 2021-01-02 17:03:37 · 126 阅读 · 0 评论 -
C++细节笔记8
1. VS快捷键Shift + Del删除整行2. 继承访问权限:继承关系的构造顺序: 先父类, 在成员最后构造自己继承关系的析构顺序: 先自己,在成员最后析构父类3. 继承的内存排布:假设发生了继承之后,父类在低地址,子类在高地址4. 继承中的隐藏可以通过作用域运算符指定调用父类函数解决该问题:4. 多态(完)...原创 2021-01-02 12:28:56 · 303 阅读 · 0 评论 -
C++细节笔记7
1. 浅拷贝和深拷贝浅拷贝可能出现重释放问题深拷贝导致资源浪费最佳解决方案: 引用计数即用一个计数器记录某块堆内存被引用的次数,平时调用拷贝构造时仅使用浅拷贝并仅增加引用计数的值,每次释放仅减少引用计数,直到引用计数变成0才会进行释放,这样就解决了这个问题计数器放在哪?静态成员变量: 不可取,因为假设有不同的对象即非拷贝构造导致的新对象,这时静态成员变量会出现混乱,因为两个对象到底增加的是谁的计数这会混淆在一起 成员属性: 可取,以成员指针的形式驻入类内,每个对象在构造原创 2020-12-24 10:31:11 · 104 阅读 · 0 评论 -
C++细节笔记6
1. 初始化列表,可对一般数据成员,常数据成员以及类对象数据成员进行初始化并且其时机比构造函数早,类中假设包含类对象成员,则构造时先构造成员后自己,析构时先析构自己后析构成员(顺序相反),类定义中假设有多个类对象成员,则他们之间的构造顺序与成员定义顺序一致2. 静态成员(未完)...原创 2020-12-24 09:30:57 · 107 阅读 · 0 评论 -
C++细节笔记5
1. C++中通过malloc在堆上分配一个类对象不会调用构造函数,free也不会调用析构函数, 调用new和delete才可以。其构造顺序是先分配内存后调构造,析构顺序是先析构在释放内存2. 为何new[]时需要传入具体个数(只要初始化了编译器就可以了解到对应大小,如果不初始化需要写入具体个数),而delete[]时不需要?原因是因为在申请内存的上4字节,有一个DWORD,其是申请的元素个数,编译器根据该值确定释放次数3. 为何new出来类实例的数组,使用delete[]没有问题,而单原创 2020-12-23 14:46:56 · 257 阅读 · 0 评论 -
C++细节笔记4
1. thiscall调用约定thiscall一般是类的成员函数用的调用约定,其特点是通过ecx传递指向实例对象的指针,即this指针。成员函数的调用约定可以改但是不推荐2. 定义类内的函数指针#include <iostream>using namespace std;class Base{public: Base() = default; void SetNum(int iNum) { m_iNum = iNum; } int GetNum() {原创 2020-12-19 22:16:45 · 82 阅读 · 1 评论 -
C++细节笔记3
1. 命名空间命名空间的定义, 以及基础使用using namespace Namespc;这句代码代表了从该行开始所有代码对Namespc空间中的内容可见。单独引用命名空间中的一个变量或者函数使用using xxx:??,其中xxx代表某个命名空间,??代表其中某个变量或者方法名。可以使用某个命名空间的具体某个内容命名空间可分开可以看到上述代码中,命名空间被分成了两部分,但其内容依旧是同一部分2. 重载重载意思是函数名相同,参数列表(顺序,类型,个数)不同。调用约定,原创 2020-12-17 13:24:49 · 123 阅读 · 0 评论 -
C++细节笔记2
1. 宏的缺点没有类型检查 宏无法进行调试(宏无符号),即在监控窗口无法显示值const修饰的常量在C与C++中是不一样的,C++在编译过程中会进行替换,类似于宏。并且是一个真的常量,而在C中const修饰的值是一个假的常量,可以通过指针修改C++中const是常量理所应当其无法被修改,在VS的Debug版中可以被修改但这是假的,在Release版本中就不可以了。它根本就没有地址2. 引用引用必须初始化 对左值不可多级引用 不能改变引用的变量,只能改变引用的变量的值 const修饰原创 2020-12-16 14:32:55 · 81 阅读 · 0 评论 -
C++细节笔记1
1. 变量初始化时加上{}可以阻止隐式类型转换int i = {3.145}; 报错,因为严格类型匹配2. 类型推导符auto和decltype(x)3. nullptr与NULL区别NULL可以赋值指针变量和非指针变量可以看到在C中NULL被定义为(void *)0,是可以指向任意类型的指针C++中NULL被直接定义为0nullptr只能赋值指针变量, 其真实类型是std::nullptr_t类型,是一个指向任意指针类型的字面值常量C++不能使用(void *)来强原创 2020-12-15 16:50:22 · 147 阅读 · 0 评论 -
关于柔性数组技巧
柔性数组的使用最典型的使用:IMAGE_IMPORT_BY_NAME数组。自己实现的小李子如下:#include <stdio.h>#include <stdlib.h>#include <string.h>typedef struct _SoftArr{ unsigned short usLen; char cArr[1];} SoftArr;void ShowString(const struct _SoftArr *pStArr原创 2020-12-08 09:10:00 · 141 阅读 · 0 评论 -
不懂汇编也可以从底层理解C/C++中各种变量(下篇)
这篇博客主要是记录关于静态局部变量的内容。在上篇中已经提到了静态局部变量是和全局变量放在一个地方的也就是全局区内部,照理说他们的属性和作用域应该是一样的,现在提出以下两个问题:1. 静态局部变量是如何限定其作用域在局部函数内部的?2. 静态局部变量是如何做到只初始一次之后即使在进入也不会初始化的?首先是第一个问题, 来看一下下面这段代码:用WinHex打开将其编译之后的obj文件, 看到如下内容:把这些内容全部复制过来:上图中注释中的字符串都是对应静态局部变量在编译后原创 2020-12-06 10:58:55 · 276 阅读 · 0 评论 -
C语言结构体技法斩
结构体成员偏移计算起始偏移: offsetZp: 默认对齐(也可以通过该选项在cl.exe编译时选定其他对齐形式)或者直接在IDE内修改满足该条件offset % min(Zp, max(member type1 size, member type2 size, ......)) == 0代表offset是对应偏移位置结构体对齐单位计算Align = min(Zp, max(member type1 size, member type2 size, ......))对齐条件if原创 2020-12-04 14:41:17 · 266 阅读 · 0 评论 -
零散的关于C语言的知识
关于解释性宏_CRTIMP: 该函数或者变量是导入自己用的_CRTEXP: 该函数或者变量是导出给别人用的一种技巧可以利用无符号短整型模拟UNICODE编码,其中MZ被写成了ZM因为在内存中是小端排序。实际上ZM在内存中的存储就是MZ:关于VC++6.0的两个BUG:float浮点协处理器问题来看一下这段代码这段代码没有任何问题,编译链接都通过:但当我运行的时候却发现了如下问题:这是什么导致的? 其原因在于专门用于处理浮点数的协处理器FPU没有初始化.原创 2020-12-02 15:37:26 · 201 阅读 · 0 评论 -
C++ Primer阅读笔记[Part 4]
IO流C++中的IO类主要有3种: iostream头文件 主要控制读写流 istream 读流类型 ostream 写流类型 iostream 读写流类型 fstream头文件 主要用于文件读写ifstream 读文件类型 ofstream 写文件类型 fstream 读写文件类型sstream头文件 主要用于读写内存中的string对象istringstream 读string类型 ostringstream 写string类型 stringstream原创 2020-10-16 10:41:04 · 233 阅读 · 0 评论 -
C++11中的constexpr
顶层const与底层constC++11中把const限定符分为了顶层const和底层const。在引用中的const永远是底层const,具体原因后面解释。首先看一下顶层const和底层const的定义, 根据C++ Primer第五版中:顶层const: 指代指向别处的指针本身是一个常量 底层const: 指代指针所指向的对象是一个常量其实说的感觉很高大上简而言之就是顶层const把const修饰指针,底层const则修饰指向的对象。实际上这里虽然说的是指针,但任意对象只要掺和了cons原创 2020-10-09 10:48:20 · 313 阅读 · 0 评论 -
C++ Primer阅读笔记[Part 3]
拷贝赋值与析构构造函数(初始化对象的非static数据成员):成员初始化在构造函数执行之前完成并且按照他们在类中的顺序进行拷贝构造函数: 第一个参数是自身类引用 任何额外参数都有默认值 由于拷贝构造函数可能被隐式引用所以一般不是explicit发生的前提条件:用=定义变量时 从一个返回类型为非引用的函数返回一个对象 把一个对象作为实参传递给一个非引用类型的形参 用花括号列表初始化一个数组中的元素或一个聚合类中的成员析构函数(销毁对象的非static数据成员):先执...原创 2020-10-04 15:18:56 · 372 阅读 · 0 评论 -
C++基础笔记
函数模板:A. 自动类型推导, 必须有参数类型符合才可以推导template<typename T>void swap(T &a, T &b) { ...}int main() { char a = 10; int b = 20; swap(a, b); return(0);}B. 调用时显式指定类型swap<int>(...);普通函数与模板函数的区别1. 普通函数可以进行隐式类型转换而模板函数没有隐式...原创 2020-10-01 12:04:37 · 154 阅读 · 0 评论 -
简化的string类的模拟
#include <iostream>#include <string>#include <ctime>#include <stdexcept>#include <iterator>#include <vector>#include <algorithm>#include <functiona...原创 2020-03-01 14:49:17 · 143 阅读 · 0 评论 -
C++ Primer阅读笔记[Part 2]
函数模板:A. 自动类型推导, 必须有参数类型符合才可以推导template<typename T>void swap(T &a, T &b) { ...}int main() { char a = 10; int b = 20; swap(a, b); return(0);}B. 调用时显式指定类型swap&l...原创 2020-03-01 12:42:27 · 348 阅读 · 0 评论