基于stm32单片机家庭环境监测系统
1.演示视频
基于stm32单片机家庭环境监测系统视频演示_哔哩哔哩_bilibili
2. 项目介绍
本项目基于STM32F103C8T6最小系统板,打造了一个功能强大、显示直观的家庭环境监测系统。系统集成了温湿度、光照强度、多种气体、人体感应等传感器,并通过OLED屏幕本地实时显示数据,同时支持手机蓝牙小程序远程监控与告警。它不仅是一个全面的环境数据采集站,更是一个具备布防/撤防功能的简易家庭安防系统。
3. 系统功能亮点
- 环境多参数监测:实时采集温度、湿度、光照强度、空气质量(CO/CO2/烟雾等综合指标)。
- 人体红外感应:检测指定区域内是否有人体活动。
- 双模远程通信:支持ESP32 Wi-Fi模块(预留扩展接口)和HC-05/06蓝牙模块与手机连接。
- 手机小程序监控:通过自开发的微信小程序,可远程查看所有传感器数据,并进行系统控制。
- 智能安防布防:具备“布防”和“撤防”两种模式。在布防模式下,检测到人体入侵将触发本地蜂鸣器高声警报并推送手机提醒。
- 交互与提示:配备四个功能按键和一个蜂鸣器,方便本地操作和声音提示。
4.硬件设计
4.1 硬件组成 (BOM List)
| 模块名称 | 型号/规格 | 通信协议 | 功能 |
|---|---|---|---|
| 主控芯片 | STM32F103C8T6 (最小系统板) | - | 系统核心,负责数据处理与逻辑控制 |
| 显示模块 | 0.96英寸 OLED屏 | I2C | 本地实时显示所有传感器数据及系统状态 |
| 温湿度传感器 | AHT20 | I2C | 高精度测量环境温度和湿度 |
| 光照传感器 | GY-30 (BH1750) | I2C | 检测环境光照强度 (Lux) |
| 气体传感器 | MQ-135 | 模拟/数字 | 综合检测空气质量、CO2、CO、烟雾、苯等有害气体 |
| 人体红外传感器 | HC-SR501 | 数字GPIO | 检测人体移动 |
| 蓝牙模块 | HC-05 或 HC-06 | UART | 与手机小程序进行串口蓝牙通信 |
| Wi-Fi模块 | ESP-01S (ESP8266) 或 ESP32 | UART | 预留物联网扩展接口,可接入云平台 |
| 声学提示 | 有源蜂鸣器 | GPIO | 发出警报和提示音 |
| 输入控制 | 4x轻触按键 | GPIO | 本地切换模式、设置参数等 |
| 供电接口 | Type-C | - | 5V供电,并配有电源开关 |
4.2主要芯片介绍
STM32F103C8T6介绍
STM32F103C8T6是一款由意法半导体公司(ST)推出的基于Cortex-M3内核的32位微控制器,硬件采用LQFP48封装,属于ST公司微控制器中的STM32系列。


AHT20温湿度传感器介绍
AHT20是一款高精度数字温湿度传感器,采用I2C通信(地址0x38),供电需3.3V。其温度精度±0.3℃,湿度精度±2%RH,出厂已校准,即插即用。相比DHT11,精度更高、通信更稳定,是环境监测项目的理想选择。


BH1750光照强度传感器介绍
BH1750FVI 是一款数字式环境光强度传感器。它通过 I2C 接口直接输出光照度值(单位:Lux),测量范围 1 - 65535 lx。具有高精度、无需外部元件等优点,是替代光敏电阻的理想选择,广泛应用于自动背光调节和智能照明系统。


ECB01H2S蓝牙模块介绍
ECB01H2S 是一款基于蓝牙5.0的串口透传模块。它将复杂的蓝牙协议封装成简单的串口通信,用户只需通过AT指令进行配置,即可让主控设备(如STM32)通过串口与手机等蓝牙主机实现无线数据双向传输,极大简化了无线通信功能的开发流程,广泛应用于智能硬件和数据传输项目。


I2C OLED显示屏介绍
该屏幕拥有128x64高分辨率,采用I2C接口,仅需两根信号线即可驱动。其像素点自发光,显示黑色时功耗极低,无需背光,视觉效果清晰锐利,对比度高,是嵌入式项目中最受欢迎的小型显示方案。


ESP8266WiFi模块介绍
ESP8266 是一款低成本、高性能的Wi-Fi SOC芯片模块。其核心功能是通过串口AT指令与单片机通信,轻松实现设备联网。它内置了TCP/IP协议栈,可作为独立MCU或Wi-Fi适配器使用,是物联网项目中实现无线连接最经典、性价比最高的解决方案之一。

5.系统设计与实现
5.1整体系统设计

5.2 数据流与工作逻辑
- 数据采集层:STM32主控循环读取各个传感器的数据。
- 数据处理层:对原始数据进行滤波、校准和计算,得到有意义的物理量(如℃、%RH、Lux、空气质量等级)。
- 本地显示层:处理后的数据通过I2C协议发送到OLED屏幕进行刷新显示。
- 远程通信层:STM32通过串口将数据按照自定义协议格式发送给蓝牙模块,再由蓝牙传输至手机小程序。手机下发的控制指令(如布防)也通过此路径逆向传输给STM32。
逻辑控制层:主控根据当前系统模式(布防/撤防)和传感器状态(是否检测到人)执行相应的动作,如控制蜂鸣器。
- 本地显示效果:
屏幕第一页显示:温度: 26.5℃, 湿度: 45%, 光照: 256 Lux。
屏幕循环显示气体数据:Air Q: Good, Gas: None, PM2.5: 15, Smoke: Low。
人体检测状态:P: Yes (有人) 或 P: No (无人)。
安防状态:Security On (布防) 或 Security Off (撤防)。
- 手机监控:
手机小程序成功连接蓝牙后,界面同步显示所有环境数据。
设有“布防/撤防”切换按钮。
在布防状态下,若检测到人体,手机端会弹出弹窗警报,并显示“警戒中!”。
- 安防联动:
撤防模式:检测到人体,仅在屏幕和手机端显示“有人”,无声音警报。(适合家中有人时)
布防模式:检测到人体,蜂鸣器立即鸣叫,同时手机端弹出警报。(适合出门或夜间)
6.代码展示
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body - 简化版
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "oled.h"
#include "temp_humi.h"
#include "gas_sensor.h"
#include "light_sensor.h"
#include "bluetooth.h"
#include "gas_display.h"
#include "buzzer.h"
#include <stdio.h>
#include <string.h> /* Private variables ---------------------------------------------------------*/
I2C_HandleTypeDef hi2c1;
ADC_HandleTypeDef hadc1;
UART_HandleTypeDef huart1; /* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
void MX_GPIO_Init(void);
void MX_I2C1_Init(void);
void MX_ADC1_Init(void);
void MX_USART1_UART_Init(void); /**
* @brief IR传感器初始化 - 简化版
* @param None
* @retval None
*/
void IR_Sensor_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0}; __HAL_RCC_GPIOB_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
} /**
* @brief 检测人体存在 - 简化版
* @param None
* @retval 1: 检测到人体, 0: 未检测到人体
*/
uint8_t IR_Sensor_Detect(void)
{
return (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_9) == GPIO_PIN_RESET) ? 1 : 0;
} /**
* @brief 应用程序入口点
* @retval int
*/
int main(void)
{
/* 初始化HAL库 */
HAL_Init(); /* 配置系统时钟 */
SystemClock_Config(); /* 初始化所有外设 */
MX_GPIO_Init();
MX_I2C1_Init();
MX_ADC1_Init();
MX_USART1_UART_Init(); /* 初始化所有传感器和外设 */
OLED_Init();
TEMP_HUMI_Init();
GAS_SENSOR_Init();
LIGHT_SENSOR_Init();
IR_Sensor_Init();
Bluetooth_Init();
BUZZER_Init(); /* 显示初始屏幕 */
OLED_Clear();
OLED_ShowString(0, 0, "Starting...", 12);
OLED_Refresh(); /* 初始化变量 */
float temperature = 0.0f;
float humidity = 0.0f;
float light = 0.0f;
uint8_t ir_status = 0;
uint8_t last_ir_status = 0;
uint8_t bt_send_counter = 0; /* 创建气体数据结构 */
GAS_DATA gas_data = {0}; /* 气体传感器初始校准 */
GAS_SENSOR_Calibrate(400.0f); /* 手动设置一些初始值,确保数据不为空 */
gas_data.raw_ppm = 500.0f;
gas_data.co2_equivalent = 400.0f;
gas_data.combustible_gas = 150.0f;
gas_data.smoke_density = 75.0f;
gas_data.pm25 = 50.0f;
gas_data.aqi = 100;
gas_data.change_rate = 0.5f;
gas_data.gas_type = GAS_TYPE_NORMAL;
gas_data.safety_level = SAFETY_LEVEL_SAFE;
gas_data.leak_detected = 0;
gas_data.fire_risk = 2; /* 无限循环 */
while (1)
{
/* 检查布防/撤防状态是否改变 */
if (Bluetooth_GetAndClearStatusChanged()) {
uint8_t armed_status = Bluetooth_GetArmedStatus();
DISPLAY_ArmedStatus(armed_status, 3000); if (armed_status) {
BUZZER_LoudAlarm();
} else {
BUZZER_Beep(100);
}
} /* 读取传感器数据 */
TEMP_HUMI_ReadData(&temperature, &humidity);
if (LIGHT_SENSOR_IsConnected()) {
LIGHT_SENSOR_ReadLight(&light);
}
ir_status = IR_Sensor_Detect(); /* 更新气体传感器数据 - 确保每次循环都更新 */
uint16_t adc_value = GAS_SENSOR_Read();
if (adc_value > 0) {
GAS_SENSOR_UpdateData(&gas_data);
} /* 人体检测处理 */
if (ir_status && !last_ir_status) {
/* 更新显示 */
DISPLAY_UpdateEnvData(temperature, humidity, light, ir_status);
DISPLAY_GasData(&gas_data); /* 发送数据到蓝牙 - 恢复原来的两次发送格式 */
/* 第一次发送基本环境数据 */
char bt_data1[150];
sprintf(bt_data1, "{\"temp\":%.1f,\"humi\":%.1f,\"light\":%.1f,\"human\":%d,\"aqi\":%d,\"pm25\":%.1f}\r\n",
temperature, humidity, light, ir_status, gas_data.aqi, gas_data.pm25);
Bluetooth_SendString(bt_data1); /* 短暂延时,确保第一条数据发送完成 */
HAL_Delay(20); /* 第二次发送气体详细数据 */
char bt_data2[150];
sprintf(bt_data2, "{\"co2\":%.1f,\"ppm\":%.1f,\"gas_type\":%d,\"safety\":%d,\"leak\":%d,\"fire\":%d,\"rate\":%.2f}\r\n",
gas_data.co2_equivalent, gas_data.raw_ppm, gas_data.gas_type,
gas_data.safety_level, gas_data.leak_detected, gas_data.fire_risk, gas_data.change_rate);
Bluetooth_SendString(bt_data2); /* 布防状态下发出警报 */
if (Bluetooth_GetArmedStatus()) {
BUZZER_EmergencyAlarm();
}
}
last_ir_status = ir_status; /* 更新显示 */
DISPLAY_UpdateEnvData(temperature, humidity, light, ir_status);
DISPLAY_GasData(&gas_data); /* 处理蓝牙数据 */
Bluetooth_Process(); /* 每5秒通过蓝牙发送环境数据 */
if (++bt_send_counter >= 5) {
bt_send_counter = 0; /* 恢复原来的两次发送格式 */
/* 第一次发送基本环境数据 */
char bt_data1[150];
sprintf(bt_data1, "{\"temp\":%.1f,\"humi\":%.1f,\"light\":%.1f,\"human\":%d,\"aqi\":%d,\"pm25\":%.1f}\r\n",
temperature, humidity, light, ir_status, gas_data.aqi, gas_data.pm25);
Bluetooth_SendString(bt_data1); /* 短暂延时,确保第一条数据发送完成 */
HAL_Delay(50); /* 第二次发送气体详细数据 */
char bt_data2[150];
sprintf(bt_data2, "{\"co2\":%.1f,\"ppm\":%.1f,\"gas_type\":%d,\"safety\":%d,\"leak\":%d,\"fire\":%d,\"rate\":%.2f}\r\n",
gas_data.co2_equivalent, gas_data.raw_ppm, gas_data.gas_type,
gas_data.safety_level, gas_data.leak_detected, gas_data.fire_risk, gas_data.change_rate);
Bluetooth_SendString(bt_data2);
} /* 切换LED指示灯状态 */
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13); /* 延时1秒 */
HAL_Delay(1000);
}
} /**
* @brief 系统时钟配置
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
HAL_RCC_OscConfig(&RCC_OscInitStruct); RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2); /* 配置ADC时钟 */
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
} /**
* @brief GPIO初始化函数
* @param None
* @retval None
*/
void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0}; /* 使能GPIO时钟 */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE(); /* 配置PC13引脚为输出 */
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
GPIO_InitStruct.Pin = GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); /* 配置PA0引脚为模拟输入(气体传感器) */
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
} /**
* @brief I2C1初始化函数
* @param None
* @retval None
*/
void MX_I2C1_Init(void)
{
hi2c1.Instance = I2C1;
hi2c1.Init.ClockSpeed = 100000;
hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
hi2c1.Init.OwnAddress1 = 0;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; HAL_I2C_Init(&hi2c1);
} /**
* @brief ADC1初始化函数
* @param None
* @retval None
*/
void MX_ADC1_Init(void)
{
ADC_ChannelConfTypeDef sConfig = {0}; /* ADC1基本配置 */
hadc1.Instance = ADC1;
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 1;
HAL_ADC_Init(&hadc1); /* 配置ADC通道0(PA0引脚)- 气体传感器 */
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_55CYCLES_5;
HAL_ADC_ConfigChannel(&hadc1, &sConfig); /* 校准ADC */
HAL_ADCEx_Calibration_Start(&hadc1);
} /**
* @brief USART1初始化函数
* @param None
* @retval None
*/
void MX_USART1_UART_Init(void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 9600;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16; HAL_UART_Init(&huart1); /* 启用UART接收中断 */
HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
} /**
* @brief 错误处理函数
* @retval None
*/
void Error_Handler(void)
{
__disable_irq();
while (1)
{
}
} #ifdef USE_FULL_ASSERT
void assert_failed(uint8_t *file, uint32_t line)
{
/* 用户可以添加自己的实现来报告文件名和行号 */
}
#endif /* USE_FULL_ASSERT */
7.原理图

欢迎在评论区交流讨论!
基于stm32单片机家庭环境监测系统的更多相关文章
- 嵌入式系统及应用课程设计——基于STM32的温湿度监测系统
大三上学期期末总结,嗯,没错上学期,写在新学期开始,hhh. 上学期学了一门嵌入式系统及应用的课程,期末的课程设计题目是基于STM32的温湿度监测系统. 记得刚开始做课程设计的时候,听说先设计画出原理 ...
- 单片机DIY制作-基于STM32单片机甲醛二氧化碳温度湿度采集系统
基于STM32单片机甲醛二氧化碳温度湿度采集系统 实践制作DIY-GC008-甲醛二氧化碳温度湿度采集系统 一.功能说明: 基于STM32单片机设计-甲醛二氧化碳温度湿度采集系统 二.功能介绍: 1. ...
- 基于stm32的水质监测系统项目基础部分详细记录
基于stm32的水质监测系统项目基础部分详细记录 软件环境:MDK5 硬件环境:STM32F103ZET6 开发板.颜色传感器.串口屏.串口打印机 搭建工程模板 在进行项目软件的撰写时,首先新建一个基 ...
- 基于STM32单片机光学指纹识别模块(FPM10A)全教程(基于C语言)
本文转载,其来源在参考中:1,稍加修改,因为近期使用到这个模块,故而加以整理! 1.平台 首先我使用的是 奋斗 STM32 开发板 MINI板 基于STM32单片机光学指纹识别模块(FPM10A)全教 ...
- 基于STM32单片机的简单红外循迹的实现
初步接触STM32,采用两路红外传感器实现小车循迹,稍显简略,如有不好的地方,欢迎大家指点改正
- STM32单片机应用与全案例实践 /stm32自学笔记 第二版 pdf
STM32单片机应用与全案例实践pdf https://pan.baidu.com/s/16WrivuLcHvLTwS__Zcwl6Q 4rj3 stm32自学笔记 第二版 pdf https://p ...
- STM32单片机最小系统
1.单片机最小系统的组成部分 STM32单片机最小系统由①主芯片,②上电复位电路,③时钟电路,④电源供电电路组成.同时一个基本完整的单片机功能还应包括下载电路和LED指示电路. 2.单片机主芯片 单片 ...
- 基于STM32+华为云IOT设计智能称重系统
摘要:选择部署多个重量传感器和必要的算法.通过WiFi 通信模块.GPS定位模块,采集车辆称重数据一地理位置信息,并通过网络发送至云平台,设计图形化UI界面展示称重.地图位置等重要信息,实现对称重系统 ...
- [每日电路图] 1、基于AT89C52单片机最小系统接口电路【转】
come from:http://www.21ic.com/dianlu/basis/interface/2015-04-21/621607.htm AT89C52是美国Atmel ...
- STM32单片机学习心得——概述
我校的课程真是跟不上时代发展,甚至还在教授8051/8052单片机的内容,于是不甘寂寞的我就自己踏入了STM32单片机的坑-- 首先,我现在大二,刚学完模拟电子技术,还没有学习数字电路技术,于是自学单 ...
随机推荐
- BAPI_OUTB_DELIVERY_CHANGE 删除DN
"""回滚数据 删除DN, CLEAR: l_header_data_chg,l_header_control_chg. l_header_data_chg-deliv_ ...
- Result Maps collection does not contain value for java.util.HashMap
前言 查询报错 Result Maps collection does not contain value for java.util.HashMap 原因 SQL XML中包含此返回类型 解决 第一 ...
- 文件操作&深浅拷贝&异常处理
文件操作 [1]基本流程 (1)文件操作 操作 打开读文件内容 r with open('01.txt', 'r', encoding='utf-8') as f: data = f.read() p ...
- 第2周2_神经网络基础之Python与向量化
神经网络基础之Python与向量化¶ 1. 向量化¶ ① 深度学习算法中,数据量很大,在程序中应该尽量减少使用loop循环语句,而可以使用向量运算来提高程序运行速度. ② 向量化(Vectorizat ...
- Elastic学习之旅 (7) 聚合分析
大家好,我是Edison. 上一篇:ES的Query DSL 什么是ES的聚合 Elastic除搜索之外,还提供针对ES数据的统计分析功能,具有较高的实时性. 通过聚合,我们可以得到一个数据的概览,它 ...
- VS2019 添加时没有区域(Areas) 通用-MVC 下也没有域
https://www.cnblogs.com/shijiehaiyang/p/13035250.html VS2019 似乎和之前版本不同,想要直接添加区域时,发现没有这一个选择1.按网上所提供意见 ...
- 前端开发系列083-Node篇之http
本文对Node的内置模块http进行介绍,包括该模块的基本情况和简单使用. 一.模块简介 http是Node的内置核心模块,包含了对HTTP处理的封装. 在Nodejs文件中可以直接在代码里通过var ...
- 前端开发系列030-基础篇之JavaScript函数基本
一.函数的创建和结构 函数的定义:函数是JavaScript的基础模块单元,包含一组语句,用于代码复用.信息隐蔽和组合调用. 函数的创建:在javaScript语言中,可以说函数是其最重要也最成功的设 ...
- leetcode 1047 双出字符串中的相邻元素
简介 如果能想到栈的话,说明你的基础足够扎实. 我没有想到,我想到的是双向链表.我就是一个弟弟 思路 两个前后指针指向一个双向循环链表,然后判断是否相等相等的话,前一个指针前移,后一个指针后移,中间的 ...
- 生成库文件 virtual studio
简介 如果我们把我们要常用的文件生成自己的动态库的话,我们将加速我们的第一代开发过程. 核心内容 参考链接: https://www.cnblogs.com/lanhaicode/p/10798385 ...

