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
相关产品推荐
相关产品推荐

