- 博客(19)
- 收藏
- 关注
原创 动态内存管理
调整时你会遇到两种情况,一种是原空间后面的空间足够你要扩大的空间。另一种就是后面的空间不够你扩大,此时编译器就会连同你原来的空间都挪去一个新的空间中,以便存下你所需的空间。如果是第二种情况的话,你要注意它返回的就是新空间的地址,此时你就需要做一点点变化。就目前我们所掌握的方式来说,创建出来的空间都是静态的,且空间长度固定后就不能在调整了。这就是malloc创建空间的方式,它是不会初识化内存的。realloc的作用就是在你发现你创建的空间不够时,可以自己去调整原空间的大小,这样更方便一些。
2026-04-03 22:55:37
264
原创 自定义类型之-------联合和枚举
联合体的基本声明啥的和结构体是相似的,只有一个带你不一样,那就是来联合体是union来为关键字的!这里就是你char[9]占了9个字节,然后找最大对齐数,char的最大对齐数是1(这里不需要看它所占的字节数,只要看类型的字节数,所有是1),int类型就是4,所有此联合体的内存就应该对齐最大对齐数的整数倍,也就是12。这些成员也是可以有不同的类型的。你会发现三个地址其实都是一样的,这就验证了在联合体中的成员都是使用同一个空间的。的理解是:联合体的大小至少是最大成员的大小,要对齐最大对齐数的整数倍。
2026-03-29 17:03:16
215
1
原创 自定义类型 ------结构体
还有就是当你一个位段是5,下一个位段是7,那你第一个位段使用剩下的3的bit是继续使用呢?4.如果嵌套了结构体,那嵌套的结构体成员对齐自身的成员的最大对齐数的整数倍处。函数在传参时要压栈,如果压的是结构体的话,那开销就有点太大了,导致性能下降。在vs中的对齐数就是8,在linux中没有默认的对齐数,对齐数就是成员自身的大小。看这两个结构体的长度,就因为第二个把俩个小的字节放在了一起,所以就多节省了4个字节的空间。3.结构体总大小为最大对齐数(结构体每一个成员都有一个对齐数,取的是最大对齐数的整数倍)
2026-03-28 20:48:59
216
1
原创 数据在内存中的存储
以32位浮点数举例,存储的8位指数位其实是你先将浮点数转为二进制,所找出的指数,再加上127,就构成了存储指数E。本来是应该以1.01去存储的,但为了更高的精度,存储时就舍弃了第一位的1,从小数点后开始存储,不过后面读取时要记得加上1就行。其实就是将其不停的乘2,如果小于1的话,写0.如果大于1的话,就把1去掉,保留剩余的数字,继续乘2.直到最终的数为1。S代表的是这个浮点数的正负,当S为0时,为正,当S为-1时,为负。首先我们要明白的是在编译器中,整数的存储和浮点数的存储时不同的。
2026-03-24 20:58:51
343
原创 内存函数
跟之前学的strcmp和strncmp函数一样,如果p1大于p2的话就返回大于0的数,小于就返回小于0的数,等于就返回0。像图中,把绿色和红色的345就重合了,如果此时想直接使用memcpy传的话就会有错误,但使用memmove就不会。这里你若想将p2的传到p1的话是不是应该先传3到1的位置,此时是不是从p2前往p1前传才合理。所以和第一种情况是相似的。如果source和destination有任何的重叠,复制的结果都是未定义的。本篇博客到这就结束了,下一篇将讲解的是数据在内存中的存储,多谢大家的支持了。
2026-03-22 00:35:05
42
原创 字符函数和字符串函数
要注意的是:strtok操作的是临时拷贝的内容并且可修改,所以我们最好使用字符数组去使用。为了实现这种形式的话,我们是不是应该去创建一个新的字符指针来存储str1的首地址,这就是为什么要创建cur的原因。都是同样的道理,比较num前的字符,如果前大于后,就返回大于0的数。相反,就返回小于0的数。这个的模拟实现是有点复杂的,首先你要考虑它所包含的情况是含有3种的。字符分类函数的用法基本都是一样的,你要使用时,记得有这种函数就行。2.strlen计算的是'\0'之前的字符个数,但不包含‘\0’。
2026-03-20 09:23:21
329
原创 深入理解指针(四)
第一点就是在这个函数中我们使用的是void*去接收了数组,所以我们首先要想到要去强制转换数组的类型。上一篇博客我们写了计算机的代码,在未进行优化前我们的代码时十分的庸余的。首先要注意的第一个问题就是在初始化结构体时,要将其初始化为数组的形式,不要单独命名两个单独的结构体。因为我们是写代码的,所以我们知道自己要用的是int,但函数指针是不知道的。里面的->就是结构体的一个指向,它要求左边放的是结构体指针,而又右边要放的是变量名。其实不管qsort排序什么数组,其实大致流程都是一样的,就有一些小细节要改变。
2026-03-17 20:22:24
342
原创 深入了解指针(三)
所以根据数组名是数组首元素的地址这个规则,我们可以知道二维数组的数组名就是代表第一行的地址。所以第一行的地址可以认为是这样了int (*p)[5],这就代表了二维数组第一行的地址了。那我们的代码就可以写出来了。这里可能有人认为这是把abcd的地址都放在了a中,但是其实不是,它这里只放了首字符的地址。前面我们知道了函数指针变量,,那函数指针数组顾名思义就是由几个函数指针变量来构成的。这里经过调试你就可以发现,两者地址是相同的,说明我们初始化就完成了。你会发现,函数是有地址的,并且函数的地址就是函数名的地址。
2026-03-15 15:48:45
172
1
原创 深入了解指针(二)
这是没有经过优化的代码,但其实可以进一步优化一下,你想,如果你这个数组没排之前就已经排好了,那你在这样写是不是就会浪费来运行的时间呢?首先我们要搞清楚的是,指针数组是指针还是数组,结合我们前面所学,整型数组,字符数组这些,不难得出结论,指针数组就是一种数组。我们通过这种方法取到了此数组首元素的地址,但实际上数组本来的地址就是数组首元素的地址。其实也很容易去实现,只要你访问数组首元素的地址,后面进行循环就可以了。除这两个以外,其他任何地方的数组名都代表数组首元素的地址。看这个代码你会发现,两者其实是一样的。
2026-03-11 19:28:06
195
3
原创 深入理解指针(一)
就是无具体类型的指针。这种类型的指针可以用来接受任何类型的指针,但有一点不好的就是void*不能直接进行整数的加减和解引用的运算。这是因为函数传过去的只是个地址,而在函数那边接收时,形成一个假地址来接受你所传的地址,并且在函数中进行的调换也只是局部的有一个调换,而不会改变传过去的参。如果是在int*类型的情况下的话,int是整型,代表4个字节,所以当a的地址被改变时,它四个字节均会被改变。在右边的话就是,限制了p这个指针只能指向某一个指针,你可以去改变这个指针所指向的值,但不能改变其指针变量。
2026-03-10 20:15:46
623
原创 操作符详解
结构体的作用就是当你定义一个物品或人时,可能要用到多种类型,如:int,char等。我们要知道,电脑在处理程序的数字时,不是十进制的,二是先转化为二进制,在转成相对应的补码。单目操作符又有有这些:++,- -,&,+,*,-,~,sizeof。那在我们的生活中常常能听到二进制,八进制,十六进制的说法,说白了,就是一个数的不同表现形式。还有单目操作符,逻辑操作符,条件操作符,逗号表达式,下标引用,函数调用等。图中的1011是个二进制数,你只需从左往右,从2的0次方开始,逐渐使次方加1。0变为1,1就变为0。
2026-03-10 20:14:47
378
原创 函数递归
现阶段来说迭代就是循环,有些问题它是即能用迭代,也能用递归的。大家要记住一点就是:“因材施教”,不要沉迷于用递归,有时迭代好用过递归。看这个图你有没有发现其实后一个数的阶乘就是前一个数的阶乘乘这个数。题目是这样的:有一个青蛙,它一次可以跳一个或两个台阶,当有n个台阶时,它有多少种跳法?递归有时在我们写代码时会用到,也算是个重要的知识点了。想要明白递归,要牢记大事化小的原则,将一个复杂的东西简单化。如果你的递归未满足含有限制条件的话,会导致栈溢出。那现在的你是不是可以根据这个图来写出一个函数了。
2025-11-19 10:18:31
173
1
原创 数组与函数的应用(扫雷游戏)
这时就需要两个数组,一个来存储雷的位置,一个来表示坐标周围有几个雷,同时为了保持神秘,你可以将第二个数组初始化为‘*’。接下来我们就来到游戏的部分了!但我们还需注意一个地方就是,由于数组传参时,是要传行和列的,但是虽然我们用的是11*11的数组,但我们的雷和坐标都是放在9*9的格子里的。你是不是还没考虑到玩得人到时候怎么去选格子,所以我们是不是还应空一行来填写坐标,所以最终来说我们建的棋盘应是11*11的。这样整个游戏就结束了,当然你可以进阶,比如说,当一个格子周围都是0时,展开一片区域等。
2025-11-16 16:39:48
546
8
原创 函数(基本)
看我们前面的代码在main函数中,Add括号里的参数就叫作实参,上面的就叫作形参。如果一个函数能同时来调用两段代码,那也是可以的,提升了函数运行的效率。在使用函数时,不免会用到数组的情况,当我们将数组传给函数时,我们不仅要把数组本身作为参数传给函数,还要将数组中的每个数传给函数。这时你会发现main函数的字母和上面自定义函数的不一样,为什么可以这样呢,这就涉及到下面要讲到的形参和实参了。对于extern来说它的作用就是你在a文件中定义的变量,在前面加上extern后,就可以在b文件中使用了。
2025-10-31 10:19:54
566
4
原创 数组入门
下标就可以认为是元素所在位置减1,如果你有n个元素,那你最后一个元素的下标就是n-1;举个具体的例子:如果你的元素是1-5,那你的下标就是0-4,了解这个后我们就可以来输出数组中的数字了。它即可以计算数组的大小,也可以用来计算数组中元素的大小。这里理应存15个数,但只有3个数,那剩下的就用0来替代。如果说一维数组只是线的话,那二维数组你可以认为是一个平面,那既然是平面,那它就包括x轴和y轴。数组在创建时,我们需要给定一些初始值,一般来说是用{}来储存数据,若不写,则默认为0。看到这,是不是觉得简单。
2025-10-15 20:40:25
701
8
原创 分支和循环(上)
当我们有多个条件需要判断时,不可能用多个if...else...语句一直叠加吧,那就要用到接下来讲的if嵌套用法。break前面的switch语句中已经简单的介绍过,它的作用就是达到某个条件后,直接跳出这个循坏。这个新的语句与前两个有一点不同就是,它这个是先进入循环体,执行循环语句,再进行条件的判断。简单来说,就是能将真的变成假的,假的变成真的。如图,当你想在其中输入多个字符,也需要加入大括号,是不是觉得和if很相似了呢?此时就是当a,b同时满足条件时,才会输出2,只要有一个不满足,那就输出3。
2025-09-24 17:24:31
1075
2
原创 c语言的数据结构和类型
unsigned代表无字符,即它包括0,正数,但不包括负数。更长整型 (long long) (signed long long) (unsigned long long)scanf在读取用户输出值时,会自动忽略空白字符,空格,制表符,换行符。我们应明白sizeof是计算数据类型长度,不是字符长度,而8是属于long这个数据类型中,所以是4。printf作用就是输出数据,但你正常写时,如果你有两个输出值,那它是会输出在同一行的。接下来我们讲复合赋值符,顾名思义,将两个符号同时使用,对象为同一个变量。
2025-09-15 16:17:36
873
原创 c语言入门
明白这点后,我还应了解printf能打印多种类型的数据,前提是要弄清楚这些数据用什么占位符(后面介绍)只能说这是国际上的习惯,用别的数字也可以,但最好不用。就是来使字符串结束的,若没\0那计算机就会一值打印直到识别到\0。从名字上我们就应懂得字符串就是由多个字符组成的,字符串的打印格式就是。:d,d代表十六进制的数,转化为十进制后,用ASCII编码表来查找。但第一种也有好处,就是能选中一部分来注释。看图中函数,输入了hehe,那它输出也是hehe。注意的是0-31是打印不出的,打印字符时要加上。
2025-09-13 20:49:37
417
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅