- 博客(1227)
- 资源 (1)
- 收藏
- 关注
原创 常用的数据结构及算法
优化方式二:将每个结点的孩子结点排列起来,以单链表作存储结构,则n个结点有n个孩子链表,如果是叶子结点则此单链表为,空。3)孩子兄弟表示法:任意一棵树,它的结点的第一个孩子如果存在就是唯一的,它的右兄弟如果存在也是唯一的。1)双亲表示法:通过静态数组的方式,存储当前结点的数据、双亲的位置(根节点的双亲结点设置为-1)。该方法的优点是容易找到结点的双亲结点,但是找结点的孩子结点就需要遍历。优化方式:除双亲的位置外,再增加一个长子域(最左孩子的位置),如结点无孩子结点,长子域设置为-1。链表常用的是单链表。
2024-04-17 14:20:53 386
转载 C++ 中在函数的前面加上static的作用
具有自动存储期的变量在进入声明该变量的程序块时被建立,它在该程序块活动时存在,退出该程序块时撤销。1.static变量:1).局部a.静态局部变量在函数内定义,生存期为整个源程序,但作用域与自动变量相同,只能在定义该变量的函数内使用。先看用来修饰变量的时候。使用内部函数的好处是:不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名,因为同名也没有关系。成员函数是属于类的,而非对象的,也就是所有该类的对象共同拥有这一个成员函数,而不是普通的每个对象各自拥有一个成员函数。
2024-04-09 10:13:20 29
转载 『算法』哨兵查找算法
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。然后,我们从后向前查找,如果和目标值相同,则结束循环,否则向前走。当下标为0时,会结束循环,因为0号下标是目标值;本篇博客介绍一下哨兵查找算法,哨兵查找算法是对顺序查找的一个优化。如果不同,则我们将0号下标元素先保存起来,然后将目标值放到0号下标处;最后判断index是否大于0,如果大于0表示找到了,否则就是没找到。首先,判断0号下标元素是否和目标值相同,如果相同,直接返回0;上述程序是一个典型的。
2024-04-09 09:53:25 15
转载 【Linux】SIGCHLD信号
这样的写法能够满足各种子进程退出的情况,假设创建10个子进程, 它们同时退出了,每个子进程退出都向父进程发送信号, 但是pending位图只能有一个比特位记录这个SIGCHILD信号, 如果只wait一次,那么只能读取一个子进程,剩下的9个就没被读到,所以设置while循环, 不等待指定一个子进程->所以参数设定-1循环式的把所有子进程退出都读取到。如果用阻塞,上述情况下,当我们读取第6次的时候, 如果子进程不退出就在信号捕捉这里卡住了,所以使用非阻塞等待可以防止程序卡住的情况。
2024-03-22 13:39:24 37
原创 递归的个人总结
func3函数返回了,继续执行func2中的语句;func2执行完了,继续执行func1之后的语句;从上图中可以看出,最后调用的函数先执行完(也是递归中回归的过程),即:this is func3先打印输出。可以按照如下来理解:func1中调用func2,func2中调用func3;递归函数(递去、回归)是函数不断的调用自己;
2024-03-22 13:03:58 435
原创 wait()、waitpid()函数的区别(个人总结)
首先使用wait()函数来回收多个子进程,我们可以在一个for循环中等待子进程的结束,创建了几个子进程就for循环等待几次,代码如下。waitpid函数,当第三个参数使用WNOHANG时,无子进程退出,也会立刻返回(返回值为0)waitpid函数的第三个参数设置为WNOHANG 时,返回值相较wait多了一种返回值,使用wait函数来循环回收子进程(wait函数是阻塞进程的),使用waitpid来循环回收子进程(不需要知道子进程的数量)wait函数会阻塞等待子进程的退出。使用wait()回收多个子进程。
2024-03-19 14:53:19 270
转载 Linux中wait()函数
如果参数status的值不是NULL,wait就会把子进程退出时的状态取出并存入其中, 这是一个整数值(int),指出了子进程是正常退出还是被非正常结束的,以及正常结束时的返回值,或被哪一个信号结束的等信息。请注意,如果进程不是正常退出的,也就是说, WIFEXITED返回0,这个值就毫无意义。函数功能是:父进程一旦调用了wait就立即阻塞自己,由wait自动分析是否当前进程的某个子进程已经退出,如果让它找到了这样一个已经变成僵尸的子进程,wait就会收集这个子进程的信息,并把它彻底销毁后返回;
2024-03-19 13:45:13 75
转载 wait()函数——子进程回收
如果进程是异常终止,则保存导致该进程终止的那个信号。回收子进程残留资源;为什么使用了waitpid()函数还会产生僵尸进程呢,这是因为在waitpid()函数中使用了选项参数WNOHANG,而子进程中有一个睡眠函数,子进程睡眠的时候,父进程中waitpid()语句没有等到子进程结束就执行了,由于WNOHANG选项参数的存在,waitpid不会阻塞等待之进程结束,而是直接返回。当waitpid()返回父进程中后,子进程才结束,但是waitpid()已经执行完了,所以并没有回收子进程,子进程因此变成僵尸进程。
2024-03-18 20:52:47 31
原创 或运算的理解
p || j>i) 还添加了 j>i ,其实while推出循环后,是不存在j>i的情况,之所以要加这个条件,是因为要排除没进while循环的情况,j=1,j>i 即排除了i
2024-03-08 11:18:33 360
原创 excel操作的注意事项
1)excel中如果公式较多,复制粘贴的时候时间会长。-----原因可能是,某个单元格的文字后面可能存在空格。3)通过查找能找到相同内容,但是通过条件查询却查不到。2) 通过筛选后,如何复制列问题还需要解决。
2024-03-06 11:51:47 336
转载 链表头结点和不带头结点的区别
的插入删除需要移动大量的元素,因此引入链表(本文讨论单链表)的概念,链表元素之间通过“链”来链接,因此插入和删除时不需要大量的移动元素,而只需要改变“链”的关系即可。若不使用头结点,当表非空时,头指针指向第1个结点的地址,即*LNode类型,但是对于空表,头指针指向的是NULL,此时空表和非空表的操作是不一致的。若使用头结点,无论表是否为空,头指针都指向头结点,也就是*LNode类型,对于空表和非空表的操作是一致的。因此,不带头结点的链表,插入第一个结点时,需要特殊处理,删除操作类似。
2024-03-04 13:18:27 55
原创 多路IO转接之 poll方式
1)可以突破1024个文件描述符限制。poll是select函数的升级版。3)搜索文件描述符范围变小了。2)监听、返回集合实现分离。fds:数组的首地址;nfds:数组的个数。
2024-03-03 16:58:26 368
原创 ppt中调整某条表格框线的格式
2、选择要调整的边框线所在的单元格(第二列的右边框加粗,体现分栏的效果)3、设计--边框--中选择要调整的边框线位置(假设要调整右框线)
2024-03-02 08:31:40 382
转载 Linux之循环创建多个子进程
但是shell进程不知道还有子进程,当父进程执行完(打印了 I am parent),shell进程抢占了前台,恢复到正常状态,此时子进程3用了终端,所以这句话( I am 3 child, pid = 19810)就没打印到下一行的行首,而是直接打印到光标的后面的位置上,打印完之后,做了个换行,光标移到下一行起始位置,这时候子进程2又抢占了终端,在光标之后打印了一句话……当我去掉所有的sleep函数之后,父进程和子进程以及shell进程之间共同抢夺CPU,shell进程并不知道父进程又创建了子进程。
2024-02-29 00:02:47 34
原创 listen函数的理解
网络编程中,listen函数直的同时发起与服务建立连接(三次握手)的客户端个数,最多是128个。并不是指能最多实现与客户端建立连接的客户端个数。
2024-02-28 23:56:00 306
原创 通过多进程并发方式(fork)实现服务器(注意要回收子进程)
2、子进程完成数据交互后,close(cfd);此时成为僵尸进程,所以需要在父进程中收尸,回收进程描述符等资源。但此时父进程在accept,无法waitpid(),此时使用signal的方式SIGCHILD来解决收尸问题,当子进程成僵尸进程后,由内核自动回收。调用fork()创建子进程后,子进程继承cfd,lfd,通过该cfd与连接过来的客户端通信,lfd对子进程来说没用,可以直接close(lfd);对于父进程来说,只是用来建立连接的,故父进程中的cfd没有用,直接close(cfd);
2024-02-28 23:52:08 538
原创 网络编程中的read、write函数的三种返回值处理及readn和writen函数
比如:总共想读4096个字节,每次只发1500个字节,就需要读多次。write函数返回值为0,表示什么东西都没写。read函数返回值为0,表示对端关闭。readn函数读一行,读到\n。
2024-02-26 00:46:11 465
原创 pthread_cond_timedwait()函数
相对时间:相对于当前时间,如sleep(3);相对于当前,过3s.绝对时间:相对于1970年1月1日0时0分0秒。
2024-02-25 14:57:59 397
原创 phtread_cancel函数用于取消线程,但不是实时的
如上图所示,线程函数中没有取消点(一般是一些系统调用----man 7 pthreads查看,自定义函数是无效的),则使用pthread_cancle函数不生效。pthread_join回收的线程已经被phread_detach了的话,会报错,错误号是22;通过pthread_join回收的线程已经被phread_cancel了的话,返回值是-1;解决方法:可以添加pthread_testcancle();
2024-02-25 01:07:53 478
转载 C语言回调函数详解(全网最全)
如上述代码:可以看到,Handle()函数里面的参数是一个指针,在main()函数里调用Handle()函数的时候,给它传入了函数Callback_1()/Callback_2()/Callback_3()的函数名,这时候的函数名就是对应函数的指针,也就是说,回调函数其实就是函数指针的一种用法。结合这幅图和上面对回调函数的解释,我们可以发现,要实现回调函数,最关键的一点就是要将函数的指针传递给一个函数(上图中是库函数),然后这个函数就可以通过这个指针来调用回调函数了。
2024-02-24 21:01:24 234
转载 C语言四大存储区域总结
4.堆区--------由malloc,calloc分配的内存区域,其生命周期由free决定。3.栈区--------主要存储局部变量,栈区上的内容只在函数范围内存在,当函数运行结束,这些内容也会自动被销毁。原文链接:https://blog.csdn.net/yue_jijun/article/details/81192102/2.数据区------主要存储全局变量(常量),静态变量(常量),常量字符串。1.代码区--------主要存储程序代码指令,define定义的常量。
2024-02-24 20:53:43 88
原创 在线程调用的函数中使用pthread_exit同样会将线程退出
如上图所示,在func()函数中调用pthread_exit,同样可以退出当前线程;类似的,如果func()函数中调用exit,可以直接退出整个进程。
2024-02-24 20:25:30 341
转载 基础知识——嵌入式内存使用分析(text data bss及堆栈)
从可执行程序的角度来说,如果一个数据未被初始化,就不需要为其分配空间,所以.data 和.bss 的区别就是 .bss 并不占用可执行文件的大小,仅仅记录需要用多少空间来存储这些未初始化的数据,而不分配实际空间。堆的地址空间是向上增加,即当堆上保存的数据越多,堆的地址越高。注意:堆内存需要程序员手动管理内存,通常适用于较大的内存分配,如频繁的分配较小的内存,容易导致内存碎片化。栈的另外一个重要特征是,它的地址空间 向下减少,即当栈上保存的数据越多,栈的地址越低。By——口袋里のInit。
2024-02-24 20:18:51 50
转载 C++类模板介绍
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。原文链接:https://blog.csdn.net/jianglij4321/article/details/114230440。将声明和实现写在同一个文件中,并更改后缀名为.hpp,hpp是约定的名称,并不是强制。类模板成员函数创建时机在调用阶段,导致分文件编写时候链接不到。提供尾插法和尾删法对数组中的数据进行增加和删除。可以获取数组中当前元素个数和数组的容量。可以通过下标的方式访问数组中的元素。
2024-02-22 13:28:50 16
转载 【Linux】生产者消费者模型代码实现和信号量
实际上我们在这里用if判断是有bug的,因为我们不仅仅可以一次唤醒一个线程,也可以唤醒多个线程,当我们唤醒多个线程的时候,如果只用一个if判断就会造成生产者生产的数据超过队列上限,因为是多个线程同时被唤醒生产。当然我们的阻塞队列在满的时候是不能生产的,这个时候我们应该将生产者放到条件变量里。之前我们讲进程间通信的时候提到过信号量,那时候我们对信号量的描述是:信号量(信号灯),本质上是一个计数器,计数器需要++和--操作,但是由于多线程并发访问的问题,所以我们的信号量++ --操作一定要是原子的。
2024-02-22 13:20:13 53
原创 生产者和消费者问题个人总结
使用while而不是if,这仍然是因为pthread_cond_wait会京mutex解锁原因,判断这个时候,是否有其他同类线程已经“捷足先登”了,导致又没资源了。同时,我们发现,当互斥量与条件变量配合使用的时候,则是互斥量在前,pthread_cond_wait()在后,这是因为,实现互斥的P操作一定要在实现同步的P操作之后。函数是个原子操作,如出现阻塞,则会先将互斥量解锁,不会出现死锁的情况。找出题目中描述的各个进程,分析它们之间的同步、互斥关系。根据各进程的操作流程确定P、V操作的大致顺序。
2024-02-21 23:58:45 311
转载 【操作系统】生产者消费者问题(使用互斥量和条件变量)
例如(调换后),将consumer的两个wait调换,在producer发出signal信号后,如果producer线程此时再次获得运行机会,执行完了wait(space),此时,另一个consumer线程获得运行机会,执行了 wait(mutex) ,如果此时缓冲区为空,那么consumer将会阻塞在wait(items),而producer也会因为无法获得锁的所有权所以阻塞在wait(mutex),这样两个线程都在阻塞,也就造成了死锁。生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。
2024-02-21 19:42:24 374
转载 生产者-消费者问题(有例题!!!)(使用互斥量和信号量完成)
问题描述系统中有一组生产者进程和一组消费者进程,生产者进程每次生产一个产品放入缓冲区,消费者进程每次从缓冲区中取出一个产品并使用。(注:这里的“产品”理解为某种数据)生产者、消费者共享一个初始为空、大小为n的缓冲区。只有缓冲区没满时,生产者才能把产品放入缓冲区,否则必须等待。只有缓冲区不空时,消费者才能从中取出产品,否则必须等待。缓冲区是临界资源,各进程必须互斥地访问。解释:在刚开始,由于这个缓冲区全部是空的,所以生产者进程可以生产一些产品,把它放入到这个缓冲区当中。
2024-02-21 19:34:45 44
转载 MySQL基础:什么是主键和外键?它们之间有什么区别?外键有什么问题?
在设计和使用外键时,需要权衡数据完整性和性能等因素,并根据具体情况采取适当的措施和优化策略,以最大程度地减少问题的发生,并确保数据库的正常运行。在上述示例中,学生表(Students)中的CourseID字段作为外键,引用了课程表(Courses)中的CourseID字段。总体而言,主键和外键在数据库设计中起着不同的作用,主键用于标识和访问数据,而外键用于建立关系和维护数据的完整性。通过主键和外键的使用,我们可以在关系数据库中建立表与表之间的关联,并通过外键确保数据的一致性和完整性。
2024-02-20 11:52:51 281
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人