自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(18)
  • 收藏
  • 关注

原创 C++:类和对象(上)

再分析⼀下,对象中是否有存储指针的必要呢,Date实例化d1和d2两个对象,d1和d2都有各⾃独⽴的成员变量_year/_month/_day存储各⾃的数据,但是d1和d2的成员函数Init/Print指针却是⼀样的,存储在对象中就浪费了。这⾥需要再额外哆嗦⼀下,其实函数指针是不需要存储的,函数指针是⼀个地址,调⽤函数被编译成汇编指令[call 地址], 其实编译器在编译链接时,就要找到函数的地址,不是在运⾏时找,只有动态多态是在运⾏时找,就需要存储函数地址,这个我们以后会讲解。

2025-09-26 12:00:00 1800

原创 C++:入门基础

在调⽤该函数时,如果没有指定实参则采⽤该形参的缺省值,否则使⽤指定的实参,缺省参数分为全缺省和半缺省参数。C++的引⽤跟其他语⾔的引⽤(如Java)是有很⼤的区别的,除了⽤法,最⼤的点,C++引⽤定义后不能改变指向,C++中为了避免引⼊太多的运算符,会复⽤C语⾔的⼀些符号,⽐如前⾯的<< 和 >>,这⾥引⽤也和取地址使⽤了同⼀个符号&,⼤家注意使⽤⽅法⻆度区分就可以。⼀些主要⽤C代码实现版本数据结构教材中,使⽤C++引⽤替代指针传参,⽬的是简化程序,避开复杂的指针,但是很多同学没学过引⽤,导致⼀头雾⽔。

2025-09-24 12:00:00 826

原创 数据结构:排序

希尔排序法⼜称缩⼩增量法。⾸先从右向左找出⽐基准⼩的数据,找到后⽴即放⼊左边坑中,当前位置变为新的"坑",然后从左向右找出⽐基准⼤的数据,找到后⽴即放⼊右边坑中,当前位置变为新的"坑",结束循环后将最开始存储的分界值放⼊当前的"坑"中,返回当前"坑"下标(即分界值下标)稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,⽽在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的;

2025-09-15 12:00:00 1333

原创 数据结构:二叉树

设⼆叉树的根结点所在层数为1,层序遍历就是从所在⼆叉树的根结点出发,⾸先访问第⼀层的树根结点,然后从左到右访问第2层上的结点,接着是第三层的结点,以此类推,⾃上⽽下,⾃左⾄右逐层访问树的结点的过程就是层序遍历。根结点的左⼦树和右⼦树分别⼜是由⼦树结点、⼦树结点的左⼦树、⼦树结点的右⼦树组成的,因此⼆叉树定义是递归式的,后序链式⼆叉树的操作中基本都是按照该概念实现的。在树形结构中,我们最常⽤的就是⼆叉树,⼀棵⼆叉树是结点的⼀个有限集合,该集合由⼀个根结点加上两棵别称为左⼦树和右⼦树的⼆叉树组成或者为空。

2025-09-13 12:00:00 1154

原创 数据结构:栈和队列

栈:⼀种特殊的线性表,其只允许在固定的⼀端进⾏插⼊和删除元素操作。进⾏数据插⼊和删除操作的⼀端称为栈顶,另⼀端称为栈底。概念:只允许在⼀端进⾏插⼊数据操作,在另⼀端进⾏删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out)队列也可以数组和链表的结构实现,使⽤链表的结构实现更优⼀些,因为如果使⽤数组的结构,出队列在数组头上出数据,效率会⽐较低。栈的实现⼀般可以使⽤数组或者链表实现,相对⽽⾔数组的结构实现更优⼀些。压栈:栈的插⼊操作叫做进栈/压栈/⼊栈,⼊数据在栈顶。

2025-09-10 10:00:00 202

原创 数据结构:顺序表与链表

1.线性表线性表()是n个具有相同特性的数据元素的有限序列。线性表是⼀种在实际中⼴泛使⽤的数据结构,常⻅的线性表:顺序表、链表、栈、队列、字符串...线性表在逻辑上是线性结构,也就说是连续的⼀条直线。但是在物理结构上并不⼀定是连续的, 线性表在物理上存储时,通常以数组和链式结构的形式存储。2.顺序表2.1概念与结构概念:顺序表是⽤⼀段物理地址连续的存储单元依次存储数据元素的线性结构,⼀般情况下采⽤数组存储。顺序表和数组的区别?

2025-09-07 20:00:00 977

原创 自定义类型:联合和枚举

上述的结构其实设计的很简单,⽤起来也⽅便,但是结构的设计中包含了所有礼品的各种属性,这样使得结构体的⼤⼩就会偏⼤,⽐较浪费内存。代码1输出的三个地址⼀模⼀样,代码2的输出,我们发现将i的第4个字节的内容修改为55了。所以我们就可以把公共属性单独写出来,剩余属于各种商品本⾝的属性使⽤联合体起来,这样就可以介绍所需的内存空间,⼀定程度上节省了内存。联合的成员是共⽤同⼀块内存空间的,这样⼀个联合变量的⼤⼩,⾄少是最⼤成员的⼤⼩(因为联合⾄少得有能⼒保存最⼤的那个成员)。联合体的特点是所有成员共⽤同⼀块内存空间。

2024-11-09 14:24:09 821 4

原创 自定义类型:结构体

⽽对⻬的内存访问仅需要⼀次访问。下图是⽹络协议中,IP数据报的格式,我们可以看到其中很多的属性只需要⼏个bit位就能描述,这⾥使⽤位段,能够实现想要的效果,也节省了空间,这样⽹络传输的数据报⼤⼩也会较⼩⼀些,对⽹络的畅通是有帮助的。4. 如果嵌套了结构体的情况,嵌套的结构体成员对⻬到⾃⼰的成员中最⼤对⻬数的整数倍处,结构体的整体⼤⼩就是所有最⼤对⻬数(含嵌套结构体中成员的对⻬数)的整数倍。仔细分析,其实是不⾏的,因为⼀个结构体中再包含⼀个同类型的结构体变量,这样结构体变量的⼤⼩就会⽆穷的⼤,是不合理的。

2024-11-02 15:21:37 1103 5

原创 动态内存管理

有时会我们发现过去申请的空间太⼩了,有时候我们⼜会觉得申请的空间过⼤了,那为了合理的时候内存,我们⼀定会对内存的⼤⼩做灵活的调整。当是情况2 的时候,原有空间之后没有⾜够多的空间时,扩展的⽅法是:在堆空间上另找⼀个合适⼤⼩的连续空间来使⽤。但是对于空间的需求,不仅仅是上述的两种情况。有时候需要空间大小在程序运行的时候才知道需要多大的内存,那数组的编译时开辟的空间就无法满足需求了。包含柔性数组成员的结构⽤malloc ()函数进⾏内存的动态分配,并且分配的内存应该⼤于结构的⼤⼩,以适应柔性数组的预期⼤⼩。

2024-10-06 13:04:50 1381 1

原创 数据在内存中的存储

但是,我们知道,科学计数法中的E是可以出现负数的,所以IEEE 754规定,存⼊内存时E的真实值必须再加上⼀个中间数,对于8位的E,这个中间数是127;具体的编译器),另外,对于位数⼤于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度⼤于⼀个字节,那么必然存在着⼀个如何将多个字节安排的问题。对于32位的浮点数,最⾼的1位存储符号位S,接着的8位存储指数E,剩下的23位存储有效数字对于64位的浮点数,最⾼的1位存储符号位S,接着的11位存储指数E,剩下的52位存储有效数字M。

2024-10-05 17:56:58 1364

原创 sizeof和strlen的对比

sizeof()函数是用来计算变量内存空间大小的函数,单位是字节。如果计算的是操作数类型的话,计算的就是类型创建的变量所占内存的大小。(sizeof()只关注内存大小,不在乎内存中存放的数据)。统计的是从strlen()函数的参数str中这个地址向后,'\0'之前的字符串个数。strlen()函数会一直向后找'\0'字符,直到找到为止,所以可能存在越界访问。3.关注内存中是否有'\0',如果没有就会继续向后寻找,可能会存在越界。2.srtlen是求字符串长度的,统计的是'\0'之前的字符个数。

2024-10-05 16:13:50 302 2

原创 深入理解指针(4)

因为截图的代码,只有调⽤函数的逻辑是有差异的,我们可以把调⽤的函数的地址以参数的形式传递过去,使⽤函数指针接收,函数指针指向什么函数就调⽤什么函数,这⾥其实使⽤的就是回调函数的功能。回调函数不是由该函数的实现⽅直接调⽤,⽽是在特定的事件或条件发⽣时由另外的⼀⽅调⽤的,⽤于对该事件或条件进⾏响应。上讲中我们写的计算机的实现的代码中,截图的代码是重复出现的,其中虽然执⾏计算的逻辑是区别的,但是输⼊输出操作是冗余的,有没有办法,简化⼀些呢?使⽤回调函数,模拟实现qsort(采⽤冒泡的⽅式)。

2024-09-15 16:54:17 576 6

原创 深⼊理解指针(3)

⾸先我们再次理解⼀下⼆维数组,⼆维数组起始可以看做是每个元素是⼀维数组的数组,也就是⼆维数组的每个元素是⼀个⼀维数组。所以,根据数组名是数组⾸元素的地址这个规则,⼆维数组的数组名表⽰的就是第⼀⾏的地址,是⼀维数组的地址。解释:p先和*结合,说明p是⼀个指针变量变量,然后指着指向的是⼀个⼤⼩为10个整型的数组。那要把函数的地址存到⼀个数组中,那这个数组就叫函数指针数组,那函数指针的数组如何定义呢?那数组指针变量应该是:存放的应该是数组的地址,能够指向数组的指针变量。

2024-09-06 16:02:46 867 4

原创 深入理解指针(2)

那么在数组传参的时候,传递的是数组名,也就是说本质上数组传参本质上传递的是数组⾸元素的地址。同理arr[i] 应该等价于 *(arr+i),数组元素的访问在编译器处理的时候,也是转换成⾸元素的地址+偏移量求出元素的地址,然后解引⽤来访问的。parr[i]是访问parr数组的元素,parr[i]找到的数组元素指向了整型⼀维数组,parr[i][j]就是整型⼀维数组中的元素。,这⾥的数组名表⽰整个数组,取出的是整个数组的地址(整个数组的地址和数组⾸素 的地址是有区别的)没错,这就是二级指针。

2024-08-31 14:22:10 833 2

原创 深入理解指针(1)

Swap1()函数时,将a和b传递给了Swap1()函数,在Swap1()函数内部创建了形参x和y接收a和b的值,但是x的地址是0x0118f7cc,y的地址是0x0118f7d0,x和y确实接收到了a和b的值,不过x的地址和a的地址不⼀样,y的地址和b的地址不⼀样,相当于x和y是独⽴的空间,那么在Swap1()函数内部交换x和y的值,自然不会影响a和b,当Swap1()函数调⽤结束后回到main()函数,a和b的没法换。在上⾯的代码中,将⼀个int类型的变量的地址赋值给⼀个char*类型的指针变量。

2024-08-24 22:12:52 1486

原创 C语言的内存函数

destination:指向要复制内容的目标数组的指针,类型转换为void*类型的指针。destination:指向要复制内容的目标数组的指针,类型转换为void*类型的指针。source:指向要复制的数据源指针,类型转换为const void*类型的指针。source:指向要复制的数据源指针,类型转换为const void*类型的指针。memset是⽤来设置内存的,将内存中的值以字节为单位设置成想要的内容。sum:需要复制的字节,size_t是无符号整数类型。ptr:指向要填充的内存块的指针。

2024-08-19 16:56:28 521 4

原创 <string.h>部分函数的使用和模拟实现

1.strlen。

2024-08-17 16:07:18 940 4

原创 扫雷游戏的模拟实现

继续分析,在棋盘上布置了雷,雷的信息(1)和非雷的信息(0),假设排查某一个位置后,这个坐标不是雷,但这个坐标周围有雷,那么需要将排查出雷的信息储存并打印出来,作为排雷的重要信息。判断是否进行展开的条件是这个坐标不是雷,且周围也没有雷的时候才会展开,如果周围有雷的话就计算周围雷的个数。假设我们访问(8,6)这个坐标时,访问周围8个坐标时会出现越界访问的情况,所以为了防止这种情况的发生,我们在设计棋盘时可以扩大一圈,将棋盘设计为 11*11 ,这样就避免了越界访问的问题。如果位置不是雷,就显⽰周围有⼏个雷。

2024-08-15 10:17:11 1334 7

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除