stm20260710 STM32_HAL库C语言内存相关函数详细说明和实例
·
stm20260710 STM32_HAL库C语言内存相关函数详细说明和实例
一、内存操作函数
1.1 memcpy - 内存拷贝
原型:void *memcpy(void *dest, const void *src, size_t n);
功能:从源地址 src 拷贝 n 个字节到目标地址 dest。
注意:源和目标内存区域不能重叠,否则行为未定义。
#include <stdio.h>
#include <string.h>
int main(void) {
// 示例1:拷贝数组
uint8_t src = {0xA5, 0xA8, 0x02, 0x20, 0x07, 0x01, 0x00, 0x00};
uint8_t dest;
memcpy(dest, src, sizeof(src));
printf("dest: ");
for (int i = 0; i < 8; i++) {
printf("%02X ", dest[i]);
}
// 输出: A5 A8 02 20 07 01 00 00
printf("\n");
// 示例2:拷贝结构体
typedef struct {
uint32_t id;
float value;
} Sensor_t;
Sensor_t s1 = {.id = 1, .value = 36.5f};
Sensor_t s2;
memcpy(&s2, &s1, sizeof(Sensor_t));
printf("s2.id=%lu, s2.value=%.1f\n", s2.id, s2.value);
// 输出: s2.id=1, s2.value=36.5
return 0;
}
1.2 memmove - 安全内存拷贝
原型:void *memmove(void *dest, const void *src, size_t n);
功能:与 memcpy 相同,但正确处理内存重叠的情况。
#include <stdio.h>
#include <string.h>
int main(void) {
// 示例1:内存重叠时向右移动
char str[] = "Hello, STM32!";
printf("原始: %s\n", str);
// 将整体向右移动3个字节(重叠场景)
memmove(str + 3, str, strlen(str) + 1); // +1 拷贝 '\0'
str = '>';
str = '>';
str = '>';
printf("右移: %s\n", str);
// 输出: >>>Hello, STM32!
// 示例2:环形缓冲区数据搬移
uint8_t buffer = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
// 将后4个字节移到前面(覆盖前4个字节)
memmove(buffer, buffer + 4, 4);
printf("搬移后: ");
for (int i = 0; i < 8; i++) {
printf("%02X ", buffer[i]);
}
// 输出: 05 06 07 08 05 06 07 08
printf("\n");
return 0;
}
1.3 memset - 内存初始化
原型:void *memset(void *s, int c, size_t n);
功能:将内存块 s 的前 n 个字节设置为值 c(按字节填充)。
#include <stdio.h>
#include <string.h>
int main(void) {
// 示例1:数组清零
uint8_t buffer;
memset(buffer, 0, sizeof(buffer));
printf("清零后: ");
for (int i = 0; i < 16; i++) {
printf("%02X ", buffer[i]);
}
// 输出: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
printf("\n");
// 示例2:结构体清零
typedef struct {
uint32_t id;
uint8_t name;
float temp;
} Device_t;
Device_t dev;
memset(&dev, 0, sizeof(Device_t));
printf("dev.id=%lu, dev.temp=%.1f\n", dev.id, dev.temp);
// 输出: dev.id=0, dev.temp=0.0
// 示例3:填充特定值(注意是按字节填充)
uint8_t fill_buf;
memset(fill_buf, 0xFF, sizeof(fill_buf));
printf("填充0xFF: ");
for (int i = 0; i < 8; i++) {
printf("%02X ", fill_buf[i]);
}
// 输出: FF FF FF FF FF FF FF FF
printf("\n");
// ⚠️ 错误示例:memset 不能正确填充多字节值
uint32_t arr;
memset(arr, 1, sizeof(arr));
// 每个字节被设为0x01,所以每个uint32_t = 0x01010101
// 而不是你期望的 0x00000001!
printf("arr=0x%08lX\n", arr);
// 输出: arr=0x01010101
return 0;
}
1.4 memcmp - 内存比较
原型:int memcmp(const void *s1, const void *s2, size_t n);
功能:逐字节比较两块内存的前 n 个字节。
返回值:0 相同,<0 s1较小,>0 s1较大。
#include <stdio.h>
#include <string.h>
int main(void) {
// 示例1:比较两个数组是否相同
uint8_t frame1[] = {0xA5, 0xA8, 0x02, 0x20};
uint8_t frame2[] = {0xA5, 0xA8, 0x02, 0x20};
uint8_t frame3[] = {0xA5, 0xA8, 0x02, 0x30};
if (memcmp(frame1, frame2, 4) == 0) {
printf("frame1 和 frame2 完全相同\n");
}
// 输出: frame1 和 frame2 完全相同
if (memcmp(frame1, frame3, 4) != 0) {
printf("frame1 和 frame3 不同\n");
}
// 输出: frame1 和 frame3 不同
// 示例2:协议帧头匹配
uint8_t rx_data[] = {0xA5, 0xA8, 0x02, 0x20, 0x07, 0x01};
uint8_t header[] = {0xA5, 0xA8};
if (memcmp(rx_data, header, 2) == 0) {
printf("帧头匹配成功,是有效帧\n");
}
// 输出: 帧头匹配成功,是有效帧
// 示例3:比较大小关系
uint8_t a[] = {0x01, 0x02, 0x03};
uint8_t b[] = {0x01, 0x02, 0x04};
int result = memcmp(a, b, 3);
if (result < 0) {
printf("a < b\n");
}
// 输出: a < b
return 0;
}
1.5 memchr - 内存查找字符
原型:void *memchr(const void *s, int c, size_t n);
功能:在内存块 s 的前 n 个字节中查找第一个等于 c 的字节。
返回值:找到返回指向该字节的指针,未找到返回 NULL。
#include <stdio.h>
#include <string.h>
int main(void) {
// 示例1:在数据中查找特定字节
uint8_t data[] = {0x01, 0x02, 0x03, 0xA5, 0x05, 0x06};
uint8_t *found = (uint8_t *)memchr(data, 0xA5, sizeof(data));
if (found != NULL) {
int offset = found - data;
printf("找到 0xA5,位于偏移量 %d\n", offset);
}
// 输出: 找到 0xA5,位于偏移量 3
// 示例2:查找不存在的字节
uint8_t *not_found = (uint8_t *)memchr(data, 0xFF, sizeof(data));
if (not_found == NULL) {
printf("未找到 0xFF\n");
}
// 输出: 未找到 0xFF
// 示例3:在字符串中查找字符(类似 strchr 但指定长度)
char str[] = "Hello, STM32 World!";
char *comma = (char *)memchr(str, ',', strlen(str));
if (comma != NULL) {
printf("逗号位置: %d
更多推荐



所有评论(0)