嵌入式八股文面试题(二)C语言算法

相关概念请查看文章:C语言概念

1. 如何实现一个简单的内存池?

简单实现:

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>

//内存块
typedef struct MemoryBlock {
    void *data; // 内存块起始地址
    struct MemoryBlock *next; // 下一个内存块的地址
} MemoryBlock;

//内存池
typedef struct MemoryPool {
    MemoryBlock *freeList; // 空闲内存块链表
    MemoryBlock *usedList; // 占用内存块链表
    int freeCount; // 空闲内存块数量
    int usedCount; // 占用内存块数量
    int blockCount; // 内存块总数量
} MemoryPool;
//初始化内存池
MemoryPool *InitMemoryPool(int blockSize, int blockCount) {
    MemoryPool *pool = (MemoryPool *)malloc(sizeof(MemoryPool)); // 为内存池分配空间
    if (pool == NULL) {
        printf("Failed to allocate memory pool!\n");
        return NULL;
    }
    pool->freeList = NULL;
    pool->usedList = NULL;
    pool->freeCount = 0;
    pool->usedCount = 0;
    pool->blockCount = blockCount;
    for (int i = 0; i < blockCount; i++) {
        // 创建内存块节点,插入到空闲链表
        MemoryBlock *block = (MemoryBlock *)malloc(sizeof(MemoryBlock));
        block->data = malloc(blockSize);
        block->next = pool->freeList;
        pool->freeList = block;
        pool->freeCount++;
    }
    return pool;
}
//分配内存块
void *AllocateBlock(MemoryPool *pool) {
    if (pool->freeList == NULL || pool->freeCount == 0) {
        printf("No free blocks available!\n");
        return NULL;
    }
    MemoryBlock *node = pool->freeList;
    // 将该内存块从空闲链表删除
    pool->freeList = node->next;
    // 将该内存块插入到占用链表
    node->next = pool->usedList;
    pool->usedList = node;
    // 更新空闲和占用状态
    pool->usedCount++;
    pool->freeCount--;
    return node->data;
}
//释放内存块
void FreeBlock(MemoryPool *pool, void *data) {
    MemoryBlock *cur = pool->usedList;
    MemoryBlock *pre = NULL;
    // 寻找该内存块的节点
    while (cur != NULL && cur->data != data) {
        pre = cur;
        cur = cur->next;
    }
    if (cur == NULL) {
        printf("Error: Data not found!\n");
        return;
    }
    // 将该内存块从占用链表删除
    if (pre != NULL)
        pre->next = cur->next;
    else
        pool->usedList = cur->next;
    // 将该内存块插入到空闲链表
    cur->next = pool->freeList;
    pool->freeList = cur;
    pool->freeCount++;
    pool->usedCount--;
}
//销毁内存块
void DestroyMemoryPool(MemoryPool *pool) {
    if (pool == NULL) return;
    MemoryBlock *cur = NULL;
    // 释放所有空闲内存块空间
    while (pool->freeList != NULL) {
        cur = pool->freeList;
        pool->freeList = pool->freeList->next;
        free(cur->data);
        free(cur);
    }
    // 释放所有占用内存块空间
    while (pool->usedList != NULL) {
        cur = pool->usedList;
        pool->usedList = pool->usedList->next;
        free(cur->data);
        free(cur);
    }
    // 释放内存池空间
    free(pool);
}
int main(void) {
    MemoryPool *pool;
    pool = InitMemoryPool(10, 5); // 初始化内存池
    int *str = (int *)AllocateBlock(pool);  //申请内存块1
    *str = 2;
    int *ptr = (int *)AllocateBlock(pool); //申请内存块2
    *ptr = 3;
    printf("free block : %d, used block : %d\n", pool->freeCount, pool->usedCount);
    FreeBlock(pool, ptr); //释放内存块2
    printf("free block : %d, used block : %d\n", pool->freeCount, pool->usedCount);
    DestroyMemoryPool(pool); 
    return 0;
}

打印结果:

2. 实现一个双向链表。

双向链表是一种每个节点都有两个指针,一个指向下一个节点,一个指向前一个节点的数据结构。可以在任意位置进行快速插入和删除。

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>

// 双向链表节点
typedef struct Node {
    int data;
    struct Node *prev; //连接前一个节点的指针
    struct Node *next; //连接下一个节点的指针
} Node;

// 创建新节点
Node* createNode(int data) {
    Node *newNode = (Node *)malloc(sizeof(Node));
    newNode->data = data;
    newNode->next = NULL;
    newNode->prev = NULL;
    return newNode;
}

// 插入节点到链表的尾部
void append(Node **head, int data) {
    Node *newNode = createNode(data);
    if (*head == NULL) {
        *head = newNode;
    } else {
        Node *temp = *head;
        while (temp->next != NULL) {
            temp = temp->next;
        }
        temp->next = newNode;
        newNode->prev = temp;
    }
}
//删除一个节点
void delete_node(Node **head, int data) {
    if (*head == NULL){  // 如果链表为空
        printf("链表为空,没有要删除的元素\n");
        return;
    }
    Node *temp = *head;
    
    // 如果删除的是头节点
    if (temp->data == data) {
        *head = temp->next;  // 更新头节点
        if (*head != NULL) {  // 如果不是空链表
            (*head)->prev = NULL;
        }
        free(temp);
        return;
    }
    // 找到要删除的节点
    while (temp != NULL && temp->data != data) {
        temp = temp->next;
    }
    // 如果没有找到该节点
    if (temp == NULL) {
        printf("未找到数据为 %d 的节点\n", data);
        return;
    }
    // 删除的是中间或尾部节点
    if (temp->next != NULL) {
        temp->next->prev = temp->prev;  // 更新下一个节点的prev指针
    }
    if (temp->prev != NULL) {
        temp->prev->next = temp->next;  // 更新前一个节点的next指针
    }
    free(temp);
}
// 打印双向链表
void printList(Node *head) {
    Node *temp = head;
    while (temp != NULL) {
        printf("%d <-> ", temp->data);
        temp = temp->next;
    }
    printf("NULL\n");
}

int main() {
    Node *head = NULL;
    append(&head, 10);
    append(&head, 20);
    append(&head, 30);
    printList(head);
    delete_node(&head, 30);
    printList(head);
    return 0;
}

打印结果:

3. 实现一个线程池。

相关推荐
焦耳加热9 小时前
阿德莱德大学Nat. Commun.:盐模板策略实现废弃塑料到单原子催化剂的高值转化,推动环境与能源催化应用
人工智能·算法·机器学习·能源·材料工程
wan5555cn9 小时前
多张图片生成视频模型技术深度解析
人工智能·笔记·深度学习·算法·音视频
u6069 小时前
常用排序算法核心知识点梳理
算法·排序
索迪迈科技11 小时前
基于野火F407开发板实现电源管理-停止模式
c语言·stm32·单片机·嵌入式硬件·mcu
蒋星熠12 小时前
Flutter跨平台工程实践与原理透视:从渲染引擎到高质产物
开发语言·python·算法·flutter·设计模式·性能优化·硬件工程
小莞尔12 小时前
【51单片机】【protues仿真】基于51单片机宠物投食系统
c语言·stm32·单片机·嵌入式硬件·51单片机
小欣加油12 小时前
leetcode 面试题01.02判定是否互为字符重排
数据结构·c++·算法·leetcode·职场和发展
3Cloudream12 小时前
LeetCode 003. 无重复字符的最长子串 - 滑动窗口与哈希表详解
算法·leetcode·字符串·双指针·滑动窗口·哈希表·中等
王璐WL12 小时前
【c++】c++第一课:命名空间
数据结构·c++·算法
空白到白13 小时前
机器学习-聚类
人工智能·算法·机器学习·聚类