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 数据流与工作逻辑

  1. 数据采集层​:STM32主控循环读取各个传感器的数据。
  2. 数据处理层​:对原始数据进行滤波、校准和计算,得到有意义的物理量(如℃、%RH、Lux、空气质量等级)。
  3. 本地显示层​:处理后的数据通过I2C协议发送到OLED屏幕进行刷新显示。
  4. 远程通信层​:STM32通过串口将数据按照自定义协议格式发送给蓝牙模块,再由蓝牙传输至手机小程序。手机下发的控制指令(如布防)也通过此路径逆向传输给STM32。

逻辑控制层​:主控根据当前系统模式(布防/撤防)和传感器状态(是否检测到人)执行相应的动作,如控制蜂鸣器。

  • 本地显示效果:

    屏幕第一页显示:温度: 26.5℃湿度: 45%光照: 256 Lux

    屏幕循环显示气体数据:Air Q: GoodGas: NonePM2.5: 15Smoke: 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单片机家庭环境监测系统的更多相关文章

  1. 嵌入式系统及应用课程设计——基于STM32的温湿度监测系统

    大三上学期期末总结,嗯,没错上学期,写在新学期开始,hhh. 上学期学了一门嵌入式系统及应用的课程,期末的课程设计题目是基于STM32的温湿度监测系统. 记得刚开始做课程设计的时候,听说先设计画出原理 ...

  2. 单片机DIY制作-基于STM32单片机甲醛二氧化碳温度湿度采集系统

    基于STM32单片机甲醛二氧化碳温度湿度采集系统 实践制作DIY-GC008-甲醛二氧化碳温度湿度采集系统 一.功能说明: 基于STM32单片机设计-甲醛二氧化碳温度湿度采集系统 二.功能介绍: 1. ...

  3. 基于stm32的水质监测系统项目基础部分详细记录

    基于stm32的水质监测系统项目基础部分详细记录 软件环境:MDK5 硬件环境:STM32F103ZET6 开发板.颜色传感器.串口屏.串口打印机 搭建工程模板 在进行项目软件的撰写时,首先新建一个基 ...

  4. 基于STM32单片机光学指纹识别模块(FPM10A)全教程(基于C语言)

    本文转载,其来源在参考中:1,稍加修改,因为近期使用到这个模块,故而加以整理! 1.平台 首先我使用的是 奋斗 STM32 开发板 MINI板 基于STM32单片机光学指纹识别模块(FPM10A)全教 ...

  5. 基于STM32单片机的简单红外循迹的实现

    初步接触STM32,采用两路红外传感器实现小车循迹,稍显简略,如有不好的地方,欢迎大家指点改正

  6. STM32单片机应用与全案例实践 /stm32自学笔记 第二版 pdf

    STM32单片机应用与全案例实践pdf https://pan.baidu.com/s/16WrivuLcHvLTwS__Zcwl6Q 4rj3 stm32自学笔记 第二版 pdf https://p ...

  7. STM32单片机最小系统

    1.单片机最小系统的组成部分 STM32单片机最小系统由①主芯片,②上电复位电路,③时钟电路,④电源供电电路组成.同时一个基本完整的单片机功能还应包括下载电路和LED指示电路. 2.单片机主芯片 单片 ...

  8. 基于STM32+华为云IOT设计智能称重系统

    摘要:选择部署多个重量传感器和必要的算法.通过WiFi 通信模块.GPS定位模块,采集车辆称重数据一地理位置信息,并通过网络发送至云平台,设计图形化UI界面展示称重.地图位置等重要信息,实现对称重系统 ...

  9. [每日电路图] 1、基于AT89C52单片机最小系统接口电路【转】

              come from:http://www.21ic.com/dianlu/basis/interface/2015-04-21/621607.htm AT89C52是美国Atmel ...

  10. STM32单片机学习心得——概述

    我校的课程真是跟不上时代发展,甚至还在教授8051/8052单片机的内容,于是不甘寂寞的我就自己踏入了STM32单片机的坑-- 首先,我现在大二,刚学完模拟电子技术,还没有学习数字电路技术,于是自学单 ...

随机推荐

  1. BAPI_OUTB_DELIVERY_CHANGE 删除DN

    """回滚数据 删除DN, CLEAR: l_header_data_chg,l_header_control_chg. l_header_data_chg-deliv_ ...

  2. Result Maps collection does not contain value for java.util.HashMap

    前言 查询报错 Result Maps collection does not contain value for java.util.HashMap 原因 SQL XML中包含此返回类型 解决 第一 ...

  3. 文件操作&深浅拷贝&异常处理

    文件操作 [1]基本流程 (1)文件操作 操作 打开读文件内容 r with open('01.txt', 'r', encoding='utf-8') as f: data = f.read() p ...

  4. 第2周2_神经网络基础之Python与向量化

    神经网络基础之Python与向量化¶ 1. 向量化¶ ① 深度学习算法中,数据量很大,在程序中应该尽量减少使用loop循环语句,而可以使用向量运算来提高程序运行速度. ② 向量化(Vectorizat ...

  5. Elastic学习之旅 (7) 聚合分析

    大家好,我是Edison. 上一篇:ES的Query DSL 什么是ES的聚合 Elastic除搜索之外,还提供针对ES数据的统计分析功能,具有较高的实时性. 通过聚合,我们可以得到一个数据的概览,它 ...

  6. VS2019 添加时没有区域(Areas) 通用-MVC 下也没有域

    https://www.cnblogs.com/shijiehaiyang/p/13035250.html VS2019 似乎和之前版本不同,想要直接添加区域时,发现没有这一个选择1.按网上所提供意见 ...

  7. 前端开发系列083-Node篇之http

    本文对Node的内置模块http进行介绍,包括该模块的基本情况和简单使用. 一.模块简介 http是Node的内置核心模块,包含了对HTTP处理的封装. 在Nodejs文件中可以直接在代码里通过var ...

  8. 前端开发系列030-基础篇之JavaScript函数基本

    一.函数的创建和结构 函数的定义:函数是JavaScript的基础模块单元,包含一组语句,用于代码复用.信息隐蔽和组合调用. 函数的创建:在javaScript语言中,可以说函数是其最重要也最成功的设 ...

  9. leetcode 1047 双出字符串中的相邻元素

    简介 如果能想到栈的话,说明你的基础足够扎实. 我没有想到,我想到的是双向链表.我就是一个弟弟 思路 两个前后指针指向一个双向循环链表,然后判断是否相等相等的话,前一个指针前移,后一个指针后移,中间的 ...

  10. 生成库文件 virtual studio

    简介 如果我们把我们要常用的文件生成自己的动态库的话,我们将加速我们的第一代开发过程. 核心内容 参考链接: https://www.cnblogs.com/lanhaicode/p/10798385 ...