1、功能要求
停车场是一个能放 10 辆车的狭长通道,只有一个大门,汽车按到达的先后次序停放。若停车场满了,车要停在门外的便道上等候,一旦有车走,则便道上第一辆车进入。当停车场中的车离开时,由于通道窄,在它后面的车要先退出,待它走后再依次进入。汽车离开时按停放时间收费。
2、程序文件
I、在停车场/src目录下新建main.c、Park.c、Strack.c、Queue.c文件
// main.c
#include <stdio.h>
#include "Park.h"
int main()
{
system("clear");
// 定义:停车栈、等候队列
Stack s;
Queue q;
// 初始化:停车栈、等候队列
Init_Park(&s);
Init_Wait(&q);
Menu_Operation(&s, &q);
return 0;
}
// Park.c
#include <stdio.h>
// 包括rand()、srand()、abs()等函数
#include <stdlib.h>
#include <time.h>
#include "Park.h"
// 菜单界面下的操作
void Menu_Operation(Stack *s, Queue *q)
{
if (NULL == s || NULL == q)
{
return;
}
char buf[10];
// 停车场里的车辆数、也即车位号
Data car_num = 0;
// 停车场外等候车辆数
Data wait_num = -1;
while (1)
{
Display_Menu();
scanf ("%s", buf);
system("clear");
printf ("\n");
// 停车、离开、查看、退出
switch (buf[0])
{
case PARK:
car_num++;
// 停车场未满,进停车栈
if (car_num < 11)
{
Push_Park(s, &car_num);
}
// 进等候队列
else
{
Push_Wait(q, &wait_num);
car_num--;
}
break;
case LEAVE:
Leave_Park(s, q, &car_num, &wait_num);
car_num--;
break;
case DISPLAY:
system("clear");
Display_Park(s, &car_num, &wait_num);
break;
case EXIT:
system("clear");
return;
default:
printf ("\t\t输入指令有误,请重新输入!\n");
sleep(1);
system("clear");
break;
}
}
}
// 菜单界面的显示
void Display_Menu(void)
{
printf ("\n \n \n \n \n \n \n \n");
printf ("\t\t\t\t\t\t**************************************************\n");
printf ("\t\t\t\t\t\t*\t\t欢迎来到同方停车场! *\n");
printf ("\t\t\t\t\t\t* *\n");
printf ("\t\t\t\t\t\t*\t\t 1、停车 *\n");
printf ("\t\t\t\t\t\t*\t\t 2、离开 *\n");
printf ("\t\t\t\t\t\t*\t\t 3、查看 *\n");
printf ("\t\t\t\t\t\t*\t\t 4、退出 *\n");
printf ("\t\t\t\t\t\t* *\n");
printf ("\t\t\t\t\t\t**************************************************\n");
printf ("\n\t\t\t\t\t\t请输入相应指令操作:");
return;
}
// 车驶离停车场
void Leave_Park(Stack *s, Queue *q, Data *car_num, Data *wait_num)
{
if (NULL == s)
{
return;
}
Data num;
// 用以存放停车栈首元素的地址
Node_Park *tmp_park;
// 用以存放让路站的首地址
Node_Park *tmp_way;
// 定义让路栈
Stack way_s;
// 初始化让路栈
Init_Park(&way_s);
system ("clear");
Display_Park(s, car_num, wait_num);
printf ("\t\t\t\t\t\t请输入离开车辆的停车位号:");
scanf ("%d", &num);
// 停车栈不为空
while (!Empty_Park(s))
{
tmp_park = GetTop_Park(s);
Data park_space_num = tmp_park->park_space_num;
if (num == park_space_num)
{
system ("clear");
printf ("\t\t\t\t\t\t\t停车位 %d 上的车已离开!\n\n", num);
printf ("\t\t\t\t\t\t\t车牌号为:");
printf ("%d\n", s->top->park_plate_num);
// time_t park_t = s->top->park_t;
// time(&park_t);
struct tm *display_park_t = localtime(&s->top->park_t);
printf ("\t\t\t\t\t\t\t停车时间:");
printf ( "%d/%d/%d %d:%d:%d\n",
display_park_t->tm_year+1900, display_park_t->tm_mon + 1, display_park_t->tm_mday,
display_park_t->tm_hour, display_park_t->tm_min, display_park_t->tm_sec);
time_t leave_t;
time(&leave_t);
struct tm *display_leave_t = localtime(&leave_t);
printf ("\t\t\t\t\t\t\t离开时间:");
printf ( "%d/%d/%d %d:%d:%d\n",
display_leave_t->tm_year+1900, display_leave_t->tm_mon + 1, display_leave_t->tm_mday,
display_leave_t->tm_hour, display_leave_t->tm_min, display_leave_t->tm_sec);
Data cost = difftime(leave_t, s->top->park_t);
printf ("\t\t\t\t\t\t\t停车时长:%d s\n\n" , cost);
printf ("\t\t\t\t\t\t\t您好,此次需支付的停车费用为 %d 元!\n\n", cost/10 + 1);
// 将停车栈车辆信息弹出
Pop_Park(s);
// 把让路栈里的车辆信息导入停车栈
while (!Empty_Park(&way_s))
{
Node_Park *node = (Node_Park *)malloc(sizeof(Node_Park)/sizeof(char));
// 获取让路栈里首辆车的地址
tmp_way = GetTop_Park(&way_s);
// 将停车栈中的每辆车的信息存到让路栈中
node->park_t = tmp_way->park_t;
node->park_space_num = tmp_way->park_space_num - 1;
node->park_plate_num = tmp_way->park_plate_num;
node->next = s->top;
s->top = node;
Pop_Park(&way_s);
}
// 获取等候队列的首辆车信息,并存入停车栈
// 停车场外等候车辆数
if ( *wait_num > -1 )
{
Data way_plate = GetTop_Wait(q);
Node_Park *node_2 = (Node_Park *)malloc(sizeof(Node_Park)/sizeof(char));
if (NULL == node_2)
{
return;
}
time_t t2;
struct tm *lt2;
time (&t2);
lt2 = localtime (&t2);
printf ("\t\t\t\t\t\t 车牌号为 %d 的车已进入同方停车场!", way_plate);
Pop_Wait(q);
break;
}
// 用于跳出while (!Empty_Park(s))循环
break;
}
else
{
// 压入让路栈
Push_Way(tmp_park, &way_s);
// 释放停车站
Pop_Park(s);
//*appoint_space_num--;
}
}
return;
}
// 让路栈:存放从停车栈中倒出的车辆信息
void Push_Way(Node_Park *s, Stack *way_s)
{
// 为让路栈元素分配空间
Node_Park *node = (Node_Park *)malloc(sizeof(Node_Park)/sizeof(char));
if (NULL == node)
{
return;
}
// 将停车栈中的每辆车的信息存到让路栈中
node->park_t = s->park_t;
node->park_space_num = s->park_space_num;
node->park_plate_num = s->park_plate_num;
node->next = way_s->top;
way_s->top = node;
}
// 查看停车场的车辆信息
void Display_Park(Stack *s, Data *car_num, Data *wait_num)
{
if (NULL == s)
{
return;
}
if (Empty_Park(s) == TRUE)
{
// 程序退出
exit(-1);
}
Node_Park *tmp = s->top;
printf ("\n\n\t\t\t\t\t\t停车位\t\t车牌号\t\t 停车时间\n");
while(tmp)
{
struct tm *display_park_t = localtime (&tmp->park_t);
printf ("\t\t\t\t\t\t %d\t\t%d", tmp->park_space_num, tmp->park_plate_num);
printf ("\t\t");
printf ( "%d/%d/%d %d:%d:%d\n",
display_park_t->tm_year+1900, display_park_t->tm_mon + 1, display_park_t->tm_mday,
display_park_t->tm_hour, display_park_t->tm_min, display_park_t->tm_sec);
tmp = tmp->next;
}
printf ("\n\t\t\t\t\t\t同方停车场内共有 %d 辆车!\n\n", *car_num);
if (*car_num == 10 && *wait_num > -1)
{
printf ("\t\t\t\t\t\t同方停车场外共有 %d 辆等候车辆!\n\n", *wait_num + 1);
}
return;
}
// Strack.c
// 链式栈
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "Park.h"
// 初始化栈
void Init_Park(Stack *s)
{
if (NULL == s)
{
return;
}
// 把s当作头结点来使用,即相当于head
s->top = NULL;
return;
}
// 判断空栈
BOOL Empty_Park(Stack *s)
{
if (NULL == s)
{
return FALSE;
}
if (NULL == s->top)
{
return TRUE;
}
return FALSE;
}
// 入停车栈
void Push_Park(Stack *s, Data *car_num)
{
if (NULL == s)
{
return;
}
// 头插
Node_Park *node = (Node_Park *)malloc(sizeof(Node_Park)/sizeof(char));
if (NULL == node)
{
return;
}
// 将当前输出的停车时间保存在t中
time_t t;
time(&t);
struct tm *now_t = localtime (&t);
srand((unsigned int)time(NULL));
Data rand_plate_num = rand() % 90000 + 10000;
// 保存:
// lt:时间
// parking_space_num:停车位号
// plate_number:随机生成5位的车牌号
node->park_t = t;
node->park_space_num = *car_num;
node->park_plate_num = rand_plate_num;
node->next = s->top;
s->top = node;
// 输出车辆信息
printf ("\t\t\t\t\t\t停车成功!\n");
printf ("\t\t\t\t\t\t车位号:%d\n", node->park_space_num);
printf ("\t\t\t\t\t\t车牌号:%d\n", node->park_plate_num);
printf ("\t\t\t\t\t\t停车时间:");
printf ( "%d/%d/%d %d:%d:%d\n\n",
now_t->tm_year + 1900, now_t->tm_mon, now_t->tm_mday,
now_t->tm_hour, now_t->tm_min, now_t->tm_sec);
return;
}
// 出栈
void Pop_Park(Stack *s)
{
if (NULL == s)
{
return;
}
if (Empty_Park(s) == TRUE)
{
return;
}
Node_Park *tmp = s->top;
s->top = tmp->next;
free(tmp);
}
// 获取栈顶元素的地址
Node_Park *GetTop_Park(Stack *s)
{
if (NULL == s)
{
return 0;
}
if (Empty_Park(s) == TRUE)
{
// 程序退出
exit(-1);
}
// 返回指向首元素的地址
return s->top;
}
// Queue.c
// 链式队列
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "Park.h"
// 初始化等候队列
void Init_Wait(Queue *q)
{
if (NULL == q)
{
return;
}
// 初始化时,均指向队头。即此时为空队列
q->front = NULL;
q->rear = NULL;
}
// 判断空队列
BOOL Empty_Wait(Queue *q)
{
if (NULL == q)
{
return FALSE;
}
if (NULL == q->front)
{
return TRUE;
}
return FALSE;
}
// 入等候队列
void Push_Wait(Queue *q, Data *wait_num)
{
if (NULL == q)
{
return;
}
static Data count = 0;
srand((unsigned int)time(NULL));
Data rand_plate_num = rand() % 90000 + 10000;
Node_Wait *node = (Node_Wait *)malloc(sizeof(Node_Wait)/sizeof(char));
if (NULL == node)
{
return;
}
// 等候队列里的车辆信息只有车牌号
node->wait_plate_num = rand_plate_num;
node->next = NULL;
system("clear");
printf ("\n\n\t\t\t\t\t\t同方停车场已满!\n");
printf ("\t\t\t\t\t\t请车牌号为:%d 的车辆暂进入等候队列!\n", node->wait_plate_num);
*wait_num += 1;
printf ("\t\t\t\t\t\t您前方共有 %d 辆等候车辆!\n\n", *wait_num);
// 入队列,为空时需单独考虑
if (q->rear != NULL)
{
q->rear->next = node;
q->rear = node;
}
else
{
q->rear = node;
q->front = node;
}
}
// 从等候队列出
void Pop_Wait(Queue *q)
{
if (NULL == q)
{
return;
}
// 判断空队列
if (TRUE == Empty_Wait(q))
{
return;
}
Node_Wait *tmp = q->front;
q->front = tmp->next;
free(tmp);
if (NULL == q->front)
{
q->rear = NULL;
}
}
// 获取等候队列顶元素的内容:车牌
Data GetTop_Wait(Queue *q)
{
if (NULL == q)
{
return 0;
}
if (TRUE == Empty_Wait(q))
{
exit(-1);
}
return q->front->wait_plate_num;
}
II、在停车场/include目录下新建Park.h文件
// Paki.h
#ifndef _PARK_H_
#define _PARK_H_
#include <time.h>
//车位10个
#define SIZE 10
enum menu{PARK = '1', LEAVE, DISPLAY, EXIT};
typedef int Data;
typedef enum {FALSE, TRUE, ERROR} BOOL;
// 停车栈
typedef struct _node_park
{
// 停车位 1-10 不可变
Data park_space_num;
// 车牌号 随机生成的5位数
Data park_plate_num;
// 存放时间:1900到现在的秒数
time_t park_t;
struct _node_park *next;
}Node_Park;
// 把s当作头结点
typedef struct _stack
{
Node_Park *top;
}Stack;
// 等候队列
typedef struct _node_wait
{
Data wait_plate_num;
struct _node_wait *next;
}Node_Wait;
typedef struct _queue
{
Node_Wait *front;
Node_Wait *rear;
}Queue;
// 菜单界面下的操作
void Menu_Operation(Stack *s, Queue *q);
// 菜单界面的显示
void Display_Menu(void);
// 车驶离停车场
void Leave_Park(Stack *s, Queue *q, Data *car_num, Data *wait_num);
// 让路栈:存放从停车栈中倒出的车辆信息
void Push_Way(Node_Park *s, Stack *way_s);
// 查看停车场的车辆信息
void Display_Park(Stack *s, Data *car_num, Data *wait_num);
// 初始化栈
void Init_Park(Stack *s);
// 判断空栈
BOOL Empty_Park(Stack *s);
// 入停车栈
void Push_Park(Stack *s, Data *car_num);
// 出栈
void Pop_Park(Stack *s);
// 获取栈顶元素的地址
Node_Park *GetTop_Park(Stack *s);
// 初始化等候队列
void Init_Wait(Queue *q);
// 判断空等候队列
BOOL Empty_Wait(Queue *q);
// 入等候队列
void Push_Wait(Queue *q, Data *wait_num);
// 出等候队列
void Pop_Wait(Queue *q);
// 获取等候队列顶元素
Data GetTop_Wait(Queue *q);
#endif // _PARK_H
III、在停车场目录下新建Makefile文件
src1 = $(wildcard ./src/*.c)
obj1 = $(patsubst ./src/%.c, ./obj/%.o, $(src1))
target = ./bin/a.out
all:$(target)
$(target):$(obj1)
gcc $(^) -o $(@)
$(obj1):./obj/%.o:./src/%.c
gcc -c $(^) -I ./include -o $(@) -g
.PHONY:clean all
clean:
-rm -rf $(target) $(obj1)
3、测试结果
略