- 博客(45)
- 收藏
- 关注
原创 CMake学习笔记(三):静态库,动态库的生成和使用
接下来我们简单的讲解下动态库的建立和使用:在后面的项目的开发过程中,我们使用第三方库或者我们跑这个项目的时候我们总会看到一些.so的文件,这些就是所谓的动态库,里面的内容就是编译后的源文件,是程序运行时被加载和链接的代码库。并且可以独立更新,且因为可以被多个程序共享同一个动态库,所以动态库也被成为共享库。我们借用上一节提到的file方式找到所有的源文件后,将源文件通过add_library来生成一个动态库名字为MyShare。
2025-03-17 23:18:13
332
原创 CMake学习笔记(二):变量设值,源文件/文件查找
在这里我们给变量SRC_LIST设值的值就是后面跟着的那些div.cpp mul.cpp;sub.cpp;add.cpp main.cpp,这里我们可以看到可以使用空格或者;进行分隔,这里的message就类似一个输出语句,用来打印SRC_LIST里面的内容,在cmake中我们使用变量的值都是使用${}把变量框起来,当我们执行cmake ../后的结果如下:从这里我们可以看出我们的message语句的输出结果可以在cmake 阶段进行打印。
2025-03-17 23:18:08
254
原创 命名管道实现传递数据到二进制文件
在做项目的过程中,一般来说我们的信息输入是有固定的端口/来源的,但是在当前的越来越快的开发节奏下,往往会出现输入源还未完全确定的情况下需要我们先实现功能逻辑,信号接受端后面再对接。或者数据接受端和功能的逻辑同步开发的情况下,为了方便快捷的将数据传递到可执行文件中去,我们可以使用命名管道实现将我们的基本测试数据写入到程序中,进而能先展示我们的功能或者调试我们的程序,或者做一个简单的demo去展示团队的快捷开发能力进而拿下项目。
2025-03-05 23:18:40
243
原创 CMake学习笔记(一):工程的新建和如何将源文件生成二进制文件
cmake是我们在工作过程中比较常见的一个工具,该系列文章是自己用来学习的笔记。目前只是记录下自己学习cmake的过程中的一些重要的知识点,其是以项目需求为导向并非完整的cmake的学习路线和系统,同样也并非适合所有的人。
2025-03-05 23:18:25
410
原创 手写精简版TinyHttpd项目(一)
我们在之前的TinyHttpd的精读(可以在首页去查看)中已经是基本的了解了显示一个网页的基本过程,那么我们学习后可以通过手写一个精简版的进行巩固下。
2024-06-18 23:03:57
908
原创 TinyHttpd源码精读(三)
当然后面的cgi这个算是一个精简版讲解,受限于cgi的布置,我们也不太容易一睹原项目中cgi的风采,但是思路是一样的。其中对于异常情况的处理和思路也是值得我们去学习的,不过我并不是主修web服务这块的,所以目前这块我的理解不够深入,暂时也不打算这样深入。主体的逻辑就是从pipe函数那里开始,创建一个子进程,父子进程的环境啥的都完全一样,然后再子进程里面打开cgi脚本,并且将脚本的输出通过dup2函数和cgi_output,cgi_input传递到父进程里面,然后由父进程传递到client(网页)中。
2024-06-11 22:19:16
437
原创 TinyHttpd源码精读(二)
书接上文,我们在TinyHttpd源码精读(一)中简单的讲解了项目的运行和main函数以及accept_request函数的主体内容。基本上这个项目的主线思路就差不多一半了,接下来我们看看这个项目是如何显示静态网页和动态的网页的。
2024-06-11 22:19:11
1105
2
原创 Socket通信学习(三):两个客户端通过服务端中转进行数据的传递
这块的思路不难,但是再后面的结果中我们发现虽然我们可以实现简单的对话但是只有当两个客户端都输入完成后才能显示出接受到的数据。当然这个可以采取两个线程,一个发送消息,一个去接受消息。同样的,对于客户端的链接我们其实也可以单独开一个线程去实时的去监听。这些具体的功能,我们后面再去慢慢的实现这个吧。
2024-06-05 00:28:24
839
原创 Soket通信学习(二):服务端和客户端的简单的对话交流
上一篇我们已经能成功的创建服务端和客户端的代码并且能创建一个简单的沟通链接,既然能建立的话,我们就循环下这个发送和接受信息的过程即可,然后注意下清空接受信息的buffer数组。可以先自己动手修改下代码然后再看下面的代码。
2024-04-29 00:43:05
148
原创 Soket通信学习(一):创建服务端和客户端并建立简单的通信
这篇文章不详细说socket的基础理论直接聚焦代码方面的实操,毕竟刚刚开始学这个的时候还是得先上手后才能更好的去理解背后的原理和知识。一般的工作中也是要求先使用后去理解。(开发/编译环境:ubuntu )
2024-04-29 00:18:13
659
原创 回调函数浅聊
我们可以看到,作为参数来看可调用对象是非常多的,函数名称,lambda表达式,函数指针等,我们在编写回调函数的时候是不知道会传入什么参数进来的,这样在我们试图使用统一的方式保持,或传递一个可调用对象时,会非常的繁琐。std::async 通常会根据执行策略(指定为 std::launch::async 或 std::launch::deferred)来决定是否创建新线程执行任务。综上所述,std::thread 适合对线程进行精细控制,而 std::async 更适合用于异步任务的简单启动和结果获取。
2023-11-28 11:37:17
164
原创 QT_OpenGL学习之路-------第二节
在上一节中,我们介绍了如何入新建一个opengl的窗口,但是QT中的OpenGL的使用和OpenGL本身的使用有些不一样,QT进行了一定的封装。从这里面我们可以知道:paintGL():渲染OpenGL窗口的函数,当窗口需要刷新的时候被调用,resizeGL():设置OpenGL的 viewport,第一次出现窗口或者窗口大小变化的时候被调用。initializeGL():设置OpenGL的资源和状态,只会在最开始的时候被调用一次,所以这个函数就是初始化的,最开始调用。
2023-11-28 11:36:36
177
原创 线程三----------异步操作
异步操作是一种执行任务而无需等待其完成的方式。异步操作可以提高程序的并发性和响应性,适用于需要长时间执行的任务或需要与外部资源进行交互的情况。C++中提供了异步操作相关的类,主要有:std::future,std::promise和std::package_task。其中std::future作为异步结果的传输通道,可以很方便地获取线程函数的返回值;std::promise用来包装一个值,将数据和future绑定起来,方便线程赋值;std::package_task用来包装一个可调用对象,
2023-11-22 23:37:15
115
原创 Shell笔记第四节(函数,文件包含,重定向)
2.参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。return 后跟数值n(0-255)1.可以带function fun()定义,也可以直接fun()定义,不带任何参数。
2023-11-15 23:59:32
74
原创 Shell笔记第三节--(printf,test,流程控制,循环语句)
until循环执行一系列命令直到条件为ture时停止,until循环与while循环在处理方式上刚好相反。一般的while循环优于until循环,不过在某些情况下until循环更加好用。Shell中的test命令用于检查某个条件是否成立,它可以进行数组,字符和文件三方面的测试。%-10s指一个宽度为10个字符(-表示左对齐,没有则右对齐),不足使用空格进行填充。当condition的值为false的时候才会执行command,否则就跳出循环。其流程控制和C中的if类似,不过sh的流程控制不可为空。
2023-11-14 15:27:17
143
原创 Shell笔记第二节
我们在一些项目中需要向脚本输入一些参数,脚本内获取参数的格式为:$n。n代表一个数字,1为执行脚本的第一个参数,2为执行脚本的第二个参数,以此类推。再此进行一个初略的估计:应该是将输入都放在一个数组或者字符串中,再有脚本去读入,这样./shell1.sh才是第0个元素。如“$@”用["]括起来的情况,以"$1" "$2" ... "$n"的形式输出所有参数。如“$*”用["]括起来的情况,以“$1 $2 ... $n”的形式输出所有参数。与$*相同,但是使用时加引号,并在引号中返回每个参数。
2023-11-14 11:12:18
61
原创 Shell笔记第一节
在Shell中,用括号来表示数组,数组元素用"空格"分开:数组名=(值1 值2 ... 值n) /数组名[n]=n/bin/bash输出结果:1,2,3,4771,2,3,4,77在Shell中数组可以不使用连续的下标,且下标的范围没有限制。输出数组的所有内容直接使用echo ${your_name[@]}
2023-11-13 16:05:28
58
原创 线程(二)
当我们的同步队列在没有满的情况下可以正常的插入数据,满了则会调用m_notFull.wait(m_mutex) 来阻塞进程进行等待,待消费线程取出数据后发一个未满的通知,然后前面阻塞的线程就会被唤醒继续往下执行。如果不满足条件则会释放mutex,然后将线程置为waiting状态,继续等待。C++11提供一个原子类型std::atomic<T>,可以使用任意类型作为模板参数,C++11内置了整型的原子变量,可以更加方便地使用原子变量,使用原子变量就不需要使用互斥量来保护该变量了。如果条件满足,则向下执行。
2023-11-10 16:31:27
55
原创 线程(一)
C++11中提供了std::thread来创建线程,其使用非常的简单,只需要提高线程函数或者函数对象即可,并且可以同时指定线程函数的参数。在上例中,函数thread_func_01()将会运行于线程对象t中,join函数将会阻塞线程,直到线程函数执行结束,如果线程函数有返回值,返回值将被忽略。输出的结果是:如果不希望线程被阻塞执行,可以调用线程的detach()方法,将线程和线程对象分离。通过detach,线程就和线程对象分离了,让线程作为后台线程去执行,当前线程也不会阻塞了。
2023-09-20 00:02:06
72
原创 基于范围的for循环
在C++98中,不同的数据和容器,遍历的方法不尽相同,写法也不同意,比较繁琐。在C++11中新增了一个基于范围的for循环以统一,简洁的方式来遍历容器和数组。在上述代码中,虽然有auto但是还是无法避免出现begin()和end()等繁琐的迭代器。从上述代码中可以看到for循环的代码写得非常的简洁,且输出的内容一致。在上面的基于范围的for循环中,n表示arr中的一个元素,auto则是让编译器自动推导出n的类型。
2023-09-13 23:11:41
79
原创 C++11中的智能指针
智能指针是存储指向动态分配(堆)对象指针的类,用于生存期的控制,能够确保在离开指针所在作用域时,自动的销毁动态分配的对象(和普通指针的区别防止内存泄露。智能指针分三种:1.std::shared_ptr:共享的智能指针,多个智能指针来同时管理这块内存。2.std::unique_ptr:独享的智能指针,只能有一个指针来管理,如果下一个指针也要管理,那么资源就会转移到下一个unique_ptr的智能指针上。
2023-09-11 23:49:46
110
原创 Decltype关键字
3.带括号的表达式和加法运算表达式(其他情况下,若exp是一个左值,则decltype(exp)是exp类型的左值引用,否则和exp类型一致。.表达式为普通变量或者普通表达式或者类表达式,在这种情况下,使用decltype推导出的类型和表达式的类型是一致的。推导是在编译期完成的,它只是用于表达式类型的推导(相较于auto,它可以进行复杂表达式的推导)。2.exp是函数调用,decltype(exp)和返回值的类型一致。decltype(exp),其中exp表示一个表达式(expression).
2023-08-28 21:34:24
209
1
原创 本文章将详细介绍Qt的绘图QPainter的使用
QPainter是用来进行绘图操作的类,QPainterDevice是一个可以使用QPainter进行绘图的抽象的二维界面,QPainterEngine给QPainter提供在不同设备上绘图的接口。Qt的二维绘图基本功能是使用QPainter在绘图设备上绘图,绘图设备包括QWidget,QPixmap等,通过绘制一些基本的点,线,圆等基本形状组成自己想要的图形,得到的图形是不可交互操作的图形。brush属性:QBrush 笔刷,设置一个区域的填充特性,可以设置填充颜色,填充方式,渐变特性等。
2022-11-04 23:13:06
1544
原创 Model/view 第二部分:QFileSystemModel的使用
目的:通过路径获取当前系统的结构并且使用TreeView显示出来,在TreeView中点击一个目录时,其目录的下层文件信息在listview和tableview中显示出来。QFileSystemModel提供了一个可用于访问本机文件系统的数据模型,其和视图组件QTreeView结合使用,可以用目录树的形式显示本机上的文件系统。ui建立:新建三个groupBox,在其内部放入Treeview,ListView,TableView。QDir::currentPath()用于获取当前应用程序的当前路径。
2022-10-30 22:59:19
564
原创 Model/view 第一部分:基础知识
所有的基于项数据(item data)的数据模型(Model)都是基于QAbstractItemModel类的,这个类定义了视图组件和代理存取数据的接口。为视图组件设置一个数据模型就可以实现视图组件和数据模型之间的关联,在视图组件上的修改将自动保持到关联的数据模型里,一个数据模型可以同时在多个视图组件里显示数据。QStandardItemModel 标准的基于项数据的数据模型类,每个项数据可以是任何数据类型。代理负责从数据模型获取。一个项可以有不同的角色的数据,用于不同的场合。
2022-10-30 22:22:57
157
原创 C++实现简易定时器
里面包含了计时器id,定时的时长,触发定时器开始的时间,执行的任务。这个地方需要注意下getTime函数,通过GetLocalTime来获取当前的时间,然后使用mktime函数来讲当前的时间点转化成秒数,最后将秒数。所以我们首要需要一个接口来添加定时器(AddTimerHandler),将定时的时间和所需要执行的任务添加进入;不停的循环主任务,当定时器的时间到了就执行子任务。注意这里的任务是通过函数指针来实现回调函数的功能(即通过函数指针来执行函数有一定的局限性,C++11标准中有更好的方法)
2022-10-11 22:22:32
5538
原创 单例的学习
当我们声明函数的时候我们就在疑惑返回值,声明一个对象是有地址的,这里的地址我们要求不能被改变,且类声明完就得有。在它的核心结构中只包含一个被称为单例的特殊类,通过单例模式可以保证系统中一个类只有一个实例并且该实例易于外界访问。但是类不完成是无法实例化的,所以我们需要一个函数去外部实例化一个对象,且这个函数是外部可访问的。如果希望在系统中某个类的对象只能存在一个,单例是最好的解决方案。做完上述工作后,我们在类外实例化下即可完成一个单例的创建。单例就是只能实例化一个对象,(真惨,对象都只能有一个)
2022-09-28 23:18:58
131
原创 Lambda表达式
lambda表达式是C++中新引入的匿名函数 ,接下来我们来看看它的结构:[capture list] (params list) mutable exception-> return type { function body } capture list:捕获外部变量列表 params list:形参列表 mutable指示符:用来说用是否可以修改捕获的变量 exception:异常设定 return type:返回类型 function body
2022-07-06 21:34:44
160
原创 聊聊C++的继承
c++中最重要的就是多态,然而在继承是实现多态的一个重要的行为。子类继承父类,就会讲父类中的所有数据,行为统统继承。继承通过:来表明。例如: class animal{}class dog :public animal{}我们知道,一个类有构造函数和析构函数。那么在继承的过程中,父类和子类的构造和析构的执行顺序是怎么样的呢?我们来看如下代码:class animal{public: animal() { cout ...
2022-06-08 23:26:13
203
原创 浅聊map容器
在进入map容器前先看看map容器内存放的值的类型:pairpair 类型(键值对)声明:pair<T1, T2> p1;声明并初始化:pair<T1, T2> p1(v1, v2);make_pair(v1, v2)以 v1 和 v2 值创建一个新 pair 对象,其元 素类型分别是 v1 和 v2 的类型也可以这么使用:auto pair = make_pair(v1, v2);OK,简单的聊完了pair类型,接下来我们就进入map容器Map容器:..
2022-05-18 23:53:45
359
2
原创 简述快速排序算法
概念:快速排序是一种二叉树结构的交换排序方法,设数组a中存放了n个数据元素,low为数组的低端下标,high为数组的高端下标,从数组的a中任取一个元素(通常去a[low]作为标准),调整数组a中各个元素的位置,使排在标准元素前面的元素的关键字均小于标准元素的关键字,排在标准元素后面的元素的关键字均大于或等于标准元素的关键字。这样一次排序后,标准元素前面的元素均小于标准元素,后面的元素均大于或等于标准元素。然后对标准元素的前后分别在使用同样的方法进行递归快速排序。递归算法的结束条件是high<=low,
2022-05-15 21:17:50
494
原创 直接插入排序
概念:顺序的把带排序的数据元素按其关键字值的大小插入到已经排序数据元素子集合的适当位置。子集合的数据元素个数从只有一个数据元素开始,逐次增大,当子集合大小最终和集合大小相同时,排序完毕。设待排序的n个数据元素存放在数组a中,初始时,子集合a[0]已经排好序,第一次循环准备把a[1]插入到已经排好序的子集合中。这时只需要比较a[0],a[1]即可。若a[0]<=a[1],则说明序列有序,否则将a[1]插入到a[0]的前面去。此时子集合的大小增大为2,第二次循环准备把数据元素a[2]插入到已经排好
2022-05-14 22:03:44
253
原创 UDP链接通信:
UDP通信不需要建立链接,直接通过ip地址和端口的绑定即可实现通信所以首先我们需要绑定一个端口号,这里我们绑定本地的端口号:这个是端口号udpsocket->localPort()port = udpsocket->localPort()udpsocket->bind(port)当我们不需要绑定时我们可以使用:udpsocket->abort();//解除绑定OK现在我们已经将端口绑定好了,接下来只需要读取数据并且显示出来就行。和TCP协议一样,当有消
2022-04-14 22:34:37
1167
原创 网络连接部分:服务器和客户端的部署代码
QTcpServer *tcpserver; QTcpSocket *tcpsocket;这两个类是必须的(对于服务器而言)。其中QTcpServer 主要用于服务器端建立网络“监听”“创建网络Socket”连接。一般监听网络连接需要ip地址+端口。当有新的客户端连接时,会发射newConnect()信号当客户端和服务器端的链接建立后就通过QTcpSocket 来传输数据。接下来我们来创建一个简单的客户端和服务器端的链接,文字发送的小程序。服务器端:大致可以分为四部分,par
2022-04-10 21:54:51
606
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人