C语言数据结构编程练习-用指针创建顺序表,进行创销和增删改查操作
使用多文件进行编程
main.c文件
#include "02.h"
int main()
{
fn2();
return 0;
}
02.h 头文件
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#define MAX_NUMBER 100
typedef int elememtType; //elememt:元素
typedef struct orderListPtr
{
elememtType* dataP;//元素类型指针 用于申请内存后存放数组元素
int length;//存放数组元素的个数
}orderList;
void fn2();
void print_menu();
void create_list(orderList* List);
void print_list(orderList List);
void append_list(orderList* List, elememtType value);
void insert_list(orderList* List, int index, elememtType value);
void delete_List(orderList* List, int index);
void alter_list(orderList* List, int index, elememtType value);
void destory_list(orderList* List);
02.c 文件
#include "02.h"
//创建顺序表 通过指针来创建顺序表
void fn2()
{
int order=0;//指令
int index = 0;//索引
elememtType value;//元素值
orderList List = { NULL,0 };//定义结构体变量
print_menu();
while (1)
{
printf("请输入操作指令:");
scanf(" %d", &order);
switch (order)
{
case 1:
//创建顺序表 create 创建
create_list(&List);
break;
case 2:
//打印顺序表
print_list(List); //print 打印
break;
case 3:
//追加一个节点 是在最后面增加数据 append:追加
printf("请输入要追加的元素:");
scanf(" %d", &value);
append_list(&List, value);
break;
case 4:
//插入一个节点 随机插入(从0开始)
printf("请输入要插入的节点:");
scanf(" %d", &index);
printf("请输入要插入的元素:");
scanf(" %d", &value);
insert_list(&List,index,value); //insert 插入
break;
case 5:
//删除一个节点 用户输入删除的索引,从1开始
printf("请输入要删除的元素位置:");
scanf(" %d", &index);
delete_List(&List, index);
break;
case 6:
//修改顺序表元素 用户输入修改的元素的索引,从1开始
printf("请输入要修改的节点位置:");
scanf(" %d", &index);
printf("请输入要修改后的元素值:");
scanf(" %d", &value);
alter_list(&List, index, value); //alter 修改
break;
case 7:
//销毁顺序表
destory_list(&List);//destory 销毁
break;
case 8:
//退出
return;
default:
printf("输入指令有误,请重新输入\n");
break;
}
}
}
//菜单
void print_menu()
{
system("cls");// 系统函数 用于屏幕清空 头文件stdlib.h里面的
printf("操作指令说明:\n");
printf("1:创建顺序表\n2:打印顺序表\n");
printf("3:追加一个节点\n4:插入一个节点\n");
printf("5:删除一个节点\n6:修改顺序表元素\n");
printf("7:销毁顺序表\n8:退出\n");
}
//创建新表并进行初始化
void create_list(orderList* List)
{
List->dataP = (elememtType*)malloc(sizeof(orderList) * MAX_NUMBER);
if (!List->dataP)
{
printf("申请内存失败\n");
return;
}
//动态申请的空间要进行初始化
memset(List->dataP, 0, sizeof(orderList) * MAX_NUMBER);
printf("初始化成功\n");
}
//打印顺序表
void print_list(orderList List)
{
if (!List.dataP)
{
printf("请先建表\n");
return;
}
if (List.length == 0)
{
printf("空表无法打印\n");
return;
}
for (int i = 0; i < List.length; i++)
{
printf(" %d ", List.dataP[i]);
//dataP是指针 List.dataP[i] 相当于 *(List.dataP + i)
}
printf("\n");
}
//追加元素
void append_list(orderList * List,elememtType value)
{
if (!List->dataP)
{
printf("请先建表\n");
return;
}
if (List->length >= MAX_NUMBER)
{
printf("空已满无法追加\n");
return;
}
List->dataP[List->length] = value;
//换一种写法 *(List->datap + List->length) = val;
List->length++;
printf("追加成功\n");
}
//插入元素
void insert_list(orderList* List, int index, elememtType value)
{
if (!List->dataP)
{
printf("请先建表\n");
return;
}
if (List->length >= MAX_NUMBER)
{
printf("空已满无法插入\n");
return;
}
//判断插入的位置是否合法
if (index < 0 || index >= MAX_NUMBER)
{
printf("插入位置不合法\n");
return;
}
//插入后需要遍历数组 index后面的数据全部需要后移一位
//从后往前遍历比较方便
for (int i = List->length - 1; i >= index; i--)
{
*(List->dataP +( i + 1)) = List->dataP[i];
}
*(List->dataP + index) = value;
List->length++;
printf("插入成功\n");
}
//删除元素
void delete_List(orderList* List, int index)
{
if (!List->dataP)
{
printf("请先建表\n");
return;
}
if (List->length >= MAX_NUMBER)
{
printf("空已满无法删除\n");
return;
}
int index_temp = index - 1;
if (index_temp<0 || index_temp>List->length - 1)
{
printf("删除位置不合法\n");
return;
}
//删除元素后 后面的数据全部需要往前移一位
//index后面的数据往前移,从前到后遍历比较方便
for (int i = index_temp; i < List->length; i++)
{
List->dataP[i] = List->dataP[i + 1];
}
List->length--;
printf("删除成功\n");
}
//修改
void alter_list(orderList* List, int index, elememtType value)
{
if (!List->dataP)
{
printf("/请先建表\n");
return;
}
if (List->length == 0)
{
printf("空表,无法修改\n");
return;
}
//判断要修改的元素位置是否合法
int ind = index - 1;//要修改元素索引
if (ind < 0 || ind > List->length - 1)
{
printf("您要修改的元素不存在\n");
return;
}
//正常修改
// List->dataP[ind] = value;
//换一种写法
*(List->dataP + ind) = value;
printf("修改成功\n");
}
void destory_list(orderList* List)
{
free(List->dataP);
List->dataP = NULL;
List->length = 0;//元素个数为0
printf("销毁成功!!\n");
}
多文件编程的好处:
- 提高代码的模块化和可维护性
- 模块化:将不同功能的代码分别放在不同的文件中,使程序结构更加清晰。每个文件专注于实现一个特定的功能,例如,在一个游戏开发项目中,可将角色移动相关代码放在
movement.c
文件中,将碰撞检测代码放在collision.c
文件中 。 - 可维护性:当需要修改或扩展某个功能时,只需在对应的文件中进行操作,而不会影响到其他无关的代码。例如,如果要优化角色移动的速度,只需在
movement.c
文件中修改相关代码,其他如碰撞检测、游戏界面等功能模块不受影响。
- 模块化:将不同功能的代码分别放在不同的文件中,使程序结构更加清晰。每个文件专注于实现一个特定的功能,例如,在一个游戏开发项目中,可将角色移动相关代码放在
- 增强代码的复用性
- 多个项目可以共享相同的代码文件。例如,在开发多个不同的图形界面应用程序时,可能都会用到一些通用的界面绘制函数,将这些函数放在一个独立的文件(如
gui_draw.c
)中,不同的项目都可以包含这个文件,从而复用这些代码,避免了重复开发,提高了开发效率。
- 多个项目可以共享相同的代码文件。例如,在开发多个不同的图形界面应用程序时,可能都会用到一些通用的界面绘制函数,将这些函数放在一个独立的文件(如
- 便于团队协作开发
- 在大型项目开发中,往往需要多个程序员协同工作。多文件编程方式使得每个程序员可以负责一个或多个特定的文件,独立进行代码的编写、调试和测试工作。例如,在一个企业级管理系统的开发项目中,程序员 A 可以负责用户登录和权限管理相关文件的开发,程序员 B 可以专注于数据库操作相关文件的实现,他们之间通过文件接口进行交互,这样可以大大提高团队开发的并行性,加快项目的开发进度。
- 加快编译速度
- 在大型项目中,修改某一个文件的代码后,只需要重新编译这个文件以及与其有依赖关系的少数文件,而不需要重新编译整个项目的所有文件。这是因为编译器会根据文件的修改时间来判断是否需要重新编译。例如,在一个包含数百个源文件的大型软件开发项目中,如果只是对某个功能模块对应的一个源文件进行了修改,那么重新编译时,编译器只需要花费少量时间重新编译这个修改过的文件以及与之紧密相关的几个文件,而其他大部分未修改的文件无需重新编译,从而大大缩短了整个项目的编译时间,提高了开发效率。