【链表4】<最新>结构体数组实现表(Table)

文/Edward

  表(Table)的概念
在充分了解了前面两小节的准备知识之后,我们接下来就可以言归正传来说链表了。
在讲述链表之前,我们再来详细讲述一下表(Table)这个概念。表(Table)是计算机C语言程序设计中的一种数据结构,简单地说,就是用多个结构体变量结合而成的有序存储模型。表(Table)在C语言的数据结构中是最简单的一种数据结构。
对于表(Table)的认识我们可以回想一下平时工作学习中使用的Excel。当我们在做一个简单的工作表的时候,我们可以给行列定义出不同的类型,在这个规定好的行列定义基础上,可以将我们需要存储的数据对象依次存入到这个表里面。如,要统计公司里面小明团队的人员信息,可以设计出如图1中的工作表,并且存入数据。
图1 为了存储某种数据对象设计的表格
图1中的表格是专门为解决现实中某种数据对象的存储而设计的表格。这个表格的表头是横向排列的,而垂直方向则是用来存储对象数据。这种表格最大的特点就是,每一行中对应项所存入的数据其含义是一样的,如姓名这一项中,不管是哪一行其所代表的含义都是某个人的姓名,这个含义是不变的。因此,结合我们之前讲述的结构体的内容,很简单的就可以看出来这个表头可以用来定义一个结构体存储类型。
typedef struct{      int Number;      int WorkId;      char Name[20];      char Sex[10];      int age;      char PhoneNumber[20];      char HouseholdRegister[100];} OfficeWorker_t;
以上这个结构体包含了我们要存入的单个员工的所有信息,因此当我们需要存入小明的信息时,只需要定义一个“OfficeWorker_t”类型结构体,接着将小明这些维度的信息全部存入即可。接着按照这个方式存入其他人的姓名。这时候我们会发现,如果使用这种方式存入这些员工的信息时,我们最终会得到5个独立的结构体,最终这5个独立的结构体之间不会有任何关联,也没有任何规律。如何将这5个独立的结构体有序地结合起来就是我们今天需要讨论的问题。
想要将5个独立的结构体有序地结合起来主要有两种方法,接下来本小节内容,我们来详细讨论第一种结合方法,即结构体数组表。
  结构体数组表
想要有序地将多个结构体变量组合起来,没有什么比数组更加直接,更加便捷的方法了,我们只需要定义一个“OfficeWorker_t”数组,接着把所有员工的信息写入进去即可。具体代码如图2所示。
图2 填入小明的信息
图2仅仅列出了小明信息的填写,按照上述内容依次写入其余员工的信息即可。但是以这种方式填入信息重复代码太过于多,阅读起来显得繁琐不堪,因此,我们可以将信息录入写成一个独立的函数,这样的话就可以将代码简化了,如图3所示。
图3 结构体数组存储信息

图3中的源码
#include<stdio.h>#include<string.h>static void WorkerInfoRecord(int Number, int WorkId, char *Name, char *Sex, int age, char *PhoneNumber, char *HouseholdRegister);typedef struct { int Number; int WorkId; char Name[20]; char Sex[10]; int age; char PhoneNumber[20]; char HouseholdRegister[100];} OfficeWorker_t;OfficeWorker_t WorkInfo[5]; //定义OfficeWorker_t类型的结构体数组int main(void){ int i; WorkerInfoRecord(1, 60001, "Xiaoming", "Male", 34, "16677789076", "Shanghai");//填入小明的信息 WorkerInfoRecord(2, 60012, "XiaoLi", "Female", 29, "17767812312", "Jiangsu"); //填入小丽的信息 WorkerInfoRecord(3, 60106, "Xiaoqiang", "Male", 30, "18910023897", "Hubei"); //填入小强的信息 WorkerInfoRecord(4, 60113, "Xiaowang", "Male", 38, "17776388990", "Hubei"); //填入小王的信息 WorkerInfoRecord(5, 60128, "Xiaoyu", "Male", 38, "16090077882", "Xinjiang");//填入小于的信息 for(i = 0; i < 5; i ++) { printf("\t%d\t%d\t%-20s\t%s\t%d\t%s\t%s\n", WorkInfo[i].Number, WorkInfo[i].WorkId, WorkInfo[i].Name,\ WorkInfo[i].Sex, WorkInfo[i].age, WorkInfo[i].PhoneNumber, \ WorkInfo[i].HouseholdRegister); }}static void WorkerInfoRecord(int Number, int WorkId, char *Name, char *Sex, int age, char *PhoneNumber, char *HouseholdRegister){ WorkInfo[Number - 1].Number = Number; WorkInfo[Number - 1].WorkId = WorkId; strcpy(WorkInfo[Number - 1].Name, Name); strcpy(WorkInfo[Number - 1].Sex, Sex); WorkInfo[Number - 1].age = age; strcpy(WorkInfo[Number - 1].PhoneNumber, PhoneNumber); strcpy(WorkInfo[Number - 1].HouseholdRegister, HouseholdRegister);}
除了使用函数去写入结构体数组之外,我们还可以在定义结构体数组的时候就将我们需要录制的信息写进去,如图4所示。
图4 结构体数组初始化时写入信息
相比于图3中的代码,图4中的代码就显得简洁许多。我们甚至如果有很多数据需要存储的时候,甚至可以将其加上“const”关键词,作为常量存入程序存储器或者程序段中。
图4 中的原码
#include<stdio.h>#include<string.h>
typedef struct { int Number; int WorkId; char Name[20]; char Sex[10]; int age; char PhoneNumber[20]; char HouseholdRegister[100];} OfficeWorker_t;const OfficeWorker_t WorkInfo[5] = { {1, 60001, "Xiaoming", "Male", 34, "16677789076", "Shanghai" }, {2, 60012, "XiaoLi", "Female", 29, "17767812312", "Jiangsu" }, {3, 60106, "Xiaoqiang", "Male", 30, "18910023897", "Hubei" }, {4, 60113, "Xiaowang", "Male", 38, "17776388990", "Hubei" }, {5, 60128, "Xiaoyu", "Male", 38, "16090077882", "Xinjiang" },}; //定义OfficeWorker_t类型的结构体数组int main(void){ int i; for(i = 0; i < 5; i ++) { printf("\t%d\t%d\t%-20s\t%s\t%d\t%s\t%s\n", WorkInfo[i].Number, WorkInfo[i].WorkId, WorkInfo[i].Name,\ WorkInfo[i].Sex, WorkInfo[i].age, WorkInfo[i].PhoneNumber, \ WorkInfo[i].HouseholdRegister); }}

  结构体数组表的缺陷
看到现在,再向自己提一个问题,我们为何要将数据组合成一张表?这是因为,一个张优秀的表,可以将一些零散的数据有机的统一起来,除此之外,一张表还可以方便使用者对其增,删,改,查这四种操作。
利用结构体数组实现的表,可以理解成一种静态的表,因为利用它来实现增,删,改,查这四种操作并不是很友好。比如,当我们需要新增一个表的项目时,如果此时的结构体数组长度被定死,那么这个增加数据项的操作无疑是行不通的。硬要实现这个操作,我们唯一的方式就是预留出足够长的结构体数组的长度。这必然会造成不必要的存储资源浪费。
要解决这个问题,最佳的方法就是可以使表格中每一项都可以动态的增加和减少。即,当有一个新的表项需要被加入时,给新的表项分配一块内存,需要减少一个表项时,将这块内存释放。这就是我们下面小节会讲述的链式表。
  结构体数组表的操作
虽然结构体数组表或多或少存在这某些缺陷,但是它也是非常简单的一种表形式,我们可以做一个简单的查找功能。即当我们输入一个员工的工号时,将这个员工的信息打印出来。
其实这个操作很简单,即对这个结构体数组的工号这一项进行遍历比较,如果有,则记住这个结构体数组元素的索引,接着打印。如果遍历完没有找到,那么就输出没有该员工的信息。具体代码如图5所示。
图5 结构体数组表查找数据
图5中的源码
#include<stdio.h>#include<string.h>#define FAIL 0x00#define SUCCESS 0xFFtypedef struct { int Number; int WorkId; char Name[20]; char Sex[10]; int age; char PhoneNumber[20]; char HouseholdRegister[100];} OfficeWorker_t;const OfficeWorker_t WorkInfo[5] = { {1, 60001, "Xiaoming", "Male", 34, "16677789076", "Shanghai" }, {2, 60012, "XiaoLi", "Female", 29, "17767812312", "Jiangsu" }, {3, 60106, "Xiaoqiang", "Male", 30, "18910023897", "Hubei" }, {4, 60113, "Xiaowang", "Male", 38, "17776388990", "Hubei" }, {5, 60128, "Xiaoyu", "Male", 38, "16090077882", "Xinjiang" },}; //定义OfficeWorker_t类型的结构体数组int main(void){ int i; int IdToSearch; //搜索的ID int SearchResult = FAIL; //搜索结果 int SearchResultIndex = 0; //搜索成功的Index printf("Input the worker's ID you want to search:"); scanf("%d", &IdToSearch); /*遍历表*/ for(i = 0; i < 5; i ++) { if(WorkInfo[i].WorkId == IdToSearch) { SearchResult = SUCCESS; SearchResultIndex = i; break; } } if(SearchResult == SUCCESS) { printf("\t%d\t%d\t%-20s\t%s\t%d\t%s\t%s\n", WorkInfo[SearchResultIndex].Number, WorkInfo[SearchResultIndex].WorkId, \ WorkInfo[SearchResultIndex].Name, WorkInfo[SearchResultIndex].Sex, \ WorkInfo[SearchResultIndex].age, WorkInfo[SearchResultIndex].PhoneNumber, \ WorkInfo[SearchResultIndex].HouseholdRegister); } else { printf("The worker is not found\n"); }
}

(0)

相关推荐