- 博客(21)
- 收藏
- 关注
原创 C++与C的关联和区别
d、C++中没有规定string类必须以'\0'结尾,编译器在实现时可以在结尾加上'\0'也可以不加,由编译器决定,因为string是一个类,它的长度信息已经被封装记录在私有成员变量中了。在C++中,void*类型不可以自动转换成其他任意类型的指针,如果需要把void*类型的指针赋值给其他类型的指针时,必须通过强制类型转换后才能赋值,为了提高指针数据类型的安全性。c、C语言使用整型来模拟的,C++中的枚举类型是一种真正的数据类型,所以不能与整型进行隐式类型转换了。
2023-09-11 20:02:25 89
原创 C语言堆内存知识
1、当首次向malloc申请内存时,malloc会向操作系统申请堆内存,操作系统会直接分配33页(1页=4096字节)内存给malloc管理,但这样不意味着可以越界访问,因为malloc可能会把内存分配给"其他人"使用,这样就产生了脏数据。2、每个内存块之间一定会有一些空隙(4~12字节),一部分空隙是为了内存对齐,其中一定有4个字节用于记录malloc的维护信息,如果维护信息被破坏会影响下一次的free的调用。功能:从堆内存中申请size个字节的内存,申请成功会得到连续的内存。
2023-09-06 19:53:38 109 1
原创 C语言指针知识
数组名就是数组的首地址,它与数组首地址是映射关系,相当于一个特殊的指针,但是它是个常量,不能修改。在C语言中,任意类型的指针可以自动转换为void*,void*类型的指针也可以自动转换。当一个指针指向数组首地址时,指针可以当做数组名使用,数组名也可以当做指针使用。函数指针就是专门指向某种函数的指针,它里面存储的是该函数在代码段中的位置(函数名)当函数的参数是指针,但是又不想被函数共享修改时,考虑使用const保护。指针是变量,它与存储的地址之间是指向关系,是可以更改的。函数的返回值\函数的参数。
2023-09-06 19:51:35 78 1
原创 算法:快速排序
在待排序数据中先找一个标杆位置p,备份p位置的值val,记录左标杆l、右标杆r,l从p的左边找比val大的数,找到后赋值给p位置,更新p到l,然后r从p的右边找比val小的数,找到后赋值给p位置,更新p到r。循环往复,直到l和r重合,把val还原回p位置完成一次快排,然后用同样的方式对p左右两边的数据进行快排。它的综合性能最优,因此得名快速排序。时间复杂度:O(NlogN)
2023-09-05 10:53:36 83 1
原创 算法:插入排序
把数据看成两个部分,前部分是有序的,把剩余部分的数据逐个往前比较,如果比前面的数小,前面的数往后移动一位,继续往前比较,直到遇到更小的数,那么该数据的后一个位置即为可以插入的位置。适合对已经排序后的数据,新增数据后再排序。时间复杂度:O(N^2)
2023-09-05 10:50:40 51 1
原创 算法:选择排序
假定最开始的位置是最小值并记录下标min,然后与后面所有的数据比较,如果有比min位置的值更小的数,那么更新min,结束后min的下标与开始时发生过改变,才进行交换到开始位置。虽然时间复杂度较高,但是数据交换次数比较少,因此实际的运行速度并不慢(数据交换比数据比较耗时)时间复杂度:O(N^2)
2023-09-01 10:41:22 39 1
原创 算法:冒泡算法
数据左右比较,把较大的数据交换到右边,往后重复以上操作,直到把最大的数据交换到最后,特点是该算法对数据的有序性敏感,如果在一次的排序过程中没有发生一次交换,那么就意味着数据已经有序,可以立即停止排序。适合待排序的数据基本有序时,则冒泡的效率非常高。时间复杂度:平均:O(N^2) 最优O:(N)
2023-09-01 10:28:24 37 1
原创 生产者消费者模型
生产者与消费者模型 生产者:生产数据的线程 消费者:使用数据的线程 仓库:临时存储数据的缓冲区(仓库解决生产、消费不匹配的问题) 可能产生的问题: 生产快于消费:仓库爆满,撑死 消费快于生产:仓库空虚,饿死 利用条件变量来解决以上问题: 当缓冲区满的时候,生产者睡入条件变量(full),并通知消费者全部醒了(empty) 当缓冲区空的时候,消费者睡入条件变量(empty),并通知生产者全部醒来(full
2023-09-01 09:51:16 35 1
原创 线程互斥锁、读写锁、自旋锁、死锁
1、当读写锁未被任何线程占用,发出读请求、写请求的线程都可以占用,如果同时请求,默认优先给读请求占用。2、当变成读锁(多个线程占用)时,读请求的线程可以占用不会阻塞,但是写请求的线程会阻塞等待读锁解锁。3、当发出读请求的线程正在执行时,发出写请求的线程必须等待前面所有读请求线程执行完后才能执行。4、当发出写请求的线程正在执行时,发出读请求的线程必须等待前面所有写请求线程执行完后才能执行。当读写锁被发出读请求的线程占用时,称为"读锁",当读写锁被发出读请求的线程占用时,称为"写锁"
2023-09-01 09:47:36 124 1
原创 进程多路复用
2、epoll会把发生了事件的描述符返回到结构数组,只需要遍历该数组就可以处理所有发生了事件的描述符,但是select返回到集合中,需要遍历全部被监控的描述符才能处理。2、pselect的超时时间参数不会改变,因此无法获取剩余时间,但是select的会改变,可以获取剩余时间,但是每次都需要重新设置。边缘触发:当数据产生了发送的动作时就会触发且只触发一次,就算文件缓冲区中要有需要读取的数据也不再触发事件。条件触发:当文件缓冲区中有要读取的数据时就会触发事件,也是epoll的默认触发。
2023-08-30 11:40:23 37
原创 socket创建进程使用
进程A:(1)、 创建socket对象。(2)、准备通信地址(本地socket文件)。(3)、 绑定sokect对象和地址。(4)、监听、 等待连接。(5)、接收\发送数据。(6)、 关闭socket、删除socket文件。进程B:(1)、创建socket对象。(2)、准备通信地址。(4)、发送\接收数据。(5)、关闭socket。实现进程之间的通信需要创建两个进程,假设进程A、进程B。演示一个基础代码A进程。
2023-08-30 10:49:05 61
原创 自定义函数调用
在函数调用前没有出现函数声明或定义,那么编译器会猜测函数的返回值为int类型,如果猜对了会产生隐式声明的警告,如果没猜对会报错。返回值类型 函数名(类型1 变量名1,类型2 变量名2,...);返回值类型 函数名(类型1 变量名1,类型2 变量名2,...)3、如果参数类型相同,不能省略后面的类型名。函数名(实参变量1,实参变量2,...);2、如果函数没有返回值,也要写void。1、如果函数不需要参数,要写void。
2023-07-26 10:52:44 47 1
原创 初学标准c语言进制转换和函数基础概念
C语言标准委员会以函数形式提供的一些基础功能,都被封装在libc.so库中,并且分在了不同的文件中,需要使用时只要把对应的头文件导入即可(例如stdio.h...),然后通过具体的 函数名(参数) 即可完成调用。注意:目前任何编程语言和系统都没有真正的随机数,C编译器是把从0~极大值范围的数值打乱后,存储到一块固定内存中,然后从里面取所谓的随机数。随着CPU的位数的不断增加,已经到目前的64位,所以八进制不再能够满足需求,因此发展出现在的十六进制,由于历史原因八进制还不能退出历史舞台。
2023-07-13 10:25:12 56
原创 初学标准c语言数组概念
7、如果有初始化数据,则可以省略数组数量,因为编译器会自动统计数据的个数,然后确定数组的数量。6、初始化数据可以全部省略,只写大括号,相当于全部成员初始化为0。2、大括号数据和列数不省略,行数可以省略,编译器会自动计算行数。1、数组与变量一样,默认值随机,所以一般都要先初始化。什么是数组:变量的组合,是一种批量定义相同类型变量的方式。1、大括号内数据可以全部省略,那么就自动补0。下标:从0开始,范围:0~数量-1。2、数组不能整体初始化,只能逐个初始化。5、初始化数据不足,编译器会自动补0。
2023-07-12 16:15:19 78 1
原创 初学标准c语言数据类型和运算符
字符就是图案或符号,字符在内存中依然存储成整数,需要显示成字符时,操作系统会根据ASCII码表中的对应关系把整数显示成对应的符号或图案。先有的C语言后有的bool类型,C语言中不可能有真正的布尔类型,都是在中对布尔类型使用整数进行模拟。特殊特例:当运算对象类型只是 char或者short,且类型不同,编译器会做类型提升,提升为int再运算。只有相同类型的数据才能进行运算,如果类型不相同的数据需要先转换成相同的类型才能运算。也可以借助短路特性,实现简单的单分支效果。
2023-07-11 19:11:20 65
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人