You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言循环队列:如何处理多数据类型输入问题

如何在C语言中实现支持多类型的循环队列

我正在编写一个C语言循环队列程序,程序接收整数指令(1、2、3)及对应数据类型(整数/字符/字符串),指令对应操作如下:

  • 1 -> 入队(Enqueue)
  • 2 -> 出队(Dequeue)
  • 3 -> 显示队列(Display)
    不同测试用例对应不同数据类型(比如测试用例1处理整数,测试用例2处理字符串),目前我实现的代码仅支持整数,需要解决如何处理多种数据类型输入的问题。

以下是仅支持整数的实现代码:

#include <stdio.h>
#include <stdlib.h>

struct node{
    int data;
    struct node *next;
};

struct node *head, *tail = NULL;

void enq(int x){
    struct node *nade = malloc(sizeof(struct node));
    nade->data = x;
    nade->next = head;
    if (head == NULL)
        head = tail = nade;
    else{
        tail->next = nade;
        tail = nade;
    }
}

void dq(){
    struct node *temp;
    if (head == NULL)
        printf("Deque is Empty\n");
    else if (head == tail){
        printf("%d is deleted\n", head->data);
        head = NULL;
    }
    else{
        printf("%d is deleted\n", head->data);
        tail->next = head->next;
        head = head->next;
    }
}

void display(){
    if (head == NULL)
        printf("Empty\n");
    else{
        struct node *temp;
        printf("Circular Queue ");
        for (temp = head; temp != tail; temp = temp->next)
            printf("%d ", temp->data);
        printf("%d\n", temp->data);
    }
}

int main(){
    int t; scanf("%d", &t);
    do{
        switch (t)
        {
        int x;
        case 1:
            scanf("%d", &x);
            enq(x);
            break;
        case 2:
            dq();
            break;
        case 3:
            display();
            break;
        }
        scanf("%d", &t);
    }while (t != 4);
    return 0;
} 

解决方案:通过联合体或void指针实现多类型支持

方法1:使用联合体(Union)存储多类型数据

C语言的联合体允许在同一块内存空间存储不同类型的数据,搭配枚举类型标记当前存储的数据类型,可以高效实现多类型队列。

核心结构修改

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 标记数据类型
typedef enum {
    TYPE_INT,
    TYPE_CHAR,
    TYPE_STRING
} DataType;

struct node {
    DataType type; // 记录当前节点的数据类型
    union {
        int int_val;
        char char_val;
        char* str_val;
    } data;
    struct node *next;
};

struct node *head, *tail = NULL;

多类型入队函数

void enq(DataType type, void* val) {
    struct node *new_node = malloc(sizeof(struct node));
    if (!new_node) {
        printf("Memory allocation failed\n");
        return;
    }
    new_node->type = type;

    switch(type) {
        case TYPE_INT:
            new_node->data.int_val = *(int*)val;
            break;
        case TYPE_CHAR:
            new_node->data.char_val = *(char*)val;
            break;
        case TYPE_STRING:
            // 字符串需单独分配内存,避免原指针失效
            new_node->data.str_val = malloc(strlen((char*)val) + 1);
            strcpy(new_node->data.str_val, (char*)val);
            break;
    }

    new_node->next = head;
    if (head == NULL) {
        head = tail = new_node;
    } else {
        tail->next = new_node;
        tail = new_node;
    }
}

多类型出队函数

void dq() {
    if (head == NULL) {
        printf("Deque is Empty\n");
        return;
    }

    struct node *temp = head;
    // 根据类型打印并释放对应资源
    switch(temp->type) {
        case TYPE_INT:
            printf("%d is deleted\n", temp->data.int_val);
            break;
        case TYPE_CHAR:
            printf("%c is deleted\n", temp->data.char_val);
            break;
        case TYPE_STRING:
            printf("%s is deleted\n", temp->data.str_val);
            free(temp->data.str_val); // 释放字符串内存
            break;
    }

    if (head == tail) {
        head = tail = NULL;
    } else {
        tail->next = head->next;
        head = head->next;
    }
    free(temp); // 释放节点本身
}

多类型显示函数

void display() {
    if (head == NULL) {
        printf("Empty\n");
        return;
    }

    struct node *temp = head;
    printf("Circular Queue ");
    do {
        switch(temp->type) {
            case TYPE_INT:
                printf("%d ", temp->data.int_val);
                break;
            case TYPE_CHAR:
                printf("%c ", temp->data.char_val);
                break;
            case TYPE_STRING:
                printf("%s ", temp->data.str_val);
                break;
        }
        temp = temp->next;
    } while (temp != head); // 循环队列遍历结束条件为回到head
    printf("\n");
}

适配多类型输入的主函数

int main() {
    DataType type;
    printf("Enter data type (0:int,1:char,2:string): ");
    scanf("%d", (int*)&type);
    getchar(); // 读取换行符,避免干扰后续输入

    int t;
    printf("Enter command (1:enq,2:dq,3:display,4:exit): ");
    scanf("%d", &t);
    getchar();

    do {
        switch (t) {
            case 1: {
                if (type == TYPE_INT) {
                    int x;
                    scanf("%d", &x);
                    enq(TYPE_INT, &x);
                } else if (type == TYPE_CHAR) {
                    char c;
                    scanf("%c", &c);
                    getchar();
                    enq(TYPE_CHAR, &c);
                } else if (type == TYPE_STRING) {
                    char str[100];
                    fgets(str, 100, stdin);
                    str[strcspn(str, "\n")] = '\0'; // 去掉换行符
                    enq(TYPE_STRING, str);
                }
                break;
            }
            case 2:
                dq();
                break;
            case 3:
                display();
                break;
            default:
                printf("Invalid command\n");
        }
        printf("Enter command: ");
        scanf("%d", &t);
        getchar();
    } while (t != 4);

    // 程序结束前释放所有节点资源
    while (head != NULL) {
        dq();
    }
    return 0;
}

方法2:使用void指针存储数据

另一种方式是用void*存储任意类型的指针,同时记录数据类型,这种方式更灵活,但需要严格手动管理内存:

typedef enum { TYPE_INT, TYPE_CHAR, TYPE_STRING } DataType;

struct node {
    DataType type;
    void* data;
    struct node *next;
};

该方式的入队、出队、显示逻辑与方法1类似,需注意整数/字符也需动态分配内存(避免栈内存失效),字符串同样要单独分配并释放。


关键注意事项

  • 内存管理:字符串类型必须单独分配内存,出队时务必释放,防止内存泄漏。
  • 输入处理:字符和字符串输入需注意换行符的处理,避免读取错误。
  • 类型安全:必须严格根据type字段处理对应数据,否则会引发未定义行为。

内容的提问来源于stack exchange,提问作者Ayush Soam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 00:41:03