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
Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐