自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(115)
  • 问答 (15)
  • 收藏
  • 关注

原创 Linux 静态库 和 动态库

在Linux系统上,库文件用于共享和重用代码。根据使用方式和链接方式的不同,库文件可以分为静态库和动态库。

2024-07-02 15:54:47 657 1

原创 基于Linux的云端垃圾分类助手

本项目旨在开发一个基于嵌入式系统的智能垃圾分类装置。该装置能够通过串口通信、语音播报、网络通信等多种方式,实现垃圾的自动识别和分类投放。系统采用多线程设计,确保各功能模块高效并行工作。

2024-07-01 21:52:48 853

原创 C语言调用python函数

通过C语言调用Python代码,需要先安装libpython3的 dev依赖库(不同的ubuntu版本下,python版本可能会有差异, 比如ubuntu 22.04里是libpython3.10-dev)。

2024-06-26 19:57:38 1305

原创 Python 字典 及 字典的嵌套

Python 的字典是一种用于存储键值对的数据结构。字典嵌套则是在一个字典中存储另一个字典,允许创建复杂的、层次化的数据结构。

2024-06-26 10:45:28 534

原创 OrangePi连接Wi-Fi步骤

然后输入sudo reboot重启树莓派,树莓派重启登录后,再次输入ifconfig就可以看到成功连上 WiFi,并获得 IP 地址了。顺带提一嘴夹在 eth0 和 wlan0 中间的 lo,这是本地回环接口(Local Loopback),一般用于本机内部通信,并不真实地从外界接收和发送数据包。然后同样使用nmcli命令连接WiFi热点,其中wifi_name是想要连接的WiFi热点的名字,wifi_passwd是想要连接的WiFi热点的密码。例如,我这里用的 WiFi 热点名字是。

2024-06-21 21:06:55 376

原创 Linux网络编程——概念及实现双方聊天

网络编程的场景: 假设你面前有五座房子(服务器),你要走到其中一座房子的某一间,此时你站在五座房子面前很迷茫,突然,第二座房子上面有人在叫,并且用汉语(TCP/UDP)叫:“我是第二号楼(ip地址),我的房间是1102(端口号)”,那么你就得到了楼号和房间号(获取服务器ip和端口号),就可以去找那个人(连接)。那个人就回房间了,等待你的到来。

2024-06-07 20:48:40 1128

原创 字节序 大端 小端

字节序(Byte Order),指的是在计算机系统中,多字节数据(如整数、浮点数)在内存中存储时的字节排列顺序。主要有两种类型的字节序:大端字节序(Big Endian)和小端字节序(Little Endian)。大端字节序在大端字节序中,数据的最高有效字节存储在内存的最低地址,而最低有效字节存储在内存的最高地址。例子: 假设我们有一个32位的整数0x12345678,按大端序存储时的字节顺序如下:内存地址: 0x00 0x01 0x02 0x03数据: 0x

2024-06-05 20:46:41 261

原创 为什么4个二进制位表示1个16进制位

为什么4个二进制位表示1个16进制位呢?首先需要了解二进制和十六进制分别是怎么样的。

2024-06-05 20:18:47 552

原创 TCP/UDP的区别

首先来介绍一下什么是TCP和UDPTCP(传输控制协议)和UDP(用户数据报协议)是互联网协议套件中两个重要的传输层协议。它们在数据传输的方式、可靠性、连接性等方面有显著的区别。总之他们两个就是个协议,协议也就是数据结构,是数据传输的方式。看不太懂?我们先讲讲他们两个的区别,在文末我们会举个生动形象的例子。

2024-06-05 19:39:58 934

原创 Linux 多线程 生产者&消费者 问题

在 Linux 系统中,生产者和消费者问题是一个经典的多线程同步问题,用于描述如何在多线程环境中协调多个线程对共享资源的访问。这个问题通常涉及两个类型的线程:生产者线程和消费者线程。生产者线程负责生成数据并将其放入缓冲区,而消费者线程则从缓冲区中取出数据进行处理。

2024-06-05 14:41:14 665

原创 手撸 串口交互命令行 及 AT应用层协议解析框架

这个任务实现了一个简单的 UART 命令控制台,通过消息队列接收 UART 输入数据,使用命令解释器处理输入命令,并将结果输出到 UART。通过这种方式,系统可以处理并执行来自 UART 的命令,同时确保并发访问的安全性。这个任务从消息队列中读取接收到的 UART 数据,并将其传递给命令解释器进行处理。这段代码实现了一个简单的命令行接口(CLI),允许通过注册命令的方式来扩展功能。这个函数会遍历注册的命令链表,找到匹配的命令,并调用相应的回调函数处理。中,最后将拷贝的数据放入消息队列中,等待处理。

2024-06-05 10:58:23 1235

原创 Linux线程 -- 互斥锁 和 条件变量

在多线程编程中,互斥量(mutex)是用于保护共享资源的同步机制,确保在任一时刻只有一个线程能够访问共享资源。互斥量用于防止竞态条件(race conditions),确保数据一致性。互斥量(mutex)是一种锁机制,用于实现线程之间的互斥访问。它有两个基本操作:在Linux中,可以使用POSIX线程库()中的互斥量。下面是一些主要函数:以下是一个使用互斥量保护共享资源的简单示例:运行结果:通过正确使用互斥量,可以确保多线程程序中的共享资源被安全地访问和修改,防止竞态条件的发生。在Linux系统中,互

2024-06-04 14:50:57 1149

原创 Linux线程--线程创建、等待及退出

持久性:静态变量在整个程序运行期间存在,不会因函数返回而销毁。唯一初始化:静态变量只在第一次声明时初始化,后续调用不会重新初始化。作用域限制:静态局部变量的作用域限制在函数内部,无法被外部访问。

2024-06-02 19:44:03 1104 1

原创 Linux -- 进程间通信的五种方式

IPC(InterProcess Communication)的方式通常有管道(包括无名管道和命名管道)、消息队列、信号量、共享存储、Socket、Streams等。其中Socket和Stream支持不同主机上的两个进程IPC。:管道是一种半双工的通信方式,用于具有亲缘关系的进程间通信。它通常用于父子进程或者兄弟进程之间。管道可以是匿名管道,也可以是命名管道。:消息队列是一种通过消息传递进行通信的方式。发送方将消息发送到队列中,接收方从队列中接收消息。消息队列可以实现进程间的异步通信。

2024-05-26 00:27:06 1704

原创 Linux进程--函数 system 和 popen 的区别

system()和popen()是 C 语言中用于执行外部命令的两个函数,它们的功能类似,但在使用方式和特性上有一些区别。

2024-05-24 21:55:55 1343

原创 Linux进程--exec族函数

由此我们可以发现: execl("/bin/ls","ls",NULL,NULL) ,第一个参数为第二个参数(程序名)的所在地,第二个参数就是要执行的程序名,第三个参数就是要执行的程序名跟的参数,比如要使用ls -l把所有文件清单列出来,则第三个参数就是“-l”。file:如果参数file中包含/,则就将其视为路径名,否则就按 PATH环境变量,在它所指定的各目录中搜寻可执行文件。exec函数族的函数执行成功后不会返回,调用失败时,会设置errno并返回-1,然后从原程序的调用点接着往下执行。

2024-05-24 20:39:21 845

原创 父进程等待子进程退出

在 Unix 和类 Unix 系统中,当一个进程结束执行时,它会留下一个称为僵尸进程的状态,此时系统仍会记录该进程的进程号和退出状态,但并未释放其占用的全部资源。等函数等待子进程退出时,操作系统会将子进程的退出状态信息传递给父进程,并在父进程成功获取退出状态后,释放子进程占用的系统资源,包括内存、文件描述符等。:父进程可能需要获取子进程的退出状态码(exit status),以了解子进程的执行结果。父进程等待子进程退出 并收集子进程的退出状态,子进程退出状态不被收集,变成僵死进程(僵尸进程)。

2024-05-24 16:59:01 490

原创 fork 与 vfork 的区别

我们可以定义一个cnt,在子进程中让它变成3, 如果使用fork,那么在父进程中打印cnt的值时,cnt依然为0,因为子进程和父进程用的是不同的内存空间。而如果使用vfork, 那么在父进程中打印cnt的值时,cnt的值为3,因为使用的是和父进程相同的内存空间。使用fork的结果:可以看见,程序没有没有等待子进程结束再执行父进程,而是互相争夺CPU的资源。关键区别二: vfork保证子进程先运行,当子进程调用exit退出后,父进程才执行。关键区别一: vfork 直接使用父进程存储空间,不拷贝。

2024-05-23 20:54:02 307

原创 Linux 进程相关概念

栈是一种先进后出的数据结构,它的大小是固定的,由系统预先分配。栈区的内存分配和释放是由系统自动管理的,通过函数调用和返回来控制栈上数据的生命周期。进程A创建了进程B 那么A叫做父进程,B叫做子进程,父子进程是相对的概念,理解为人类中的父子关系。结果:父进程和子进程的ID不同, 父进程的retpid是子进程的ID,子进程的retpid是0。返回子进程的进程ID,这个值是一个正整数,表示新创建的子进程的进程ID。:子进程会被分配一个新的进程ID,这个ID是操作系统为了标识进程而分配的唯一标识符。

2024-05-23 20:42:37 1237 3

原创 标准C库打开创建文件

fopen`是C标准函数,因此拥有良好的移植性;而`open`是UNIX系统调用,移植性有限。但如果你需要更底层的文件操作或与系统级别的 API 交互,那么使用。总的来说,如果你只需要简单地打开文件并进行读写操作,使用。

2024-05-22 15:55:44 474

原创 Linux文件编程--修改程序的配置文件

【代码】Linux文件编程--修改程序的配置文件。

2024-05-22 10:46:34 301

原创 实现Linux CP命令的代码

这段代码的主要功能是将一个文件的内容复制到另一个文件中。它首先打开源文件,获取文件的大小,然后动态分配内存空间并读取文件内容到内存中,最后将内存中的内容写入到目标文件中。接受命令行参数意味着程序可以在运行时从命令行中接收输入,并将这些输入用作程序的参数。: 打开第二个命令行参数指定的文件,如果文件不存在则创建,如果存在则清空文件内容,并以读写方式打开。: 将文件指针移动到文件的开头,以便后续读取文件内容。中的内容写入到目标文件中,写入的字节数为。中,读取的字节数为文件的大小。,用于存储从源文件读取的内容。

2024-05-21 21:33:18 580

原创 【全网最简单】手把手教你做出学生成绩管理系统

全网最简单的学生成绩管理系统

2024-05-20 15:27:29 793

原创 改写STM32标准库函数中的fputc

函数,你可以改变字符的输出方式,比如将字符通过 UART 发送出去,而不是输出到标准输出流(比如终端窗口)。所以虽然ch数组大小为20个字节,但是printf会多次调用fputc,一个一个字节传过去。函数被多次调用的过程,因为这个过程是在标准库中进行的,是隐藏在。函数,将字符一个个发送到输出流中。函数会被多次调用来完成字符的输出。所以,虽然在你的代码中你看不到。函数被多次调用的过程,但在。函数在执行输出时会调用。函数的内部实现中的。

2024-04-12 19:49:35 257

原创 睡眠真重要 | 小车摇头测距

昨晚遇到的问题:小车一开始摇头了两三下就不摇了。

2024-04-08 11:37:42 133

原创 IIC协议——OLED(128*64)外设

IIC协议(Inter-Integrated Circuit Protocol),也被称为I2C(Inter-Integrated Circuit),是一种串行通信协议,通常用于连接集成电路(IC)和外部设备,例如传感器、存储器、显示屏等。起始信号和停止信号的发送以及应答信号的接收是确保数据传输顺利进行的重要步骤,而时钟信号和数据信号则负责实际的数据传输。从设备被动地响应主设备的指令,并提供所需的数据或执行相应的操作。:IIC协议支持不同的时钟频率,可以根据应用的需求选择适当的通信速率。

2024-04-06 12:47:29 1094

原创 非标准单总线——DHT11温湿度传感器

【代码】非标准单总线——DHT11温湿度传感器。

2024-04-04 22:37:25 105

原创 左移的过程是怎么样的,为什么相当于乘以2

类似地,在二进制中,每位的权值是2的幂次方(最低位是2^0,次低位是2^1,依此类推)。在计算机中,数值的表示方式是通过位的位置和权值来实现的,左移操作改变了每一位的权值,从而导致数值的表示发生了变化,相当于每一位的数值乘以2。在二进制中,每一位的权值是2的幂次方(从右到左依次是2^0、2^1、2^2、...、2^7),因此左移八位相当于将原数值乘以2^8,即256。左移操作可以有效地将一个二进制数的所有位向左移动,可以用于实现乘以2的效果,因为在二进制中,左移1位相当于乘以2。,其十进制数值为240。

2024-04-04 22:30:34 1178

原创 wifi模块_esp工作在路由模式遇到的问题及解决

为什么做白盒测试的时候有用呢,是因为做白盒测试时,单片机接收到的只有OK和0,Connect这两种字串,而直接连接单片机时,接受到的字串不止这两种,在没有判断到OK和0,Connect这两种关键字时,索引i就不会清0,反而会一直递增,导致后面关键字符来了,单片机也找不到。达到最大值时,需要将其重置为0,以便缓冲区可以重新使用。这样的话,新接收到的字符将会丢失或覆盖掉之前缓冲区中的数据,导致接收到的数据不完整或混乱。原因:在中断服务函数中的最后面部分,没有在当i = 12时,对i清零,让i回到初始的位置。

2024-04-04 13:54:54 237

原创 51超智能开关盖垃圾桶

代码开头包含了reg52.h和头文件,用于引入 8051 微控制器的寄存器定义和内联汇编指令。使用sbit定义了系统中使用的各种输入输出引脚,如LED、舵机、超声波模块、蜂鸣器、按键、遥控信号和震动传感器等。和函数实现了微秒级和毫秒级延时。和函数分别初始化定时器0和定时器1。EX0_init()函数初始化外部中断0,用于检测震动传感器信号。Star_HC()函数用于触发超声波模块发送测距信号。和函数分别控制垃圾桶盖子的开闭以及状态灯的亮灭。函数用于获取超声波模块返回的距离值。

2024-04-01 22:16:47 578

原创 strcpy和strcat的自我实现

【代码】strcpy和strcat的自我实现。

2024-03-30 16:52:34 90

原创 二维数组中a[0] 和 &a[0]的区别

这表示二维数组的第一个元素,也就是第一行的地址。在内存中,它代表的是第一行的起始地址。接受一个指向整数的指针,用于表示一维数组的首地址,它被视为指向一维数组的指针;接受一个指向整数数组的指针,用于表示二维数组的首地址,它被视为指向二维数组的指针。在C语言中,二维数组是以连续内存块的形式存储的,其中每个元素都是数组。将是一个包含4个整数元素的数组的地址,因为每个数组都包含4个整数。将是整个二维数组的地址,它指向二维数组的第一个元素。是指向二维数组的第一个元素(一维数组)的指针,而。

2024-03-29 22:49:35 692

原创 函数指针的运用

这段代码的主要功能是根据用户输入的命令选择不同的操作,并对两个数进行相应的处理,然后输出结果。这段代码使用了函数指针,实现了根据用户输入的命令选择不同的操作,并对两个数进行相应的处理。函数获取用户输入的命令,并根据用户输入的命令选择对应的函数,并将函数地址赋值给函数指针。,用于指定对数据进行的操作。函数内部通过调用函数指针来实现对数据的处理,并返回处理结果。函数分别用于获取两个数中的较大值、较小值和它们的和。,用于存储用户输入的命令。,用于存储根据用户命令选择的函数地址。函数中,定义了两个整型变量。

2024-03-29 22:38:22 332

原创 数组指针的运用

这段代码的主要功能是根据用户输入的行号和列号,从二维数组中获取对应位置的元素值,并输出到屏幕上。函数用于提示用户输入要获取的元素的行号和列号,然后通过指针参数返回用户输入的行号和列号。这段代码使用了数组指针,实现了从二维数组中获取指定位置的元素值。函数提示用户输入要获取的元素的行号和列号,并将用户输入的行号和列号传递给。的方式获取二维数组中指定位置的元素值,并将其返回。用于存储用户输入的行号、列号和获取到的元素值。,以及要获取元素的行号和列号。函数,获取对应位置的元素值。最后,输出获取到的元素值。

2024-03-29 22:32:36 214

原创 函数指针数组的运用

这段代码使用了函数指针数组,实现了一个简单的函数处理器,可以根据用户选择的操作对两个数据进行处理,并输出结果。这段代码的主要功能是通过函数指针数组实现了一个函数处理器,用户可以根据需求选择不同的处理操作,对两个数据进行处理并输出结果。,用于指定对数据进行的操作。函数内部通过调用函数指针来实现对数据的处理,并返回处理结果。函数分别用于获取两个数中的较大值、较小值和它们的和。,并定义了一个包含三个函数指针的函数指针数组。函数接收三个参数:两个数据。函数中,定义了两个整型变量。进行处理,并输出结果。

2024-03-29 22:28:04 167

原创 指针函数的应用——找出哪些学生有不及格的科目

它接收一个指向整数数组的指针,并遍历该数组,查找是否存在不及格的成绩。如果找到了不及格的成绩,就返回指向不及格学生所在行的指针;这个程序的主要目的是找出哪些学生有不及格的科目。在每次检查中,它遍历每个学生的成绩,如果有不及格的成绩,就输出该学生的学生号。函数对每个学生的成绩进行检查。如果有不及格的科目,就打印该学生的学生号(即学生在数组中的索引)。函数中,定义了一个二维整数数组。,表示了三个学生的四门课程成绩。

2024-03-29 22:22:51 205

原创 数组名常量和指针变量的区别

表示递增操作,它作用于变量,将变量的值增加1。如果作用于指针,那么指针会指向下一个元素。是两个完全不同的操作符,它们有不同的作用和语义。是一个递增运算符,它是对指针进行递增操作。数组名可以看作是指向数组首元素的常量指针。是一个算术运算符,它是将指针进行偏移,而。:表示将指针(或者数组名)往后偏移。则是取出该地址处的元素的值。指向的位置向后移动一个元素。表示数组的首地址偏移。

2024-03-29 11:21:34 264

原创 C语言实践:数组初始化、排序与统计

【代码】C语言实践:数组初始化、排序与统计。

2024-03-28 22:09:23 131

原创 二维数组:定义、初始化与遍历

二维数组是数组的一种,它可以理解为一个数组的数组。这样就创建了一个3行4列的整数型二维数组。通过本文的介绍,我们了解了二维数组的定义、初始化和遍历方法。二维数组是一种非常实用的数据结构,能够有效地组织和处理多维数据。

2024-03-28 15:22:24 320

原创 选择排序和冒泡排序

选择排序和冒泡排序虽然简单,但在某些场景下仍然具有一定的实用价值。它们的实现原理清晰易懂,适用于小规模数据的排序。但需要注意的是,选择排序和冒泡排序的时间复杂度都为O(n^2),因此在处理大规模数据时可能效率较低。在实际应用中,我们可以根据具体情况选择更高效的排序算法,如快速排序、归并排序等,以满足不同的需求。

2024-03-28 14:42:38 147

空空如也

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

TA关注的人

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