自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 网络编程及原理(三)

同样,我们想要从文件中读写 100 个字节,我们可以一次性读写 100 个字节,也可以分 2 次,每次读写 50 个字节,也可以分 10 次,读写 10 个字节。对于字节流来说,也就是传输数据是基于 IO 流的,流式数据的特征就是在 IO 流没有关闭的情况下,是无边界的数据,可以多次发送,也可以分开多次接收。UDP 的特点:无连接,不可靠传输,面向数据报,有接收缓冲区,无发送缓冲区,大小受限,一次最多传输 64 k, 全双工。原始套接字用于自定义传输层协议,用于读写内核没有处理的 IP 协议数据。

2025-06-06 19:16:04 409

原创 网络编程及原理(二)

在传输层构造好数据后,就会继续调用网络层提供给传输层的 API ,将数据进一步交给网络层,(由于传输层和网络层都是在系统内核中实现好的,上述的调用过程咱们无需关心,也感知不到)网络中也有很多种协议,其中最主要的就是 IPv4 协议,简称为 IP 协议(当前有 IPv4 和 IPv6 ,但在目前, IPv4 仍然是占据主导地位)得到上述的数据包,需要进一步交给物理层(硬件设备),我们的网卡就会针对上述的二进制数据进行真正的传输,需要把上述 010101 这样的序列,转化为光信号 / 电信号 / 电磁波。

2025-06-05 16:18:20 886

原创 网络编程及原理(一)

计算机之间的传输媒介是光信号和电信号,通过 “ 频率 ” 和 “ 强弱 ” 来表示 0 和 1 这样的信息,那么我们想要传递各种不同的信息,由于我们计算机生产厂商有很多,计算机的操作系统也有所不同,计算机的网络硬件设备也是各式各样的,为了让这些不同厂商之间生产的计算机能够互相顺畅地进行数据通信,就需要提前约定好双方的数据格式,不然收到数据怎么解析的懂呢?比如现在以太网通过的网线(双绞线)、早期以太网采用的同轴电缆(现在主要用于有线电视)、光纤,现在的 WiFi 无线网使用电磁波都属于物理层的概念。

2025-06-04 14:14:09 1010

原创 多线程(八)

这就相当于 “ 悲观锁 ”。在上面 “ 乐观锁与悲观锁 ” 例子的基础上,这就例如我们还有一个同学 C ,他也想问老师问题,他最开始就认为老师比较闲,就直接去找老师,但找了几次之后,都发现老师一直很忙,于是下次再来找老师之前,他也就发消息问一问,确定老师忙不忙,这就是 “ 自适应锁 ”。首先我们来了解一下常见的锁策略,这些分类将各式各样的锁分成了不同的类型,但值得注意的是这些类型并不是指的单一特定的锁,而是一个更广义的概念,所有的锁都可以往这些策略中套,我们根据锁的不同属性来将其定义为下列这些锁。

2025-05-22 19:15:57 987

原创 多线程(七)

而我们的 wait 不一样,在我们的 schedule 添加任务的方法中,我们在添加任务的时候会进行 notify 操作,也就是说当我们使用 wait 的时候,在添加了新任务时,wait 就会被 notify 唤醒,而不至于在 wait 的过程中察觉不到新任务的添加。在我们一开始,队列为空的情况下,我们程序一进入 while 循环,加锁,然后判断队列是否为空,队列为空,continue 跳转到下一次循环,再加锁,再判断,又为空 . . . . . .且我们的下面的 wait 操作也可能触发线程阻塞。

2025-05-21 18:05:07 668

原创 多线程(六)

所以我们就一提或者一箱一箱的买。线程池就是将线程提前从系统中申请好,共同存到一个地方,后续有需要使用该线程的时候,就直接到这个地方来取,而不是系统重新申请,将线程用完了之后,也还是放回到原来的地方。实现线程池其实很简单,我们这也是一个很基础很简单的线程池代码案例,其核心操作原理就是借助我们的一个阻塞队列来进行我们任务的交换,一边来添加任务,一边来获取任务并执行。注意:CPU上的核心数目是有限的,且核心线程会始终存在于线程池的内部,而非核心线程,在繁忙的被创建出来,不繁忙了,在空闲时候就会把这些线程释放掉。

2025-05-20 19:42:18 919

原创 多线程(五)

如图,此时我们的 size 为 0,本来应该阻塞等待,但是这时因为某些原因被唤醒了,此时我们并不能够捕捉到异常,而是代码继续执行下去,而由于我们的 size 为 0 ,继续执行下列操作,就很可能会出问题,即使我们能够成功返回一个值,那也是一个看起来 “ 正确 ” 实则 “ 错误 ” 的值。但是偶尔也会有卡顿的时候,那就是我们擀好的饺子皮一般会放在桌子上的一个盘子里,如果我们包饺子的速度快于擀饺子皮的速度,那当盘子中的饺子皮包完了,我们就只能等,等到新擀好的饺子皮放到盘子中的时候,我们才能继续开始包饺子。

2025-05-19 15:10:12 777

原创 多线程(四)

在我们软件开发中也有很多常见的套路,一些 “ 问题场景 ”,针对这些特定场景,我们的程序员大佬们,前辈们总结了一些固定套路,通过这个套路来公式化的实现代码,就是 “ 最优解 ”。程序一启动,我们的 Singleton 这个类就加载了,类一加载,我们类成员的初始化就完成了,这里的实例创建的非常迫切,也就是我们的 “ 饿 ”,所以就叫做我们的 “ 饿汉模式 ”。,比如打篮球,踢足球,做数学题,下棋等等,在某个特定情况下,我们直接使用一些套路化,公式化的应对措施,就是解决当前问题的最优解,这就是设计模式。

2025-05-16 17:16:01 1301

原创 多线程(三)

这就好比如一个悲伤的故事,在学生时代,有一对男孩女孩互生情愫,但都是暗恋,等到即将毕业前,女孩在送给男孩的一本书里偷偷夹了一封信,已示告白,但是粗心大意的男生并没有发现,直到多年后,男孩偶然间翻开这本书,这才发现这封已经泛黄的告白信,但此刻时光荏苒,物是人非事事休咯,这就是错失的遗憾。,我们打球肯定不是说每个球员都想着抢球投球,要想赢得一场漂亮的比赛,咱们肯定是要执行战术的,每个人都有自己的位置,什么时候谁持球做什么,这都是很严谨的。(1)wait 是用于线程之间通信的,sleep 是让线程阻塞一段时间。

2025-05-14 17:30:13 857

原创 多线程(二)

一 . 前台线程与后台线程今天先来了解一个上一期的遗留概念 —— 前台线程与后台线程一 . 前台线程与后台线程大家应该多多少少都听过酒桌文化,咱们平常吃饭,座位次序是没有那么多讲究的,但是在跟领导吃饭,或者出席宴会和一些重要场所的饭局时,这个座位次序,朝向都是非常有讲究的,那么通过酒桌文化这个例子,我们就可以生动形象的描述出前台线程与后台线程关系前台线程与后台线程的概念如果某个线程在执行过程中,能够阻止进程结束,该线程就被称为 “ 前台线程 ”。如果某个线程在执行过程中,

2025-05-13 18:15:22 848

原创 多线程(一)

例如:当我们过年的时候,我们就会吃饺子,要吃饺子呢,我们就需要包饺子(不知道各位平时是怎样吃饺子的啊,我们家一般都是自己包),包饺子就涉及到三个基本的步骤,要饺子皮儿,饺子馅,最后包饺子,如果我们想要包100个,200个饺子,那么我们一个人包就需要很多时间,并且可能在三个过程中不断地往返,导致我们效率低下,这就相当于。那么这个时候,我们最合适的做法就是,叫爸爸妈妈和家里人来一起,每个人分配一项工作,例如妈妈负责擀面皮,我负责拌饺子馅,爸爸负责包饺子,通过这样的协同作业,我们的效率就会高很多,这就相当于。

2025-05-12 19:47:24 1173

原创 Java EE 计算机的操作系统

并不是我们的线程数目越多就越好,当我们线程数目达到一定的临界值的时候,将每个核心都已经充分利用完全了之后,此时我们若是再去增加线程,就无法再提高效率了,甚至呢,有可能还会影响我们原有的高效率。(假设是单CPU单核的计算机)操作系统对于 CPU 资源的分配,采用的是时间模式 —— 不同的进程在不同时间段去使用 CPU 资源。(内存、硬盘、网络宽带等等),内存资源是代码中定义的变量 / 对象,在我们的编程中,多个线程是可以共用同一份变量的。因为我们这个线程调度也是有一定会消耗的是吧,这一点大家能懂吧。

2025-04-27 19:45:30 526

原创 动态内存管理

序言哈喽啊各位,时隔多日咱们又见面了。又到期末了昂,所以呢时间实在是很紧,除开学校的时间呢,又由于自己还要抽时间看课,所以博客就更新的很缓慢啦,还望诸君见谅。今天得空呢,就来为大家整理一期有关于动态内存管理的博客这应该是我关于C语言正期的最后一期了昂,零零散散的为诸君总结的C语言的知识点也涵盖了绝大部分了,如果我总结的这些知识点能为诸君加深对一些知识点的理解以及解决到大家的一些困惑,能够帮助到大家,我当然是不甚荣幸的。

2024-12-14 19:29:50 853

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

我们创建一个整数 a 并赋值为 1,1 在内存中的存储是十六进制,应该是 01 00 00 00,我们函数中取 a 的地址,取到的地址就应该是这一段的起始位置,由于我们只需要判断第一个字节,若是1,那就为我们的小端字节序存储,是 0 的话就应该是大端字节序存储,所以我们接收后强转为 char* ,只访问第一个字节,再解引用,再判断即可。衬衫要有设计、颜色、尺寸。我们为赋值的部分还是从 0 开始的默认值,有赋值的就是赋的值,若是中间有一个是赋值的,那么下面的变量就在该值的基础上每次递增 1。

2024-12-01 17:31:24 885

原创 自定义类型:结构体(三)

跟我们之前学习的结构体的自引用一样,我们结构体的大小是不固定的,跟里面的成员相关,可能很小,占用几个字节,可能很大,这个时候我们使用传址调用的话,前面在 sizeof 的部分讲到过,下图是网络协议中,IP数据报的格式,我们可以看到其中很多的属性只需要几个 bit 位就能描述,这里我们使用位段,能够实现我们想要的效果,也可以最大程度的节省空间,这样我们的网络传输的数据报大小会相对小很多,对网络数据的通畅有很大的帮助。总结:函数在传参的时候,参数是需要压栈的,会有时间和空间上的系统开销;结构体的位段是什么呢?

2024-11-18 19:08:40 923

原创 自定义类型:结构体(二)

是不是 int —— 4,那么 8 正好是 4 的整合倍,符合结构体对齐原则的第三条,所以最终我们s1 的大小就是 8。s2中,第一个是 char 类型,那么我们直接占用第一个字节位,接下来的变量 b 是 int 类型,应该占 4 个字节,又因为 4 比我们的系统对齐数 8 小,则我们此时的对齐数就是 4 ,那么根据第二条规则,我们这个 int 占用空间的起始位置就应该从 4 的整数倍位置开始,所以我们 int 就应该从 4 的位置开始,接下来就跟 s1 中同理了,最后得出,我们 s2 的大小应该为 8。

2024-11-17 19:44:18 687

原创 自定义类型:结构体(一)

由图可见,我在进行结构体的初始化时,用力两种方法,一种是我们正常的初始化,这个初始化必须是严格按照我们创建结构体成员列表时的顺序一对一进行初始化的;虽然我们两个结构体中的类型和成员一模一样,但是由于是匿名结构体,在系统看来这两个结构体的类型是不相同的,编译器会把上面两个声明当成完全不同的两个类型,所以这种操作是属于非法的。结构体的自引用,听到这个概念,我相信大多数小伙伴都会想起我们的函数递归之类的,没错,结构体的自引用就跟我们之前学过的函数递归是有着异曲同工之妙的。,我们的结构体便是由这三个部分组成。

2024-11-07 21:16:35 777

原创 数据在内存中的储存

二 . 浮点数在内存中的储存今天我们来深入了解一下各项数据在内存中的存储一 . 整数在内存中的存储这个众所的周知昂,咱们之前在讲解操作符的时候提到过一嘴,整数在内存中的存储形式——那就是以二进制的形式储存,记不清也没关系,很简单,咱们今天一起来回顾一下:整数的二进制表现形式有三种:原码、反码、补码。有符号的整数,三种表现形式均分为和两部分,符号位都用 0 来表示 正 ,用 1 来表示 负。而正负数的原、反、补是略有差异的:(1)正负数原、反、补的差异。

2024-10-26 18:14:42 1332

原创 C语言中的内存函数

的,我们虽然是用整型举例,但我们实质还是模拟实现 memcpy 函数,我们不能只用整型,也得遵循 void * 类型的接收返回,我们这里虽然是整型类型,但是朋友们请注意了,我们在赋值时用的是 char * 的强转,为什么不用 int * 强转呢?有的同学坚信实践是检验真理的唯一标准昂,自己去试了一下发现没有问题啊,怎么这样说呢,那是因为我们特殊的编译环境,VS上的库函数 memcpy 也能实现重叠内存的拷贝,但并不是所有编译器上都能实现,可能在其他编译器就跑不动了呢?

2024-10-21 18:57:24 1086

原创 字符函数和字符串函数(三)

所以我们在比较移动的时候不应该直接对 str1、str2 进行移动,而是在一开始就创建两个新的指针变量,用这两个代替 str1、str2 移动,并且还需要再创建一个指针变量,因为我们对比到第一个相同字符的时候需要在这个位置留下一个指针,如果全部匹配成功,它就作为我们的返回值。注意:一般来说,我们函数中创建的一个东西,出函数就会销毁,但是这个strtok函数,会记住我们上一次运行时的起始地址,出函数不会直接销毁,下一次依然可以读取,这就说明我们这个strtok函数中大概率是有。,所以我们这样子去判断。

2024-10-20 21:35:53 987

原创 字符函数和字符串函数(二)

大家在后续自己的测试中可能会想到这样一个问题:我们每次比较返回的结果,大于就是 1 ,小于就是 - 1 ,等于就是 0 ,没有出现过其它数字,跟我们C语言概念定义的不一样,这是为什么呢?提到字符串大小的比较,大家可能第一时间想到的是长短的比较,其实不然,如果是长短的比较那就太片面了昂,长短一样的情景很多,接下来又该如何进行区分呢?,其他的没什么好说的了,跟上面 strcat 的原理如出一辙,如果有看不懂的部分,大家再去上面翻翻看昂,咱也就不过多赘述了。并不是的,通过调试可以看到,我们的。

2024-10-20 20:22:56 993

原创 字符函数和字符串函数(一)

思路分析:我们在自己的 My_strlen 函数中首先设立一个新指针 ptr,将我们的原字符串起始地址赋给我们的ptr,然后让我们的 ptr 去想计数器那样一位一位的移动,直到遇到 ‘ \0 ’ 停下来,然后。如上图,我们给出了一段有大写有小写的字符串,我们需要对这段字符串中的小写字符转化为大写字符,原本是大写的或空格则保留。在我们的C语言中有着这样一系列函数是专用于字符分类的,这里为诸君举例一些,并且注意,这这些函数的使用都需要包含一个相同的。当然是可以的,之前就提到过我们C语言中也有一个霸总——

2024-10-14 19:02:10 626

原创 指针 (八)例题深度解析

有的小伙伴看到二维数组的形式就怕了,不要怕嘛,这些都是纸老虎,经过我们上一道题的解析,再来看这个不也是一样的原理么:c p p [ -1 ] [ -1 ] == *(*(c p p - 1)- 1),我们此时的 c p p 可还是指向的 C + 1 的位置,因为第三次打印不是自加或自减的形式,其运算过程并不会对其本身造成改变,所以先 - 1 指向了 C + 2 的位置,再 - 1 得到 C + 1,然后再解引用找到我们 c 中 N 的地址,再 + 1 跳过一个字节,所以最终打印结果为:EW。

2024-10-09 21:38:48 956

原创 sizeof 和 strlen

这个是我们的老朋友了昂,经常都在使用,它是专门用来计算变量所占内存空间大小的,单位是字节,当然,如果我们的操作对象是类型的话,计算的就是类型所创建的变量所占内存的大小,注意,它与这个变量的本身大小没有任何关系,sizeof 只关注内存空间的大小,不在乎内存中存放的什么数据。(有关于库函数的概念我就不说了昂,都是老生常谈的概念词了)其功能是求字符串长度,只能针对字符串(字符数组)二维数组在内存中的储存实际上是一段连续的空间,并且我们可以将其分段看做是由一个个一维数组组成的。我们再来回顾一下,在一般情况下,

2024-09-28 14:38:17 450

原创 指针 (七)

我们之前讲过的哈,就是说为了使用统一和便利,人们把一些常用的函数直接实现并放在库中,我们需要的时候可以随时调用。只要理解到了是将我们需要调用的函数将其地址作为参数传递给另一个函数,回调函数这一点就显得很简单了,诸君都是聪明人昂,我就不过多赘述了。在我们排序结构体数组之前,我们先来认识一个函数 —— strcmp,我忘了之前讲没讲这个函数了昂,没事儿,现在我们再一起回顾一下嘛。我们之前讲过的哈,就是说为了使用统一和便利,人们把一些常用的函数直接实现并放在库中,我们需要的时候可以随时调用。

2024-09-22 20:56:49 852 1

原创 指针 (六)

诸君可以想一想,我们什么时候需要对类型进行重命名呢?当我们的一个函数指针类型非常冗长、复杂,且我们还需要反复调用时,我们是不是就可以对这个函数指针类型进行一个重命名,将其简化呢?由此可见,我们的函数是的的确确有地址的,并且其性质可以说跟我们的数组一样,函数的地址也就等同于函数名。有图可知,我们经过上面的几个例子,习惯性的将新类型名放在最后,其实我们仔细观察可以发现,,而未来当我们需要时,就可以通过存放的这个地址我们就可以调用该函数。这样子简单,但是很低端,不够高级昂,太繁琐,我们的。

2024-09-17 21:04:07 579

原创 指针 (五)

所以,我们根据数组名是数组首元素地址这个原则,二维数组的数组名就表示第一行的地址,是一维数组的地址,那么在上面的例子当中,第一行一维数组的类型就是 int [ 5 ] ,所以第一行的地址类型就是 int ( * ) [ 5 ] ,那就。当然是有的,我们将二维数组看做是每个元素是一维数组的数组,也就是二维数组的每个元素都是一个一维数组,那么二维数组的首元素就是第一行,是一个一维数组。我们的 p 会先和 * 结合,说明 p 是一个指针变量,然后指针指向的是一个大小为 10 的整形数组。

2024-09-10 20:59:57 317

原创 冒 泡 排 序

这就很浪费我们的时间。针对于这一点,我们可以做出一点小小的优化(以上就是我们初步完成的冒泡排序,大家不难发现,今天咱们单独拎出一小节来聊一聊冒泡排序昂。(理解思路诸君可看下图)

2024-08-21 18:13:58 226

原创 指针 (四)

上图就是传值调用,看似没有问题,但我们的运行结果却出乎了我们的意料,a、b 的值并没有按照我们预想的那样交换,这是为什么呢?众所周知,指针变量那也是变量,是变量就有地址,我们指针本身就是指向一个地址的,那么它本身作为一个变量而言,它的地址又存放在哪里呢?在上方两个调试的图中,我们可以看到,在我们的 Swap1 中,的的确确是将我们的 x、y 的值进行了交换,但是我们也可以看到,,这就证明,a、b 和 x、y 有着本质上的区别,我们改变的是在 Swap1 中的 x、y ,并不是我们想要改变的 a、b(

2024-08-20 21:14:24 848

原创 指针 (三)

如图,这段代码的意义就是:我们先进入到 main 函数当中,创建一个指针 *p ,这个 *p 就是 test 的返回值,然后哦我们进入到 test 函数当中,创建一个变量 a 并给其赋值为 100 ,然后返回 a 的地址,再次回到 main 函数当中,打印 *p ,按理说我们应该是通过 *p 的地址找到 a ,最后打印出100,这看起来好像并没有任何问题,但是请大家注意, test 这里的 a 是一个局部变量,进函数创建,出函数销毁,我们并不能通过 test 的返回值打印出 a。

2024-08-19 22:32:06 1534

原创 指针 (二)

从我们打印出来的地址可以很清楚地看到,char * 类型的指针变量 + 1 就是跳过 1 个字节,- 1 就是退后 4 个字节,而反观 int * 类型的指针变量 + 1 就是跳过 4 个字节,- 1 就是退后 4 个字节。,除非像图2中那样使用强转(强制类型转换),当然我们之前也提到过的是吧,强扭的瓜不甜,我们不到万不得已,应该避免使用强转,养成良好习惯是吧。我们知道,变量变量,就是因为他是可以改变的量,当我们把变量的地址交给一个指针变量,通过这个指针变量我们也可以对该变量进行改动,但是当我们。

2024-08-16 11:23:40 790

原创 指针(一)

比如说我们在宿舍或者家里点外卖,我们肯定会给外卖员一个详细地址包括我们的门牌号是吧,不然外卖员挨个挨个房间去找,效率是不是就非常低了,但当我们给到他一个非常详细的地址,例如一栋二单元202这样子的。),&a 取出来的是 a 所占 4 个字节的地址,虽然整型变量占了 4 个字节,但我们只要知道了第一个字节的地址,就可以顺藤摸瓜访问到 4 个字节的数据。在我们的日常生活中,我们把门牌号叫做地址,在计算机中我们将内存单元的编号也叫地址,在我们的C语言中,将。

2024-07-07 20:46:38 774

原创 结构体(二)

在我们的结构体中,包含一个类型为该结构本身的成员是否可行呢?我们可以看出VS系统已经检测出并自动报错了,这是为什么呢?这样做答案是否定的,因为我们需要考虑一个顺序的问题,今天来继续介绍我们有关结构体的相关知识。另外呢,在我们的结构体自引用的过程中,

2024-06-26 19:43:32 261

原创 结构体 (一)

例如:char 、short 、int 、long 、float 、double 等等,但是呢,仅仅只有这些内置类型是远远不够的,当我们想要描述一名学生,一本书,一件商品时,这时候单一的内置类型就很难办到了。,例如我们想要描述一名学生,我们要在结构体中写出这名学生的姓名、性别,身高、体重、年龄、学号、成绩等,这些值就被称为。上面的两个结构体在声明的时候就省略了结构体的标签(名字)tag。(结构的每一个成员可以是不同类型的变量,甚至是其它结构体)有时候我们得到的不是一个普通格式的结构体,而是一个。

2024-06-24 20:42:38 426

原创 C语言中操作符详解(二)

优先性指的是,如果一个表达式包含多个运算符,我们就应该依照操作符的优先性来判断哪一个运算符优先执行,(大部分运算符都是左结合(从左到右),少数是右结合(从右到左)例如赋值运算符:= )、+ 、- 、++ 、-- 、* 、& 、~ 、sizeof 、(类型)(1)& :按位与(同为 1 才为 1 ,否则为 0 )(4) ~ :按位取反( 0 变 1 ,1 变 0 )(3) ^ :按位异或(不同为 1 ,否则为 0 )OK,今天继续为诸君带来有关C语言中操作符的讲解。(2) | :按位或(有 1 就为 1 )

2024-06-23 15:10:07 686

原创 C语言中操作符详解(一)

以上为诸君罗列了一些在C语言中我们常用的操作符,在此之前,我们已经介绍过了算术操作符、赋值操作符、逻辑操作符、条件操作符和一部分单目操作符。众所周知,在我们的C语言中有着各式各样的操作符,并且在此之前呢,我们已经认识并运用了许许多多的操作符,都是诸君的老朋友了昂。在讲操作符之前呢,我们需要铺垫一下,所以我们先来认识一下C语言中的原码、反码、补码。,在二进制序列中,最高位的 1 位是被当做符号位,剩余的都是数值位。众所周知,计算机用的都是二进制运算法,而在我们的计算机系统中,,得到的32位数就是该数的原码。

2024-06-21 22:21:45 937

原创 函数递归

当我们求第 n 个斐波那契数的时候,它是不适合用递归的方式来求解的,这个时候就有小伙伴要真诚地发出疑问了:这是为什么呢?如图,我们要通过递归计算第50个斐波那契数,这是一个倒序的运算过程,我们先要知道第49位的数和第48位数,我们要知道这两位数我们又得先知道第48,47,47,46位,以此类推......运用了迭代的方式,没有了冗余的计算,咱们的运算效率就高得多昂,即使是50也是秒出答案。在我们的C语言中,“ 递归 ”是我们相当重要的一环,简而言之,斐波那契数列是什么呢?

2024-06-17 14:55:34 624

原创 Visual Studio 的调试

大家调试一个程序,我们首先是要承认出现了问题,然后我们通过一些手段去定位到问题,可以是逐过程的调试,也可以是隔离和屏蔽代码的方式,当我们找到问题的所在,再确定了问题产生的原因,我们就可以去修复代码了。除此之外,在我们的调试的窗口中还有:自动窗口,局部变量,反汇编、寄存器等窗口,我这里就不一 一为大家赘述, 诸君感兴趣的话可以自行去搜集影视资料学习。:可以在程序的任意位置设置断点,打上断点就可以使得程序执行到想要的位置暂停执执行,接下来我们就可以使用F10,F11这些快捷键,观察代码的执行细节。

2024-05-26 18:02:34 1234

原创 函数 (三)

现阶段我们还处于一个学习的阶段,还是初期,我们写的代码都很简单,简洁。若是以后我们出身社会了,工作了,一般在企业中我们当码农的时候,那时候需要我们写的代码就比较繁杂了。这个么,当然也是可以滴,咱们兵来将挡,水来土掩,前辈们早已为我们想好了解决方案,那就是——存储在静态区的变量和全局变量是一样的,生命周期就和程序的生命周期一样了,只有程序结束,变量才销毁,内存才回收。如图:我将声明单独放在头文件中,将函数的实现放在一个源文件中,将函数的调用放在一个源文件中,诸如此类,相信这点诸君不难理解。

2024-05-21 09:43:55 1284

原创 函数 (二)

中华文字博大精深昂,一个词肯定是由它代表的意义命名的,所以从我们“ 形式参数 ”这个字面意思不难理解,这个参数,仅仅只是一个形式而已,其实质就是:当我们定义了一个函数,但我们却不调用它时,这个形参只是一个形式而已,看得见,摸不着,不是真实存在的。我相信,绝大部分的小伙伴是没有做对的昂,这不怪大家,这是为什么呢?因此,我们返回一个“ 2 ”,再打印“ 2 ”,然后又因为 “ 2 ”是“ 1 ”个字符,又会返回一个“ 1 ”,再打印“ 1 ”,最终答案“ 4321 ”就是这么来的。

2024-05-18 10:02:38 1103

空空如也

空空如也

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

TA关注的人

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