MST

星途 面试题库

面试题:C语言联合体在简单状态机框架搭建中的应用

请描述如何使用C语言联合体设计一个简单的状态机框架,用于管理一个具有开启、关闭两种状态的设备。并写出关键代码片段,阐述联合体在其中如何简化数据存储和状态切换逻辑。
40.4万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试

1. 联合体设计思路

联合体(Union)可以让不同的数据类型共享同一块内存空间。在状态机框架中,我们可以利用这一特性,将与不同状态相关的数据放在同一个联合体中,从而简化数据存储。

2. 关键代码片段

#include <stdio.h>

// 定义状态枚举类型
typedef enum {
    STATE_OFF,
    STATE_ON
} DeviceState;

// 定义联合体,包含与不同状态相关的数据
union DeviceData {
    // 设备关闭时,可以存储一些关闭相关的信息,这里简单示例为一个标志
    struct {
        int isShutdownGracefully;
    } off;
    // 设备开启时,可以存储一些开启相关的信息,这里简单示例为运行时间
    struct {
        int runningTime;
    } on;
};

// 定义状态机结构体
typedef struct {
    DeviceState state;
    union DeviceData data;
} DeviceStateMachine;

// 初始化设备状态机
void initDevice(DeviceStateMachine *machine) {
    machine->state = STATE_OFF;
    machine->data.off.isShutdownGracefully = 1;
}

// 开启设备
void turnOnDevice(DeviceStateMachine *machine) {
    if (machine->state == STATE_OFF) {
        machine->state = STATE_ON;
        machine->data.on.runningTime = 0;
    }
}

// 关闭设备
void turnOffDevice(DeviceStateMachine *machine) {
    if (machine->state == STATE_ON) {
        machine->state = STATE_OFF;
        machine->data.off.isShutdownGracefully = 1;
    }
}

// 打印设备状态信息
void printDeviceStatus(DeviceStateMachine *machine) {
    if (machine->state == STATE_OFF) {
        printf("Device is off. Shutdown gracefully: %d\n", machine->data.off.isShutdownGracefully);
    } else {
        printf("Device is on. Running time: %d\n", machine->data.on.runningTime);
    }
}

3. 联合体简化逻辑阐述

  • 数据存储简化:联合体使得与不同状态相关的数据可以复用内存空间。例如,设备关闭时,union DeviceDataoff 结构体的空间被使用;设备开启时,on 结构体的空间被使用。这样避免了为不同状态分别分配独立的数据结构,节省了内存。
  • 状态切换逻辑简化:在状态切换函数(如 turnOnDeviceturnOffDevice)中,通过直接修改联合体中对应状态的数据成员,简化了状态切换时的数据处理逻辑。而且,由于联合体共享内存,不需要额外的逻辑来处理不同状态数据结构之间的转换,使代码更加简洁直观。

你可以通过以下方式调用上述代码:

int main() {
    DeviceStateMachine machine;
    initDevice(&machine);
    printDeviceStatus(&machine);

    turnOnDevice(&machine);
    printDeviceStatus(&machine);

    turnOffDevice(&machine);
    printDeviceStatus(&machine);

    return 0;
}