将C源码分文件编写主要分为三步:
(1)××.h文件中声明函数,声明需要使用的数据结构的定义(如结构体的定义等)
(2)××.c文件中写的是.h文件中声明的函数的具体实现
(3)main.c文件中,通过导入#include"××.h"文件的方式,即可调用对应函数实现
这里以队列的实现举例说明:
步骤一:分别创建三个文件:
头文件.h,函数实现文件.c,主函数文件main.c
步骤二:.h文件中写函数声明
// .h文件写数据结构的定义及函数的声明
typedef struct Node //创建节点
{
int data;
struct Node* next;
}Node;
typedef struct Queue
{
Node* front; //头指针
Node* rear; //尾指针
}Queue;
void init(Queue* q); //队列初始化
int isempty(Queue* q);//检测队列是否为空
void enqueue(Queue* q, int dight); //入队
int dequeue(Queue* q); //出队
步骤三:导入头文件,.c文件写函数的实现
.c文件是具体的函数实现,在其中需要导入前一步骤的头文件/.h文件。其他部分就和正常写代码类似,同时导入需要用到的工具包。
//.c文件中写函数的实现
#include<stdlib.h>
#include"my_queue.h" //记得导入头文件
#include<stdio.h>
void init(Queue* q) //队列的初始化
{
q->front = NULL;
q->rear = NULL;
}
int isempty(Queue* q)
{
return q->front == NULL;
}
void enqueue(Queue* q, int dight) //入队操作 队尾入,队头出
{
Node* newnode = (Node*)malloc(sizeof(Node));
if (!newnode)
{
printf("创建新节点失败!");
exit(EXIT_FAILURE);
}
newnode->next = NULL;
newnode->data = dight;
//注意这里的q和main函数中的q含义是不一样的,这里的q已经是一个结构体指针了,所以在传入enpty()时直接传入
//而main函数中实例化的一个q只是queue类型的一个变量,需要使用取址符&传入
//不要写成了 if (isempty(&q))
if (isempty(q))
{
q->front = newnode;
q->rear = newnode; //将两个指针均指向第一个进来的节点
}
else
{
q->rear->next = newnode; //这里其实是将之前最后的节点的Next指向newnode
q->rear = newnode; //这里是重新将rear指针指向最后一个节点
}
}
int dequeue(Queue* q) //出队
{
if (isempty(q))
{
printf("队列为空!\n");
return -1;
}
else
{
Node* temp = q->front;
q->front = temp->next;
int item = temp->data;
free(temp);
return item;
}
}
步骤四:main.c文件导入头文件,调用相关函数
#include<stdio.h>
#include"my_queue.h"
int main()
{
Queue q;
init(&q);
/*printf("%d", isempty(&q));*/
enqueue(&q, 3);
enqueue(&q, 2);
enqueue(&q, 1);
//printf("第一次出队:%d\n", dequeue(&q));
//printf("第二次出队:%d\n", dequeue(&q));
//printf("第三次出队:%d\n", dequeue(&q));
//printf("第四次出队:%d\n", dequeue(&q));
while (q.front != NULL)
{
printf("%d\n", dequeue(&q));
}
return 0;
}