Windows下网络编与ESP8266-WiFi通信(win32-API)
一、前言
络编程是指编写程序使不同计算机之间能够通过网络进行通信和数据交换。网络编程涉及使用网络协议和编程接口来建立、管理和终止网络上的数据通信。在这一领域中,TCP/IP协议族是核心组成部分,尤其TCP(传输控制协议)是面向连接的协议,为数据包在网络上传输提供可靠的保障,确保数据的准确性和顺序性。TCP客户端与TCP服务器是网络通信模型中的两个角色:服务器监听特定的端口,等待客户端的连接请求;一旦连接建立,双方即可进行双向通信。
在Windows下创建TCP服务器涉及使用Windows Socket(Winsock)API,这是一个用于网络编程的接口,允许应用程序通过TCP/IP协议栈发送和接收数据。
网络编程涵盖了客户端和服务器的交互机制。在这一模型中,服务器通常处于被动监听状态,等待客户端主动发起连接请求。一旦连接建立,服务器与客户端便能通过TCP协议进行可靠的数据交换。TCP协议通过三次握手建立连接,四次挥手断开连接,确保数据的有序传输和完整性检查。
在Windows环境下,创建TCP服务器涉及以下几个关键步骤:
- 初始化Winsock:使用
WSAStartup()
函数初始化Winsock库,这是网络编程前的必要步骤。 - 创建套接字:使用
socket()
函数创建一个套接字,它将成为服务器与客户端通信的端点。 - 绑定套接字:使用
bind()
函数将套接字与本地IP地址和端口号关联。服务器通常绑定到一个固定的端口,以便客户端可以发现并连接。 - 监听连接:使用
listen()
函数将套接字置于监听状态,准备接受来自客户端的连接请求。 - 接受连接:使用
accept()
函数等待并接受客户端的连接请求。当客户端连接时,accept()
会返回一个新的套接字,用于与特定客户端通信。 - 读写数据:使用
recv()
和send()
函数(或recvfrom()
和sendto()
在UDP情况下)读取和发送数据。在TCP连接中,数据以流的形式传输,无需关注数据包的边界。 - 关闭连接:当通信完成后,使用
closesocket()
函数关闭套接字,释放资源。 - 清理Winsock:使用
WSACleanup()
函数清理Winsock库。
ESP8266 WiFi模块是一款由乐鑫科技(Espressif Systems)推出的低成本、高性能的无线通信模块,专为物联网(IoT)应用设计。该模块内置了Tensilica L106超低功耗32位微控制器,拥有80MHz的主频,集成了Wi-Fi 802.11 b/g/n标准的无线网络功能,支持多种加密方式,如WEP、WPA/WPA2、WPA-PSK、WPA2-PSK等。ESP8266因其体积小、功耗低、价格便宜以及集成度高,迅速成为了物联网开发者的首选解决方案之一。
ESP8266模块支持TCP/IP协议栈,这意味着它可以作为TCP客户端或服务器,与其他设备进行网络通信。开发者可以利用ESP8266的AT指令集,或直接使用SDK进行固件开发,从而实现数据的传输与接收。除了TCP,ESP8266也支持UDP、HTTP、HTTPS、MQTT等多种网络协议,这使得它能够在各种网络环境中灵活应用。
由于ESP8266的强大功能和易用性,它已经成为许多物联网项目的基础,无论是业余爱好者还是专业开发者,都能够快速构建起具有网络连接能力的智能设备。
下面是一个C语言代码示例,展示如何在Windows下创建一个TCP服务器,等待ESP8266 WiFi模块的连接,并与之通信:
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>#pragma comment(lib, "ws2_32.lib")int main() {WSADATA wsaData;SOCKET serverSocket;sockaddr_in serverAddress;int addrLen = sizeof(serverAddress);char buffer[1024];// 初始化WinsockWSAStartup(MAKEWORD(2, 2), &wsaData);// 创建套接字serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);// 设置地址和端口serverAddress.sin_family = AF_INET;serverAddress.sin_port = htons(8080);serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);// 绑定套接字bind(serverSocket, (SOCKADDR*)&serverAddress, sizeof(serverAddress));// 开始监听listen(serverSocket, SOMAXCONN);// 接受连接SOCKET clientSocket = accept(serverSocket, (SOCKADDR*)&serverAddress, &addrLen);// 通信while (1) {int bytesReceived = recv(clientSocket, buffer, 1024, 0);if (bytesReceived > 0) {buffer[bytesReceived] = '\0';printf("Received: %s\n", buffer);send(clientSocket, buffer, bytesReceived, 0);}else {break;}}// 关闭连接closesocket(clientSocket);closesocket(serverSocket);// 清理WinsockWSACleanup();return 0;
}
通过上述步骤和示例代码,创建了一个能够等待ESP8266 WiFi模块连接的TCP服务器,实现了基本的数据收发功能。对于初学者而言,理解网络编程的基础概念,如TCP协议的工作原理和Winsock API的使用,是学习ESP8266 WiFi编程的重要一步。掌握了这些知识后,可以更深入地探索物联网(IoT)项目,利用WiFi模块实现远程数据采集、监控以及其他智能应用。
二、实例代码
2.1 网络编程相关的函数
网络编程在Windows环境下主要依赖于Winsock(Windows Socket)API,是微软实现的基于Berkeley sockets API的一个版本,用于在Windows操作系统上进行网络编程。Winsock API提供了丰富的函数集,用于创建、配置、管理和关闭套接字(sockets),以及通过网络进行数据的发送和接收。
以下是几个核心的Winsock函数及其参数详解:
1. WSAStartup
功能:初始化Winsock DLL。
语法:
int WSAStartup(WORD wVersionRequired,LPWSADATA lpWSAData
);
参数:
wVersionRequired
:指定需要的Winsock版本。lpWSAData
:指向WSADATA结构的指针,用于返回Winsock DLL的信息。
2. WSACleanup
功能:卸载并关闭Winsock DLL。
语法:
int WSACleanup(void);
3. socket
功能:创建一个套接字。
语法:
SOCKET socket(int af,int type,int protocol
);
参数:
af
:地址家族,如AF_INET(IPv4)或AF_INET6(IPv6)。type
:套接字类型,如SOCK_STREAM(TCP)或SOCK_DGRAM(UDP)。protocol
:协议类型,如IPPROTO_TCP或IPPROTO_UDP,通常可以设置为0。
4. bind
功能:将套接字绑定到一个本地地址。
语法:
int bind(SOCKET s,const struct sockaddr *name,int namelen
);
参数:
s
:套接字描述符。name
:指向sockaddr结构的指针,包含要绑定的地址和端口号。namelen
:地址结构的大小。
5. listen
功能:将套接字置于监听状态,准备接受连接请求。
语法:
int listen(SOCKET s,int backlog
);
参数:
s
:套接字描述符。backlog
:连接队列的最大长度。
6. accept
功能:接受传入的连接请求,创建新的套接字用于通信。
语法:
SOCKET accept(SOCKET s,struct sockaddr *addr,int *addrlen
);
参数:
s
:监听状态的套接字描述符。addr
:指向sockaddr结构的指针,用于接收客户端地址信息。addrlen
:指向整型变量的指针,用于指定和返回地址结构的大小。
7. connect
功能:主动发起连接到远程主机。
语法:
int connect(SOCKET s,const struct sockaddr *name,int namelen
);
参数:
s
:套接字描述符。name
:指向sockaddr结构的指针,包含远程地址和端口。namelen
:地址结构的大小。
8. send
和 recv
功能:发送和接收数据。
语法:
int send(SOCKET s,const char *buf,int len,int flags
);int recv(SOCKET s,char *buf,int len,int flags
);
参数:
s
:套接字描述符。buf
:指向数据缓冲区的指针。len
:数据长度。flags
:控制选项,通常为0。
9. closesocket
功能:关闭套接字。
语法:
int closesocket(SOCKET s
);
参数:
s
:要关闭的套接字描述符。
10. gethostbyname
功能:将主机名转换为IP地址。
语法:
struct hostent *gethostbyname(const char *name
);
参数:
name
:主机名或域名。
11. inet_addr
功能:将点分十进制IP地址字符串转换为网络字节序的二进制格式。
语法:
in_addr_t inet_addr(const char *cp
);
参数:
cp
:点分十进制IP地址字符串。
以上函数构成了网络编程的基础,它们使得在Windows平台上进行网络通信变得可能。正确理解和使用这些函数是开发网络应用程序的关键。
2.2 创建一个TCP服务器
开发环境:在Windows下安装一个VS即可。我当前采用的版本是VS2020。
在Windows环境下,创建一个能够处理多个客户端连接的TCP服务器通常需要使用多线程。下面是一个使用C语言和Winsock库实现的多线程TCP服务器的示例代码。服务器将监听客户端的连接请求,每当有新的客户端连接时,服务器将启动一个新的线程来处理与该客户端的通信,读取并打印客户端发送的消息。
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>#pragma comment(lib, "ws2_32.lib")#define DEFAULT_PORT 8080
#define BACKLOG 10
#define BUFFER_SIZE 1024void ErrorHandling(const char* message);
void ClientHandler(SOCKET clientSocket);int main() {WSADATA wsaData;SOCKET serverSocket;SOCKET clientSocket;struct sockaddr_in serverAddr;struct sockaddr_in clientAddr;int addrLen = sizeof(clientAddr);int result;// 初始化Winsockif (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {ErrorHandling("WSAStartup() failed!");}// 创建服务器套接字serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (serverSocket == INVALID_SOCKET) {ErrorHandling("socket() failed!");}// 准备服务器地址结构serverAddr.sin_family = AF_INET;serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);serverAddr.sin_port = htons(DEFAULT_PORT);// 绑定套接字到地址if (bind(serverSocket, (SOCKADDR*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {ErrorHandling("bind() failed!");}// 监听连接if (listen(serverSocket, BACKLOG) == SOCKET_ERROR) {ErrorHandling("listen() failed!");}printf("Server is listening on port %d...\n", DEFAULT_PORT);// 主循环,等待客户端连接while (1) {clientSocket = accept(serverSocket, (SOCKADDR*)&clientAddr, &addrLen);if (clientSocket == INVALID_SOCKET) {ErrorHandling("accept() failed!");}printf("Client connected: %s:%d\n",inet_ntoa(clientAddr.sin_addr), ntohs(clientAddr.sin_port));// 创建新线程处理客户端HANDLE threadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ClientHandler, (LPVOID)clientSocket, 0, NULL);if (threadHandle == NULL) {ErrorHandling("CreateThread() failed!");}CloseHandle(threadHandle);}// 清理closesocket(serverSocket);WSACleanup();return 0;
}void ClientHandler(SOCKET clientSocket) {char buffer[BUFFER_SIZE];int bytesReceived;// 读取客户端数据while ((bytesReceived = recv(clientSocket, buffer, BUFFER_SIZE, 0)) > 0) {buffer[bytesReceived] = '\0'; // 确保字符串以空字符结尾printf("Received from client: %s\n", buffer);}if (bytesReceived == 0) {printf("Client disconnected.\n");} else if (bytesReceived == SOCKET_ERROR) {ErrorHandling("recv() failed!");}// 关闭客户端套接字closesocket(clientSocket);
}void ErrorHandling(const char* message) {printf("%s\n", message);WSACleanup();exit(1);
}
在上面的代码中,main()
函数初始化Winsock库,创建并配置服务器套接字,然后开始监听客户端的连接请求。每当有新的客户端连接,main()
函数就调用CreateThread()
来创建一个新的线程执行ClientHandler()
函数。ClientHandler()
函数负责接收并打印客户端发送的消息,直到客户端断开连接或发生错误。
2.3 创建TCP客户端连接服务器
开发环境:在Windows下安装一个VS即可。我当前采用的版本是VS2020。
创建一个TCP客户端,使其能够连接到指定的服务器并在连接成功后定期发送消息,可以通过使用Winsock库在C语言中实现。
下面是一个示例代码,展示如何创建一个TCP客户端,连接到服务器,并每隔一定时间(本例中为5秒)向服务器发送一条消息。
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <windows.h>
#include <string.h>#pragma comment(lib, "ws2_32.lib")#define SERVER_IP "127.0.0.1"
#define SERVER_PORT 8080
#define MESSAGE "Hello from the client!"
#define BUFFER_SIZE 1024
#define SEND_INTERVAL 5000 // 5 seconds in millisecondsvoid ErrorHandling(const char* message);int main() {WSADATA wsaData;SOCKET clientSocket;struct sockaddr_in serverAddr;char buffer[BUFFER_SIZE];int bytesSent;int result;// Initialize Winsockif (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {ErrorHandling("WSAStartup() failed!");}// Create a socketclientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (clientSocket == INVALID_SOCKET) {ErrorHandling("socket() failed!");}// Prepare server address structureserverAddr.sin_family = AF_INET;serverAddr.sin_port = htons(SERVER_PORT);serverAddr.sin_addr.s_addr = inet_addr(SERVER_IP);// Connect to the serverif (connect(clientSocket, (SOCKADDR*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {ErrorHandling("connect() failed!");}printf("Connected to server %s:%d\n", SERVER_IP, SERVER_PORT);// Main loop for sending messageswhile (1) {// Send message to serverbytesSent = send(clientSocket, MESSAGE, strlen(MESSAGE), 0);if (bytesSent == SOCKET_ERROR) {ErrorHandling("send() failed!");}printf("Message sent: %s\n", MESSAGE);// Sleep for the specified interval before sending next messageSleep(SEND_INTERVAL);}// Cleanupclosesocket(clientSocket);WSACleanup();return 0;
}void ErrorHandling(const char* message) {printf("%s\n", message);WSACleanup();exit(1);
}
在上述代码中,main()
函数先初始化Winsock库,创建一个套接字,使用connect()
函数连接到指定的服务器。一旦连接成功,进入一个无限循环,每隔5秒使用send()
函数向服务器发送一条消息。消息的内容是静态定义的字符串MESSAGE
。
如果服务器不在同一台机器上,要将SERVER_IP
替换为服务器的实际IP地址。 SEND_INTERVAL
常量定义了发送消息的时间间隔,单位为毫秒。
相关文章:

Windows下网络编与ESP8266-WiFi通信(win32-API)
一、前言 络编程是指编写程序使不同计算机之间能够通过网络进行通信和数据交换。网络编程涉及使用网络协议和编程接口来建立、管理和终止网络上的数据通信。在这一领域中,TCP/IP协议族是核心组成部分,尤其TCP(传输控制协议)是面向…...
【Golang】golang安装一些依赖包时总是失败
Golang安装一些依赖包失败: 比如安装gin包:go get -u github.com/gin-gonic/gin 可能会报错:连接网络失败、超时等 这时可能需要修改go的环境配置,修改代理即可: go env -w GO111MO…...

ubuntu如何监控Xvfb虚拟显示器
在Ubuntu中监控Xvfb显示器主要涉及到使用VNC服务器来远程访问这个环境。以下是一些基本步骤: 安装Xvfb和相关工具: 使用apt安装Xvfb和x11vnc,x11vnc是一个VNC服务器,可以远程访问Xvfb创建的虚拟桌面环境。 sudo apt-get install xvfb sudo ap…...

小型需求管理软件盘点:8款功能强大的工具
本文介绍了以下8款工具:PingCode、Worktile、易得云、Ping、燃草、Gitee、Monday.com、Slack。 在现代企业管理中,需求管理一直是个让人头疼的问题,特别是对于小型企业来说,选择一款合适的需求管理软件往往比想象中更复杂。如果选…...

Labelme的安装与使用教程
文章目录 一、Labelme是什么?二、安装步骤1.新建虚拟环境2.安装Labelme3.Labelme的使用 三、json2yolo 一、Labelme是什么? Labelme是一个用于图像标注的开源工具,可以实现图像标注、语义分割、实例分割等。 本文记录一下labelme的安装与使…...
C#基础:数据库中使用Linq作分组处理(反射/直接分组)
目录 一、使用反射分组 二、不使用反射分组 三、调用示例 四、代码demo 一、使用反射分组 private static List<GroupList<T>> GetGroupList<T>(List<T> entities, string groupByProperty) {// 获取分组字段的类型var propertyInfo typeof(T).…...

Revite二次开发_使用WPF和WebView2制作一个访问网站的窗口
如果想在revit里打开网页,可以使用WebView2来实现,下面是一个代码示例。 也尝试过使用CefSharp,但由于Revit本身也使用了CefSharp,所以需要根据不同的Revit版本选择适合的CefSharp版本,比较麻烦,所以最好还…...
Java Spring Boot 连接数据库
要在Java Spring Boot应用程序中连接数据库,您需要遵循以下步骤: 1. 添加数据库依赖项:在您的Spring Boot项目中的pom.xml文件中添加数据库依赖项,例如MySQL或PostgreSQL等。例如,如果您要连接MySQL数据库,…...

Java面试八股之消息队列中推模式和拉模式分别有哪些使用场景
消息队列中推模式和拉模式分别有哪些使用场景 消息队列的推模式(Push)和拉模式(Pull)各有不同的使用场景和优缺点。下面我会详细介绍这两种模式及其适用场景: 推模式(Push) 特点:…...
springboot jar是如何启动的
我们先来看一个项目的打完包后的MANIFEST.MF文件: Manifest‐Version: 1.0 Implementation‐Title: spring‐learn Implementation‐Version: 0.0.1‐SNAPSHOT Start‐Class: com.tulingxueyuan.Application Spring‐Boot‐Classes: BOOT‐INF/classes/ Spring‐Bo…...

Android 12系统源码_屏幕设备(二)DisplayAdapter和DisplayDevice的创建
前言 在Android 12系统源码_屏幕设备(一)DisplayManagerService的启动这篇文章中我们具体分析了DisplayManagerService 的启动流程,本篇文章我们将在这个的基础上具体来分析下设备屏幕适配器的创建过程。 一、注册屏幕适配器 系统是在Disp…...
常用Mysql命令
前言 本文列举了一些常见的mysql操作 正文 一、连接和登录 MySQL 1. 使用命令行登录 MySQL 注意:需要将mysql的bin目录导入到环境变量中 mysql -u 用户名 -p示例: mysql -u root -p执行上述命令后,系统会提示输入密码,输入…...

IDEA Debug工具
一、Debug工具栏 自定义debug工具栏:先把debug程序运行起来->右击->配置 常用的工具: 二、DeBug常用图标详解 三、DeBug实践操作 常规Debug:略。 Stream Chain:处理流式语句 Reset Frame:重置方法入栈 …...
ARM64的汇编资源
最近在写一本ARM64的教材,所以在晚上查找了一下相关资源,都是免费开源的,不包括盗版书籍。 Exploring AArch64 assembler Roger Ferrer Ibez的博客文章,写在2016-2017年,内容简单充实,适合入门。 《ARM6…...

实验室安全分级分类管理系统在高校中的具体应用
盛元广通高校实验室安全分级分类管理系统的构建,旨在通过科学合理的管理手段,提高实验室的安全水平,保障师生的人身安全,防止实验事故的发生。这一系统通常包括实验室安全等级评估、分类管理、风险控制、安全教育与培训、应急响应…...

使用 prerenderRoutes 进行预渲染路由
title: 使用 prerenderRoutes 进行预渲染路由 date: 2024/8/20 updated: 2024/8/20 author: cmdragon excerpt: prerenderRoutes 函数是 Nuxt 3 中一个强大的工具,它能够帮助开发者优化页面加载速度和改善用户体验。通过使用 prerenderRoutes,你能够灵活地指定需要预渲染的…...

【深度解析】WRF-LES与PALM微尺度气象大涡模拟
查看原文>>>【深度解析】WRF-LES与PALM微尺度气象大涡模拟 针对微尺度气象的复杂性,大涡模拟(LES)提供了一种无可比拟的解决方案。微尺度气象学涉及对小范围内的大气过程进行精确模拟,这些过程往往与天气模式、地形影响和…...

redis事件机制
redis服务器是一个由事件驱动(死循环)的程序,它总共就干两件事: 文件事件:利用I/O复用机制,监听Socket等文件描述符发生的事件,如网络请求时间事件:定时触发的事件,负责完成redis内部定时任务&…...

【C++】模拟实现vector
可以把vector看作升级版的数组,可采用下标进行访问,非常高效,大小可动态改变,会自动扩容,数据存储在堆空间上。 VECROR 成员变量、函数及模板总览构造函数和析构函数无参构造函数构造n个元素大小的空间并初始化通过某个…...

【CAN-IDPS】汽车网关信息安全要求以及实验方法
《汽车网关信息安全技术要求及试验方法》是中国的一项国家标准,编号为GB/T 40857-2021,于2021年10月11日发布,并从2022年5月1日起开始实施 。这项标准由全国汽车标准化技术委员会(TC114)归口,智能网联汽车分会(TC114SC34)执行,主管部门为工业和信息化部。 该标准主要…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...

接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...

RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...

初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配
目录 一、C 内存的基本概念 1.1 内存的物理与逻辑结构 1.2 C 程序的内存区域划分 二、栈内存分配 2.1 栈内存的特点 2.2 栈内存分配示例 三、堆内存分配 3.1 new和delete操作符 4.2 内存泄漏与悬空指针问题 4.3 new和delete的重载 四、智能指针…...

代码规范和架构【立芯理论一】(2025.06.08)
1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...
「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案
在移动互联网营销竞争白热化的当下,推客小程序系统凭借其裂变传播、精准营销等特性,成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径,助力开发者打造具有市场竞争力的营销工具。 一、系统核心功能架构&…...

C++_哈希表
本篇文章是对C学习的哈希表部分的学习分享 相信一定会对你有所帮助~ 那咱们废话不多说,直接开始吧! 一、基础概念 1. 哈希核心思想: 哈希函数的作用:通过此函数建立一个Key与存储位置之间的映射关系。理想目标:实现…...