- 博客(36)
- 收藏
- 关注
原创 15_Linux学习总结_进程程序替换
所以在刚在的代码中,可以现在父进程中调用putenv,然后子进程就可以进程父进程的环境变量。进程B是进程A的子进程,所以继承了进程A的环境变量,进程B调用了putrnv就可以把新的环境变量添加到自己的环境变量中(父进程是看不见这个新的环境变量的)传递环境变量时,新的环境变量就把老的环境变量给替换了(注意:子进程的环境变量即使被覆盖,也不会影响父进程的环境变量。进程C是可以看见刚刚B进程新添加的环境变量,这是因为进程C是进程B的子进程,所以进程C继承了进程B的环境变量。所以子进程可以继承父进程的环境变量。
2026-02-26 22:47:14
633
原创 14_Linux学习总结_进程等待
子进程退出时,内核会保留其退出状态等相关信息,以便父进程可以获取,因此子进程会先进入僵尸状态。因为父进程调用了 wait () 主动等待并回收子进程,所以子进程退出后会被立即清理,不会进入僵尸状态(Z 状态),因此无法通过 ps 查看到僵尸进程。:老明点了外卖,在送达前必须站在门口一动不动等 —— 不能玩手机、不能炒菜、不能做任何事,只能傻等,直到外卖员敲门(子进程退出),才能继续做其他事。结论:哪怕父进程不需要子进程的任何信息,也必须调用 wait()/waitpid(),这是保证系统稳定的基本要求。
2026-02-24 21:08:44
631
原创 13_Linux学习总结_进程终止
这是因为在 Linux 系统中,进程的退出码被限制在 0 到 255 之间(即一个无符号 8 位整数的范围)。当你返回的数值超过这个范围时,系统会自动对其进行 模 256 运算,只保留低 8 位的值作为最终的退出码。进程终止的本质就是释放系统资源,就是释放进程申请的相关数据结构和对应的数据和代码。当它出了些错误,考试结束后最终的分数为50.代表程序正常退出,但结果不正确。这里就直接把结论告诉大家,但进程发生异常时,该进程的退出码就没有意义。当进程的退出码为0时,代表进程正常退出。这里先写出来让大家看到)
2026-02-23 18:33:47
558
原创 12_Linux学习总结_进程地址空间(虚拟地址)
只有读的权限,没有写的权限。但看到 VMA 定义的代码段属性,才会觉得 “这块代码内存是只读的、能执行的”—— 前者是 “模拟空间大小”,后者是 “模拟空间内容”。哪怕这些区域暂时没有对应的物理内存,VMA 也会先把 “区域的存在和属性” 模拟出来,让进程觉得 “我的 4GB 空间里,这里是代码、那里是堆,都是实实在在的内容”。简单说:操作系统用 mm_struct 里的虚拟地址边界,给进程构建了一个 “4GB 内存的假象”,进程把这个结构体里记录的地址范围,当成了自己真正拥有的内存。
2026-02-16 18:39:52
625
原创 11_Linux学习总结_环境变量
(关于bash,大家可以去问一下ai是什么或者搜索相关文章,因为我写的这些文章目的只是自己用来复习,加强记忆的。比如输入 ls -a,bash 最终会向操作系统发起“执行 /usr/bin/ls,参数为 -a的请求,这也是为什么我们直接输入 ls -a 和输入 /usr/bin/ls -a 效果完全一致的原因。我们知道运行程序时必须知道这个程序的所在位置,所以我们运行test程序需要带上路径,为什么ls不需要带上路径呢?有了上面的过程,我们就可以知道命令行参数是让程序可以通过不同的选项实现不同的子功能。
2026-02-15 16:51:15
471
原创 10_Linux学习总结_进程优先级
现实中进程数是远大于CPU的数量。这样做的原因是,用户在修改优先级时,就不需要知道原来的优先级是多少。一个进程的优先级的数值越小,代表这个进程的优先级越高。现在我们试着把该进程的nice值设置成-100,理论上最终优先级应该是80 -100 = -20。为什么要有 NI ,这是因为用户无法直接对优先级进行修改,需要修改NI的值来间接的改变优先级。这是因为进程的最终优先级是优先级的默认值(80) + NI 的默认值(0)得出的。即使当前进程的优先级是90,但在修改优先级值都是从80开始加上nice值。
2026-02-14 16:06:36
417
原创 9_Linux学习总结_进程状态_僵尸进程_孤儿进程
所以当一个子进程结束时,代码和数据会被立即释放,但是该子进程的PCB不会立即释放,会先保留直到父进程从子进程的PCB中获取相关状态时,这段时间子进程就处于僵尸状态,此时子进程也被称为僵尸进程。这时候就需要D状态,如果该进程是D状态(不可中断休眠),该进程不受理任何杀死指令,操作系统和用户都无法杀掉该进程,只有等IO操作结束。但是上面说了,子进程退出后必须由其父进程获取其信息,不然子进程就会一直处于僵尸状态,子进程的PCB就会一直在内存中,造成内存泄漏。现在来看X状态,当进程结束时,进程就处于X状态。
2026-02-13 21:02:14
659
原创 8_Linux学习总结_进程
也就是给fork给父进程返回子进程的pid时,是因为父进程可能会有多个子进程,所以需要返回子进程的pid。这时候就需要PCB(进程控制块),PCB是一个结构体,里面包含着进程的属性,如 pid(唯一表示进程),优先级、代码地址、数据地址等属性。也就是有新的PCB。所以理论上最终结果就是先打印 “我是父进程,我的pid是:xxx”,然后父进程接着打印“我是进程,我的pid是:xxx”。现在来讲为什么fork函数需要给父进程和子进程返回不同的内容和是怎么给父进程返回一个值和给子进程返回一个值(返回不同的值)。
2026-02-12 21:19:01
565
原创 7_Linux学习总结_回车与换行
而我们现在键盘上的Enter键的功能就是回车+换行。先让光标移动到当前行的开头,在让光标移动到下一行。在C语言中进行格式化输出时会有符号 \n。该符号的功能包括了回车和换行。回车:让光标回到当前行的开头。换行:让光标移动到下一行。符号 \r 的功能就是回车。
2026-02-09 20:23:50
69
原创 6_Linux学习总结_自动化构建
这是因为编译器会对test.c文件进行检测,当用户对test文件没有进行修改操作,只是查看。只有在我们修改了test.c文件的内容后,test.c的修改时间会到mytest的修改时间之后。现在先写一个最简单的Makefile文件,Makefile文件需要依赖关系和依赖方法。现在我们能够生成可执行程序,既然可以生成可执行程序,那么也需要删除可执行程序才行。我们在进行编译文件时,不用向上面一步一步的编译,下面的指令可以一步到位。但现在我们还没有.o文件,所以需要通过依赖关系和依赖方法来生成.o文件。
2026-02-08 23:48:04
645
原创 5_Linux学习总结_vim
就可以先让光标移动到第三行,然后先输入6再输入yy。插入模式要切换到底行模式就必须先切换到命令模式,在从命令模式切换到底行模式。当前光标在第7行的开头,假设现在要把光标移动到第7行里面的第二个printf,使用l键向右移动就要连续按多次才能到第二个printf。比较麻烦,这时候就可以使用w。/输入内容:在底行模式下,输入斜杠/然后在斜杠的后面输入内容,会定位到有你输入内容的行的位置。输入之后,现在光标位置就在最底行,现在就是底行模式输入wq(保存退出,w:保存、q:退出)再加上回车就可以保存并退出该文件。
2026-02-07 21:06:11
698
原创 4_Linux学习总结_权限
而不是所属组,所以不能进行读操作。现在是超级用户(root),可以观察到 f2.txt 文件的拥有者是root,且拥有者的权限是rw-,那么理论上来说,超级用户(root)是不能查看f2.txt文件里面的内容。发现文件和目录都不能创建,这是因为对于dir1目录来说,普通用户cxy‘是其它用户,而其它用户的权限没有写权限,所以就不能在dir1目录下进行对文件和目录的操作。上面说过超级用户几乎不受权限的限制,所以超级用户相当于这个公寓的房东,可以自由的进出房间(目录),也可以改变房间里面的东西(文件)。
2026-02-06 19:42:33
630
原创 C++题目,数组中的第k个最大元素
这道题可以用priority_queue容器来解决,这个容器在初始化时是按照大堆来初始化的,所以priority_queue这个容器里面的值是从大到小排序的。题目来源:https://leetcode.cn/problems/kth-largest-element-in-an-array/description/题目中要取得第k个最大元素,那么只需要进行k - 1次pop操作,此时最大的值就是第k个最大元素,最后返回该值即可。
2026-02-05 16:07:13
67
原创 3_Linux学习总结_基础指令
比如现在要在dir3目录下通过输出重定向,向dir3目录下的test.txt文件内写入”hello Linux“(使用输出重定向,若没有这个文件则会创建这个文件)这样操作只能把zip文件解压解包到当前目录下,若想要解压解包到其它目录,要加上 -d 选项再指定目录。压缩的内容包括目录:把目录local及其里面的目录和文件打包压缩成local.zip。把test.tgz文件移动到other目录下,并解压解包test.tgz文件。(2)tar指令:将文件和目录打包压缩成.tgz文件或解压解包.tgz文件。
2026-02-04 21:14:04
388
原创 2_Linux学习总结_基础指令
从1号开始查询,1号里面有printf就显示1号里面的printf。上面说过Linux下一切皆文件,cat指令把目标文件显示在屏幕上,其实就是目标文件的内容写入到显示器文件里,所以我们可以看见目标文件里面的内容。——————————————————————分割线——————————————————————————————————————————————分割线——————————————————————————————————————————————分割线————————————————————————
2026-02-03 23:42:38
703
原创 1_Linux学习总结_基础指令
这里的..相当于上一级目录,也就是root,然后cd ../ef相当于是从abc的上一级目录下面的ef目录。前面我们使用cd -p指令创建了连续的目录/a/b/c/d,若我们想删除目录a,由于a目录下有b目录,b目录下有c目录,c目录下有d目录,在使用root账户删除时就会进行询问。注:ls指令也可以用绝对路径来显示所需目录下的目录和文件(为了演示,提前在abc目录下创建了edk目录和lac.text文件)现在在d这个目录下,然后使用cd /root进入root目录,此时目录d就是上一次进入的目录。
2026-02-02 23:35:02
763
原创 C++题目,两个数组的交集
根据上面的过程,我们选择set容器。因为set容器就是升序且内部不允许有相同的元素。先用nums1和nums2的迭代器分别初始化set容器。现在有两个数组,它们存储的值分别为{1、2、2} 和 {2、2、3}交集就是取这两个数组的共同元素。这两个数组的交集就是{ 2 }。题目来源:https://leetcode.cn/problems/intersection-of-two-arrays。交集就是取这两个数之间相同的值,我们这里可以遍历这两个数组来比较。
2026-01-26 11:28:27
125
原创 C++题目,最小栈
题目来源:https://leetcode.cn/problems/min-stack/description/逻辑是返回栈中最小的元素,_minStack的栈顶记录着最小的值,所以返回_minStack的栈顶即可。一个栈用来正常的存储数据。逻辑是,_minStack在出栈时需要判断出栈的值是否和自己的栈顶相同,相同就出栈,不相同就不出栈。这里只需要放回_stack的栈顶,因为_minStack的栈顶只是记录最小值。逻辑是_stack直接入栈,_minStack在为空时或入栈的值比栈顶小就可以入栈。
2026-01-22 20:50:28
264
原创 C++实现杨辉三角
上面的代码意思是给这些空的vector容器对象创建指定数量的 int 元素,并将这些新创建的元素初始化为 1,这里resize(i + 1 , 1)里面的 i 要加1的原因是,下标是从0开始的,vv[0]就是第一行,第一行一共有1个元素,所以这里需要加1,就能把vv[0]这个空容器的size(指有效元素个数)为1,并且初始化为1.当 i 为1时,代码就时vv[1].resize(1 + 1, 1),意思是,第二行这个空容器的size修改为2,并且初始化为1.第一行只有一个元素,第二行有两个元素。
2026-01-19 21:24:31
366
原创 C++ 类的定义
现在来写一个“人”的类public:void Init(const char* name, int age, int money)//初始化_age = age;void spendMoney(int spmoney)//花钱void earnMoney(int eamoney)//挣钱void print()//打印std::cout << "姓名:" << _name << std::endl;std::cout << "年龄:" << _age << std::endl;
2025-09-23 15:21:26
338
原创 C++缺省参数、函数重载
那么在调用时,如果没有传递参数,则会以设定的默认值进行相应的操作。C++支持在同一作用域中出现同名函数,但是要求这些同名函数的形参不同,可以是形参的个数不同,也可以是形参的类型不同。如果这个函数在定义时有参数,那么在调用这个函数时就必须要把对应的参数传入这个函数。上面截图调用本意是,给形参a、c、d、传入实参,形参b使用默认值,但是不能跳跃给形参,所以有问题。最后,在函数声明和定义分离时,缺省参数不能在函数声明和定义中同时出现,规定必须函数声明给缺省值。当有参数传入时,则会按传入的参数进行相应的操作。
2025-09-23 10:11:26
583
原创 单链表——合并两个有序链表
尾插先判断新链表是不是为空链表,若是空链表。若新链表不为空,则让newTail->next指向新链表并且让newTail指向尾结点即可完成尾插操作。创建一个新链表newHead,并用两个指针(l1、l2)分别遍历两个单链表(list1、list2)。定义一个新的链表,这个链表中有两个指针newHead和newTail,分别指向这个链表的头、尾结点。若l1指针先到达空指针,那么就说明list1里面的所有结点已经全部尾插到新的链表中。题目:将两个升序链表(list1、list2)合并为一个新的升序链表并返回。
2025-05-06 20:50:10
599
原创 单链表——寻找中间结点,快慢指针
当fast == NULL和fast->next == NULL时,slow指针正好指向中间结点。此时退出循环并返回slow结点即可。定义两个指针slow,fast。都指向head结点。slow指针每次自走一个结点。fast指针每次走两个结点。用while循环来实现这一过程。给你单链表的头结点,请你找出并返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。定义快慢指针slow和fast。本题使用快慢指针来解决。现在来用代码实现这一过程。
2025-04-28 20:41:15
219
原创 单链表——反转链表实现
也就说明了此时的指针n3指向的是NULL(就是最后一个结点的next是NULL)我们可以用三个指针n1、n2、n3,分别指向NULL,head,head->next。此时先让n1指向n2所在的结点,随后让n2指向n3所在的结点,最后让n3。最后需要注意的是,当传入的链表为空链表时。首先让n1指向n2所在的结点,随后让n2指向n3所在的结点,最后让n3。应该加上判断,当n3指向NULL时,不执行n3 = n3->next。给你单链表的头结点head,请你反转链表,并返回反转后的链表。用循环来改变指针的指向。
2025-04-28 19:30:04
318
原创 单链表元素移除题目
在新链表newList中,指针ptail始终指向该链表中最的后一个结点。当这个链表head的最后一个结点的val值与题目所给的val相同时且前一个结点val值与题目所给的val值不同时,最后一个结点就会被前一个结点带到新的链表中。题目:给你一个链表的头结点head和一个整数val,请你删除链表中所有满足Node.val == val的结点。最后还有一种情况需要考虑,就是但题目给出的链表中的结点中的val全都与题目给的val相同时的情况。这里选择用一个指针来遍历这个链表,和val不同的结点尾插到新的链表中。
2025-04-26 21:56:54
364
原创 C语言 数据结构 移除元素
当src指向的元素和val的值不同时,把src指向的元素赋值给dst指向的元素。直到src的值大于数组总的元素个数时,跳出循环。此时的dst的值就是这个数组剩下的元素个数。如:nums[] = {3,3,3,2}。val = 3,这个数组在删除val = 3时,还剩下一个元素2。现在有一个已知数组nums和一个值val。计算这个数组删除所有和val相等的元素后,还剩的元素个数。现在有个数组nums[] = {3,4,4,5}. val = 4。遍历这个数组,当src指向的元素和val的值相等时,src++
2025-02-19 18:51:03
233
原创 C语言数据结构 动态顺序表
动态顺序表是通过结构体来实现的。现在来思考一下。动态顺序表可以实现内存动态的调整。这里就要用到realloc。realloc的返回值类型时void*,所以在结构体中我们需要定义一个指针来接收realloc返回的指针。这里假设我们要存储int类型的数据。int* arr;现在定义了一个int*类型的指针来接收realloc返回的地址。顺序表除了需要接收地址的变量外,还需要两个变量,一个用来表示这个顺序表的容量大小,另一个用来表示顺序表内有效元素个数。int* arr;//用来表示容量大小。
2025-01-21 14:13:42
664
原创 C语言 旋转数组
reverse函数只需要对数组进行逆置,不需要返回值,所以函数的返回类型是void,需要把数组传给函数reverse,所以第一个参数是int * a,用来接收数组。但代码还是不够完善,我们上面的例子都是numSize大于k的情况,没有考虑numSize小于k的情况。我们就可以实现把numSize < k的情况转变为numSize > k的情况。我们只要不断的进行上面的步骤就可以完成逆置,显然是需要一个循环来进行多次操作的。我们可以发现左边旋转3次的效果和右边旋转1次的效果最终都是一样的。
2025-01-20 18:43:11
500
原创 C++ namespace介绍
在这句代码中,小伙伴可以发现有个符号" :: ",这个符号的名字是域作用符,它可以帮助程序找到对应域中的变量或函数等…比如说我现在要打印变量a,我们知道变量a在mm域中,我们可以使用域作用符mm::a。域mm在域hh中,我们用域作用符hh::mm::a。在不同域中可以定义相同的名字,在同一个域中不可以定义相同的名字。我们可以发现,报错了。using namespace hh来把hh域和全局域相同,但这里我们发现在全局域中定义了变量b。在这个代码块中,我们想要多次使用hh域中的a和单独使用hh域中的b。
2024-11-10 12:54:09
1059
原创 C语言 一元买一瓶水,两个空瓶子可以换一瓶水,用户输入钱数,返回总共可以换多少瓶水
当我们首次进入bottleNum()函数时,我们的total有m瓶水,m瓶水可以产生m个空瓶。这里我们需要注意的是,当我们用empty除以2的时候(两个空瓶换一瓶水),是有可能产生余数的,比如我们现在有3个空瓶,用两个空瓶换一瓶水,现还剩下一个空瓶。分别存放买水的个数和空瓶的个数.在我们把money传入bottleNum()函数时,比如我们传入的是9.那么现在我们可以花费9元来买9瓶水。而empty空瓶的数量是我们买多少瓶水决定的,我们买了m瓶水,即产生m个空瓶。水变空瓶,空瓶换水,不断循环。
2024-11-10 10:05:36
524
原创 C语言分别输入年份和月份,输出这个月有多少天
小伙伴这里会发现我在数组最前面加了一个元素0,目的是把每个月份往后移一位,使得数组中的天数下标可以正好和月份对应上.我们定义一个变量day.让这个变量接收days[m].(若没有在数组前面添0,这里写的是day = days[m - 1])最后return 变量day。由于最后需要输出这个月有多少天,所以getDays()函数的返回值类型为int.我们要输入年份和月份,所以这个函数的参数为两个类型为int 的形式参数,分别为y和m。在这道题中,我们可以写一个getDays()函数来完成我们的需求。
2024-11-04 23:49:03
986
原创 C语言二分查找,画图讲解
要想得到数组中间的下标,我们可以在定义两个变量left和right,给这两个变量分别赋值数组第一位元素的下标和数组最后一位元素的下标。2、mid所指向的元素arr[mid]大于num.此时的num在mid的左边,我们要缩小范围,让right移到mid左边一位,让mid重新指向新right和left中间的下标。1、mid所指向的元素arr[mid]小于num.此时的num在mid的右边,我们要缩小范围,让left移到mid右边一位,让mid重新指向新left和right中间的下标。可以快速的找到数字。
2024-11-02 15:36:01
884
原创 C语言猜数字游戏
由于时间一直在变化,time()函数返回的时间戳也是一直在变化,我们就可以把time()函数的返回值作为srand()函数的参数,这样就可以生成不同的种子。首先我们要生成1-100之间的随机数,我们用rand()函数生成一个随机的数,我们将这个数%100就可以得到一个在0-99之间的数,再加上1就可以得到一个范围在1-100之间的数。rand()函数是根据种子的不同来生成不同的数,所以这就是为什么说rand()函数生成的随机数是伪随机数了。,这样rand()函数生成的随机数就会不同。用if语句来进行判断。
2024-10-31 22:13:31
1438
原创 生成100~200之间的素数
进入第一个for循环i = 100,进入第二个for循环j = 2,开始执行第二个for循环的if语句 100 % 2 == 0.这个表达式的结果为True(真),所以100不是素数,此时我们把flag赋值0.用来表示这个素不是素数,并用break跳出第二个for循环。原理是,一个数若能写成两个因子相乘,那么这两个因子其中一个会小等于这个数的平方根,另一个数会大等于这个数的平方根。然后在进行是否能被整除的那一步其实不用生成2 ~(i- 1),只需要生成2 ~i的平方根。:只能被1和自身整除的数为素数。
2024-10-30 13:24:35
732
1
原创 C语言扫雷9*9,10个雷,简单版
/调用函数//注意,单个字符是单引号int x = 0;int y = 0;;//开始排查雷elseprintf("非法输入\n");可以理解成字符’0’代表48,字符’1’代表49。int x = 0;int y = 0;printf("请输入坐标:");win++;elseprintf("很遗憾,游戏失败\n");break;elseprintf("非法输入\n");////////////////这里这里,看见了吗。
2024-05-08 21:37:29
960
2
原创 C语言分支与循环学习总结
满足条件,开始第一次循环,打印“我是猪”,然后执行i++;先从表达式中得到一个结果,用这个结果和case中的常量表达式进行对比,若相同则执行语句,不相同则继续对比。此时 i = 5,与循环条件i < 5 进行判断,不满足循环条件,此时退出循环。这里的表达式时1,为真,则进行循环。由于a < b.为1 < 100.为真,则执行if里的语句,打印“我是猪”。由于这里的a > b是, 1 > 100,为假,则不执行if里的语句。首先判断条件是否为真,此时括号里的值为0,为假,即不会进行循环。
2024-04-14 20:20:47
1874
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅