- 博客(42)
- 收藏
- 关注
原创 C++:内存管理(new,delete)
在C/C++中,都有一块虚拟地址,内部井然有序的将代码分成了几部分,如下表:栈:又叫堆栈,存放着非静态局部变量、函数参数、返回值等,栈是向下生长的内存映射段:是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口创建共享内存,做进程间通信堆:用于程序运行时动态内存分配,栈是向上生长的数据段:存储全局数据和静态数据代码段:存储可执行代码、只读常量。
2024-07-22 18:13:48
908
1
原创 C++:类和对象 III(初始化列表、explicit、友元、匿名对象)
这两种写法给我们带来的效果都是一样的,但是无论怎么写我们的成员变量都要经过初始化列表一遍,就算没有写初始化列表也会!这里就是由于编译器的优化,由于A a2 = a1这个表达式做了两件事情,一件就是构造,另一件就是拷贝构造,所以编译器优化成了只有拷贝构造即可。这是因为类声明是先声明的_b,才声明的_a,所以初始化列表会先初始化_b,再初始化_a,而不是因为_a在初始化列表中初始化就初始化_a。那就是在初始化列表中!初始化列表中按照成员在类中声明的定义来初始化,于初始化列表中出现的先后顺序无关。
2024-07-18 23:24:15
1031
原创 C++:类和对象 II(默认成员函数)
浅拷贝是字节的拷贝,那么这个st1指针的字节也会被另一个对象st2所拷贝,这时候如果析构函数我们需要释放空间st1的空间,那么会根据_a的指向来free(_a),这时候st1的空间已经被销毁,总所周知,在C语言中如果我们写了一个日期类,如果我们想要在我们自己的类定义出的对象里面进行加减乘除法明显是不行的,你自己定义的类怎么能加减呢?如果别人需要使用我们的类,我们不想给他们使用,或者有别的意思,我们是可以恶搞一下的,取地址运算符重载,把地址变成一些莫名其妙的数字。
2024-07-15 15:00:47
855
原创 C++:类和对象 I(访问限定符、this指针)
class就是类,class是C++中的一个关键字当然类也可以是C语言中的struct,C++兼容struct,甚至还有一些升级定义类的方式class Date和C语言的struct一样,class是C++中定义类的一个关键字,Date是这个类的名字,我们需要在后面跟上一个 {}和;,{}里面可以放变量,函数等定义在类里面的成员函数默认为inline。
2024-07-12 17:56:34
1178
原创 C++:入门基础
因为编译器不能随意的展开一段代码,假设我们的func函数有1000条代码来完成,但是我们在main函数或者其他地方调用了func函数100次,全部都展开的话就是1000*100的代码量,这样会使我们的内存负担极大,相反,不展开的话只需要一个个call func函数的地址即可。上图的a是被const修饰的,只可读不可写,没有const限制的b自然也无法变成a的别名,因为b是可读可写,如果可以引用的话那a的权限就相当于被b放大了,这是不被允许的。
2024-07-10 20:57:25
969
原创 C数据结构:排序
若按照错误方法来:例如:begin = 0,end = 3,那么mid = 1,begin1 = 0,end1 = 2,递归左右区间为[0,2]也就是begin = 0,end = 2,那么mid = 1,begin1 = 0,end1 = 2,这样又递归就会出现栈溢出的情况,所以必须要按照 上面代码的方式走。然后这个for循环做的就是遍历原数组,将原数组的值减去最小值,这个值映射到count数组中,让这个下标的值++,这样就会统计这个值出现的次数,而与原数组建立的关系就是减去一个min的关系。
2024-06-12 17:26:51
1084
1
原创 C数据结构:堆(实现、排序)
这时候就已经不是一个堆了,那么我们就需要用向下调整算法让第一个节点向下调整,使之重新成为一个堆,让最后的end--(也就是将我们刚刚找到的最大的数据或最小的数据排除在外),循环结束时我们的排序也就做完了。堆排的思想是先让堆顶最大(或最小的元素放到最后),然后把最后一个节点排除在外将其他节点看成一个堆,重新找出第二大(或第二小的元素放到倒数第二个位置),以此往复即可将数组顺序排好。在循环中,若第二个孩子节点的值小于第一个孩子的值,则child++,就能找到两个孩子节点中小的那一个。
2024-05-20 16:33:26
596
原创 C数据结构:队列
双向链表也很好,但是我们需要多定义一个prev指针,我们在出队和入队的过程中并不是很需要这个prev指针(如果只是为了出队方便完全可以定义一个队头节点的指针一直指向队头即可), 如果多了一个prev指针那么就意味着我们需要多维护一个指针变量,并且还会多消耗一点空间。队列这种特殊的结构既可以通过数组的方式实现,也可以链表的方式来实现,这时候就要考虑它两的优缺点来决定使用谁来实现了。这个QNode是必须要定义的,这是链表的基础,为了完成我们的队列而创建的,这是我们底层的结构。
2024-05-12 01:07:25
837
原创 C数据结构:栈
栈是一种特殊结构的线性表先来看看栈的图之所以说它特殊,是因为它的插入删除功能比较特殊栈的插入也叫作栈的插入只能在栈顶插入栈的删除也叫作栈的删除只能在栈顶删除。
2024-05-08 20:57:47
1028
原创 时间复杂度和空间复杂度
我们每个人都有每个人自己的思想,写出来的代码自然就各有不同但是代码也是分好坏的,每做一道题,使用到的算法也是有好坏的,那么我们如何来衡量这个好坏呢?下面将从时间和空间两个角度分析。
2024-04-30 15:45:19
311
原创 C语言:贪吃蛇游戏(万字解读超详细)
贪吃蛇这个游戏应该我们小时候都玩过吧我相信能够点进这个博客的应该都很熟悉这个游戏了如果对这个游戏不熟悉的可以网上查查怎么玩,这样才能对这个游戏有个清晰的认知该篇博客需要拥有C语言基础(对指针熟悉、会链表的使用)下面我们需要先学习一些C语言之外的东西认真坚持看完,我相信你一定能完成这个接近500行的C语言贪吃蛇项目该类型内部封装了两个成员,一个x,一个y,代表坐标我们可以将我们的控制台理解为一个平面坐标图横向正方向是x轴正方向,竖向负方向是y轴正方向。
2024-04-20 16:54:01
3387
2
原创 C数据结构:双向链表(带头循环)
链表分多种,分别为不带头不循环单向链表、不带头循环单向链表、带头循环单向链表、带头不循环单向链表不带头不循环双向链表、不带头循环双向链表、带头循环双向链表、带头不循环双向链表一共八种在前一篇博客中完成的单链表即为不带头不循环单向链表而今天要完成的是带头循环双向链表。
2024-04-14 15:11:11
601
原创 C数据结构:单链表
每一个车厢可以看作是一个个的数据,中间把它们链接起来的东西就是我们的指针,指针存储着下一个“车厢”的地址,只有到达了这个车厢获取到了我们的指针才能获取到下一节车厢的钥匙。所以我们定义了一个cur负责走到pos的前一个节点,然后将cur的next指针指向我们新创建的节点连接起来,然后让新节点的next指向我们的pos指向的节点即可。= NULL 的条件终止循环。这样我们的第一个节点就做好了,这个节点里既存放了我们的data数据,还存放了下一个节点的地址,我们就可以通过解引用next找到我们的下一个节点。
2024-04-10 20:41:04
732
原创 C顺序表:通讯录
数据结构中的顺序表如果已经学会了,那么我们就可以基于顺序表来完成一个通讯录了通讯录其实我们使用前面学习过的顺序表就能完成不过,相比较来说,前面的顺序表就是个整型数组,但通讯录就是一个多信息的自定义类型了如果没了解过顺序表的可以看看我前篇博客下面直接来开始完成我们的通讯录吧。
2024-04-07 21:43:26
827
原创 C数据结构:顺序表
数据结构是什么?为什么我们需要数据结构?数据结构是计算机存储、组织数据的方式1. 能够存储数据2. 存储的数据能够方便查找顺序表本质可以理解为是一个数组我们需要对这个数组进行有效的增删查改方面的操作,进行有效的管理,所有有了顺序表。
2024-04-05 21:45:03
908
原创 C语言:预处理详解
C语言中设置了一些预定义符号,可以直接使用__FILE__ //进⾏编译的源⽂件__LINE__ //⽂件当前的⾏号__DATE__ //⽂件被编译的⽇期__TIME__ //⽂件被编译的时间__STDC__ //如果编译器遵循ANSI C,其值为1,否则未定义FILE表示当前文件的路径LINE表示当前的行号DATE表示当今日期TIME表示具体时间STDC为1我们来测试一下int main()return 0;
2024-03-30 18:53:23
962
原创 C语言:文件操作的详解(看完一定有更深刻的理解)
在我们进行C语言编程时,我们每次运行的代码虽然都会出结果,但是我们并不能保存下来,所以如果我们需要保存下来得学习文件的操作文件几乎是每个项目里都需要的东西,因为我们的项目运行的时候都需要保存数据,甚至需要从文件里读取数据,比如一个学生管理系统做完之后,使用者总需要用这个系统将所有学生的信息输入到电脑里,但是总不能输入不保存吧,所以需要使用一个文件保存,在下次使用的时候又可以从这个文件里读取数据,从而进行增删改查等等功能所以文件的学习是非常有必要的。
2024-03-27 20:15:53
970
原创 C语言:动态内存管理(malloc,calloc,realloc,free)
在这一章节将讲解动态内存分配,它可以在程序的堆区创建一块内存,在这块内存中存什么值就是由自己决定的了开辟的空间有两个特点:1. 空间开辟的大小是固定的2. 数组在声明时必须指定长度,数组的大小一旦确定就不能调整在使用这些函数之前我们需要包含他们头文件。
2024-03-26 23:10:36
1421
1
原创 C语言:自定义类型:联合体和枚举
联合体也是个自定义类型,它和结构体类似,都是由多个成员构成,可以有不同的内置类型。2. 当最大成员的大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。这样我们就可以在枚举作用的范围内直接使用它的成员作为值了,跟宏定义类似。联合体之所以叫联合体,是因为它里面的成员会重复使用一块内存空间。这里的char c 是会和 int i 共用一块空间的,如图。要调整到最大对齐数的整数倍,这里不难看出最大对齐数为4。所以联合体的大小至少是最大成员14个字节的大小。1. 联合体的大小至少是最大成员的大小。
2024-03-25 22:24:43
767
原创 C语言:自定义类型:结构体
C语言中有很多种类型,例如:int ,float ,char ,double, long ,long long ,long double等等,这些叫C语言的内置类型但是有的时候描述一个人或物只用某一个类型是明显不够的这时候C语言提供了自定义类型:结构体。
2024-03-22 00:18:50
922
1
原创 数据在内存中的存储
对于64位的浮点数(double),最高1位存储S,接着11位存储指数E,剩下的52位存储有效数字M。对于32位的浮点数(float),最高1位存储S,接着8位存储指数E,剩下的23位存储有效数字M。大端存储模式:指数据的低位字节内容保存在内存的高地址处,高位字节内容保存在内存的低地址处。小端存储模式:指数据的低位字节内容保存在内存的低地址处,高位字节内容保存在内存的高地址处。(-1)^S 表示符号位,当S = 0,V为正数,S = 1,V为负数。符号位不变,其他位依次按位取反即可(0变1,1变0)
2024-03-18 23:32:55
779
原创 ctype.h的了解,string.h库函数、memcpy,memmove函数的使用和模拟实现,
如果str1大于str2,返回大于0的数字,str1小于str2,返回小于0的数字(具体什么数字不做要求)如果我们从str1中找str2的时候,发现了第一个l,那么往后走发现第二个不是o的时候,我们如何返回呢?该函数的作用是可以将一个字符串的内容拷贝到另一个字符串中,以需要拷贝的字符串中的'\0'作为标志结束。因为我们如果只有str1和str2就算能够找到str1中的str2也无法后退返回原来的地址了。str2判断完str1的ll不是lo的时候str2又怎么返回到str2的起始地址l中呢?
2024-03-16 16:53:28
830
2
原创 C语言:指针的进阶讲解
比如 input = 1 ,那么这个p[1]存放的是add的地址,那么就相当于add(x, y),跟平常调用函数没有区别,使用函数指针数组可以让我们的代码更加简洁,如果一个一个写调用的话就比较麻烦,看起来的效果自然没有这个好。上面的指针数组里的指针没有加上小括号,所以 * 会优先和 int 结合,p1自然就和[10]结合,所以这是个有10个元素的整型指针数组。下面的数组指针里的指针加上了小括号,所以*先和p2形成一个指针,那么这个指针会指向后面的数组,所以这是个整型的数组指针。
2024-02-24 21:31:18
1327
1
原创 C语言:指针的基础详解
这样*p虽然能获得值并且打印出来,函数每次调用都是建立栈空间,但是使用过后,函数建立的栈帧会消失, 那么地址就不存在了,p原本还指向这个函数,但函数消失后就变成了未知的区域,所以p就变成了野指针。我们看待这个指针的时候要把 int 和 * 看成一对,int* 就和上面的 int类似,都是个类型,它两组成了一个整型指针类型,这个p就是个名字,和 a 是一样的。主要是看const的位置在哪里,如果const是在*p的前面,限制的是*p,*p不可改变,如果是在*的后面p的前面,限制的是p,那么p不可改变。
2024-02-16 00:23:33
1036
原创 那些也许你不知道的操作符!
操作符有很多种,目前我们已经了解了一部分例如最简单的+、-、*、/、=,还有我们学到的&&,||,!等,但是操作符可不是就只有这么些的,让我们一起来看看吧目录1. 移位操作符原码、反码、补码1.1 <<左移操作符1.2 >>右移操作符2. 位操作符&按位与|按位或^按位异或~按位取反3.整型提升。
2024-02-13 01:12:44
579
1
原创 C语言:函数递归
在解决某些问题时,如果这个问题递归和循环两者皆可,那么建议使用循环理由:1.循环时间复杂度低2.循环空间复杂度低3.代码简单易懂但是在某些比较棘手的困难问题上,循环会很麻烦,而且不容易想出来,这个时候可以尝试使用一下递归理由:1.递归实现较容易2.递归可简化问题学习递归是有助于我们后期学习数据结构的,在学习树的时候会大量使用递归,所以递归是一个重要的内容完。
2024-02-08 01:21:59
528
原创 学会了C语言的数组和函数,那就来看看扫雷游戏吧
扫雷游戏我们应该都有玩过吧,那么当我们学完了二维数组之后就可以开始自己动手制作一个简易的扫雷游戏了下面是效果展示先来看看完整代码。
2023-12-21 20:59:15
1148
1
原创 C语言函数的精解
自定义函数就是我们自己创造出一个属于我们自己的函数,格式如下type fun_name(形式参数)语句;这里的type可以是整型(int)也可以是浮点型(float)等等,这里的类型表示的是我们最后return语句返回值的类型,甚至也可以是void,没有任何类型,可以不用写returnfun_name是函数名,由自己定义,最好有意义,能够让人记住,方便使用小括号中是你需要的参数,参数的个数由自己决定最后在大括号里面加入你需要的语句即可如果我们要创建一个加法函数return ret;
2023-12-16 19:00:41
1244
1
原创 printf函数为什么输出用的是双引号?有没有其他方式打印?你真的懂使用printf函数来打印了吗?
我们知道printf()里面的参数时用字符串,可以打印字符串里的内容,但它的参数是给一个字符串吗?
2023-12-13 10:41:25
693
原创 C语言猜数游戏(精讲),你能顺利做成这个游戏并且自己游玩通关吗?
这里为了美观起见我们可以在游戏开始前制作一个菜单,如果输入1则开始游玩,如果输入0则退出游戏定义一个menu函数制作出来一个菜单,所以可以这样int main()int guess;int input;//定义input来接受用户输入的值do {menu();//使用menu函数printf("请输入0或1决定是否游玩\n");case 1:printf("请输入一个数字:\n");printf("猜大了\n");printf("猜小了\n");else {
2023-12-02 16:45:42
1161
1
原创 关于C语言中的分支知识讲解
括号里的表达式如果成立,则会执行下面的语句,如果不成立,则不执行C语言中成立就为真,不成立就为假,1为真,0为假,所以表达式里如果是1则会执行下面语句,如果是0则不执行下面是使用if语句判断是否为奇数。
2023-11-27 19:09:28
1231
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人