這次大作業(yè)開(kāi)始構(gòu)思到寫完程序并測(cè)試完畢,經(jīng)歷了兩周多的努力。在初步分化好模塊之后,在網(wǎng)上找各種資料學(xué)習(xí)鏈表(比較推薦翁愷老師的課),后邊又學(xué)習(xí)了一些相對(duì)應(yīng)的知識(shí),像是鏈表的排序算法(因?yàn)榫τ邢拗粚W(xué)了插入排序)。準(zhǔn)備工作做完之后,剛開(kāi)始編寫程序就遇到了Segment fault報(bào)錯(cuò),因?yàn)槭堑谝淮斡面湵?,?duì)于這種報(bào)錯(cuò)完全是一頭霧水,問(wèn)了好幾個(gè)同學(xué),改了好幾天。最后實(shí)在沒(méi)辦法,又從頭寫了一遍。雖然現(xiàn)在回過(guò)頭來(lái)看,這玩意也沒(méi)那么難,但是實(shí)際學(xué)習(xí)過(guò)程中真是不簡(jiǎn)單。
因?yàn)橄胱鲆粋€(gè)模塊化的程序,每一個(gè)都可以配合mian函數(shù)獨(dú)立使用,所以像是遍歷,輸入文件這樣的功能重復(fù)出現(xiàn)了好幾次。
函數(shù)功能實(shí)現(xiàn)及參數(shù)分析
1,結(jié)構(gòu)體聲明
Worker結(jié)構(gòu)體包含了員工的工號(hào),姓名,基本工資。獎(jiǎng)金,扣款,應(yīng)發(fā)工資,實(shí)發(fā)工資和稅款信息;
List結(jié)構(gòu)體包含了鏈表的頭指針(head)和尾指針(tail),當(dāng)對(duì)包含頭指針和尾指針的結(jié)構(gòu)體修改的函數(shù)結(jié)束后,雖然結(jié)構(gòu)體不會(huì)保存,但指針?biāo)赶虻牡刂芬呀?jīng)被修改了,為函數(shù)省去了需要return的部分
2,Main函數(shù)
Main函數(shù)實(shí)現(xiàn)了讀取文件,鏈表創(chuàng)建和模塊選擇的功能;
變量Option用于控制switch結(jié)構(gòu),對(duì)執(zhí)行模塊進(jìn)行選擇;變量n用于創(chuàng)建鏈節(jié)時(shí)判斷當(dāng)前鏈節(jié)是否為頭節(jié)點(diǎn)。結(jié)構(gòu)體指針emp1和p兩個(gè)臨時(shí)變量,指針temp1負(fù)責(zé)指向malloc函數(shù)開(kāi)辟出的內(nèi)存區(qū)域,并承接文件傳進(jìn)來(lái)的數(shù)據(jù)。指針p每次循環(huán)負(fù)責(zé)將前一個(gè)鏈節(jié)的指針指向后一個(gè)鏈節(jié),并將指向后一個(gè)鏈節(jié),以此延長(zhǎng)鏈表。Boolean變量負(fù)責(zé)判斷while循環(huán)內(nèi)的switch函數(shù)是否執(zhí)行,switch函數(shù)負(fù)責(zé)調(diào)用各大模塊的函數(shù)。
3,輸出,查找,修改,刪除函數(shù)主體都有鏈表的遍歷
輸出操作,就是f臨時(shí)指針,for循環(huán)遍歷鏈表,遍歷的同時(shí),使用printf函數(shù)打印出來(lái)
查找操作,就是f臨時(shí)指針,賦給頭指針的值,for循環(huán)遍歷鏈表,找到與工號(hào)相匹配的鏈節(jié),printf將其輸出出來(lái)。
修改操作,f臨時(shí)指針,for循環(huán)遍歷鏈表,找到匹配鏈節(jié)后,scanf對(duì)該鏈節(jié)數(shù)據(jù)重新輸入,并計(jì)算其他數(shù)據(jù)。
刪除操作,f和p為臨時(shí)指針,f指向待刪除結(jié)點(diǎn),p指向前一個(gè)結(jié)點(diǎn),連接待刪除結(jié)點(diǎn)的前后兩個(gè)鏈節(jié),釋放該鏈節(jié)的空間,并使指針指向?yàn)榭?/p>
4,排序函數(shù)
指針lastSorted指向已經(jīng)參與排序的部分的末尾鏈節(jié),
指針curr指向下一步待插入到已排列部分的鏈節(jié);
指針prev指向待插入鏈節(jié)在已排列部分該插入位置的前一個(gè)鏈節(jié);
指針dummyhead便于在頭結(jié)點(diǎn)插入鏈節(jié);
在鏈表前端人為創(chuàng)造一個(gè)已排序的有序部分,初始時(shí)只有一個(gè)頭節(jié)點(diǎn),curr指針指向lastSorted后方第一個(gè)鏈節(jié)。此時(shí)從已排序部分遍歷,找到剛好小于等于它的結(jié)點(diǎn),將curr結(jié)點(diǎn)插入到該結(jié)點(diǎn)后方,再完成指針的鏈節(jié)。直到鏈表中的所有元素都加入到有序的部分,這個(gè)鏈表也就完成了排序;
首先做好函數(shù)聲明與結(jié)構(gòu)體聲明
#include#include#include#include#define LEN sizeof(Worker)
typedef struct _Worker
{
int num; //工號(hào)
char name[20]; //姓名
float base_salay; //基本工資
float bonus; //獎(jiǎng)金
float fine; //扣款
float salay; //應(yīng)發(fā)工資
float real_salay; //實(shí)發(fā)工資
float tax; //稅款
struct _Worker *next; //指向下一鏈節(jié)的指針
} Worker;
typedef struct _list //便于傳遞頭指針和尾指針,程序執(zhí)行完畢可以不使用return
{
Worker *head;//頭指針
Worker *tail;//尾指針
}List;
void Menu(); //菜單函數(shù)
void Print(List list); //輸出函數(shù)
void Add(List list); //增添函數(shù)
void Delate(List list); //刪除函數(shù)
void Amend(List list); //修改函數(shù)
void Seek(List list); //查找函數(shù)
void Sort(List list); //排序函數(shù)
void Statis(List list); //統(tǒng)計(jì)函數(shù)
Worker結(jié)構(gòu)體
是鏈表的基礎(chǔ),可分為兩個(gè)部分,一部分是儲(chǔ)存數(shù)據(jù)的
這個(gè)List結(jié)構(gòu)是我在翁愷老師的c語(yǔ)言鏈表視頻里學(xué)習(xí)到的,雖然是結(jié)構(gòu)體,但他就只包含了兩個(gè)指針。這兩個(gè)指針?lè)謩e指向頭指針和尾指針。因?yàn)樵谝恍┖瘮?shù)里會(huì)對(duì)頭指針,尾指針進(jìn)行修改,而指針本身只是一個(gè)地址,所以在函數(shù)內(nèi)修改后還需要返回值給main函數(shù),為了方便一些,創(chuàng)建一個(gè)指針的指針
以下為全部代碼,需配合對(duì)應(yīng)txt文件使用
#include#include#include#include#define LEN sizeof(Worker)
typedef struct _Worker
{
int num; //工號(hào)
char name[20]; //姓名
float base_salay; //基本工資
float bonus; //獎(jiǎng)金
float fine; //扣款
float salay; //應(yīng)發(fā)工資
float real_salay; //實(shí)發(fā)工資
float tax; //稅款
struct _Worker *next; //指向下一鏈節(jié)的指針
} Worker;
typedef struct _list //便于傳遞頭指針和尾指針,程序執(zhí)行完畢可以不使用return
{
Worker *head;//頭指針
Worker *tail;//尾指針
}List;
void Menu(); //菜單函數(shù)
void Print(List list); //輸出函數(shù)
void Add(List list); //增添函數(shù)
void Delate(List list); //刪除函數(shù)
void Amend(List list); //修改函數(shù)
void Seek(List list); //查找函數(shù)
void Sort(List list); //排序函數(shù)
void Statis(List list); //統(tǒng)計(jì)函數(shù)
int main()
{
List list; //包含鏈表頭指針和尾指針
int option; //用于switch函數(shù),對(duì)程序功能進(jìn)行選擇
int n=0; //用于判斷鏈表節(jié)點(diǎn)的位置
Worker *temp1,*p; //兩個(gè)臨時(shí)指針,交替向后移動(dòng),以創(chuàng)建鏈表
FILE *fp;
if((fp=fopen("worker.txt","r+"))==NULL){
printf("文件打開(kāi)失敗\n]");
system("pause");//打開(kāi)失敗后按下按鍵即可退出程序
}
else{
printf("文件打開(kāi)成功\n");
}//打開(kāi)文件并對(duì)打開(kāi)結(jié)果是否成功進(jìn)行判斷并提示
while (feof(fp)==0)//while對(duì)文檔中的數(shù)據(jù)進(jìn)行讀取
{
n++;
temp1 = (Worker*)malloc(LEN);
fscanf(fp,"%d %s %f %f %f %f %f %f",
&temp1->num,&temp1->name,&temp1->base_salay,
&temp1->bonus,&temp1->fine,&temp1->salay,&temp1->real_salay,&temp1->tax);
temp1->next=NULL;
if (n==1){
list.head=temp1;//頭指針
}
else
p->next=temp1;
p=temp1;
}
list.tail=p;//尾指針
printf("文件數(shù)據(jù)讀入完成\n");
fclose(fp);//文件關(guān)閉
fp=NULL;
int boolean=1;//布爾值,用于判斷while是否進(jìn)行
do{
Menu(); //程序打開(kāi)后先輸出菜單欄目
printf("\n請(qǐng)輸入與模塊相對(duì)應(yīng)的數(shù)字進(jìn)行使用\n");
scanf("%d",&option);
//do while 循環(huán),實(shí)現(xiàn)一次打開(kāi),多次使用
switch(option)
{
case 1:
Print(list);//輸出函數(shù)
break;
case 2:
Add(list);//增添函數(shù)
break;
case 3:
Delate(list);//刪除函數(shù)
break;
case 4:
Amend(list);//修改函數(shù)
break;
case 5:
Seek(list);//查找函數(shù)
break;
case 6:
Sort(list);//排序函數(shù)
break;
case 7:
Statis(list);//統(tǒng)計(jì)函數(shù)
break;
default:
printf("選擇輸入錯(cuò)誤,請(qǐng)重新選擇\n");
break;
}
printf("\n如果繼續(xù)使用程序請(qǐng)輸入1,結(jié)束使用則輸入0\n");
scanf("%d",&boolean);
system("cls");
}while(boolean==1);
return 0;
}
void Menu()
{
printf("\n\n\t歡迎使用工資信息管理系統(tǒng)\n");
printf("\t本程序含有以下功能模塊\n");
printf("\t請(qǐng)輸入與模塊相對(duì)應(yīng)的數(shù)字進(jìn)行使用\n");
printf("\n\t--------工資信息管理系統(tǒng)---------\n"
"\t|1.輸出模塊\t\t\t|\n"
"\t|2.添加模塊\t\t\t|\n"
"\t|3.刪除模塊\t\t\t|\n"
"\t|4.修改模塊\t\t\t|\n"
"\t|5.查找模塊\t\t\t|\n"
"\t|6.排序模塊\t\t\t|\n"
"\t|7.統(tǒng)計(jì)模塊\t\t\t|\n"
"\t---------------------------------\n");
}
void Print(List list)
{
Worker *f=list.head;
printf("\n工號(hào) 姓名 基本工資 獎(jiǎng)金 扣款 應(yīng)發(fā)工資 實(shí)發(fā)工資 稅款\n");
for(;f;f=f->next)
{
printf("%-6d %-15s %-9.2f %-9.2f %-9.2f %-9.2f %-9.2f %-9.2f\n"
,f->num,f->name,f->base_salay,f->bonus,f->fine,f->salay,f->real_salay,f->tax);
}
}
void Seek(List list)
{
int number;
Worker *f; //臨時(shí)指針
printf("\n請(qǐng)輸入你要查找的員工號(hào)\n");
scanf("%d",&number);
f=list.head;//將頭指針賦給臨時(shí)指針
for (;f;f=f->next)
{
if(f->num==number){
printf("查詢成功\n");
printf("\n工號(hào) 姓名 基本工資 獎(jiǎng)金 扣款 應(yīng)發(fā)工資 實(shí)發(fā)工資 稅款\n");
printf("%-6d %-10s %-9.2f %-9.2f %-9.2f %-9.2f %-9.2f %-9.2f\n"
,f->num,f->name,f->base_salay,f->bonus,f->fine,f->salay,f->real_salay,f->tax);
break;
}
} //遍歷鏈表,將員工號(hào)與輸入的數(shù)字相匹配
}
void Add(List list)
{
FILE *fp;//打開(kāi)文件
if((fp=fopen("worker.txt","a+"))==NULL){
printf("文件打開(kāi)失敗\n");
exit(0);
}
Worker *f;//臨時(shí)指針
int boolean;
do{
f=(Worker*)malloc(LEN);//由malloc函數(shù)
printf("\n請(qǐng)輸入你要添加的員工信息\n"
"依次為\n員工號(hào) 姓名 基本工資 獎(jiǎng)金 扣款\n");
scanf("%d %s %f %f %f",&f->num,f->name,&f->base_salay,&f->bonus,&f->fine);
printf("\n如果繼續(xù)添加員工信息請(qǐng)輸入1,結(jié)束輸入則輸入0\n");
scanf("%d",&boolean);
f->salay=f->base_salay-f->fine+f->bonus;//應(yīng)發(fā)工資的計(jì)算
if(f->salay<=5000)
f->tax=0;
else if(f->salay<=6500)
f->tax=(f->salay-5000)*0.03;
else if(f->salay<=9500)
f->tax=(f->salay-5000)*0.1-105;
else if(f->salay<=14000)
f->tax=(f->salay-5000)*0.2-555;
else if(f->salay<=40000)
f->tax=(f->salay-5000)*0.25-1005;
else if(f->salay<=60000)
f->tax=(f->salay-5000)*0.3-2755;
else if(f->salay<=85000)
f->tax=(f->salay-5000)*0.35-5505;
else
f->tax=(f->salay-5000)*0.45-13505;
//稅款計(jì)算
f->real_salay=f->salay-f->tax;//實(shí)發(fā)工資
fprintf(fp,"\n%d %s %f %f %f %f %f %f"
,f->num,f->name,f->base_salay,f->bonus,f->fine,f->salay,f->real_salay,f->tax);
//將新開(kāi)辟的空間所儲(chǔ)存的數(shù)據(jù)
list.tail->next=f; //將新鏈節(jié)與鏈表相連
list.tail=list.tail->next;//更新尾指針
list.tail->next=NULL;//保持尾指針的next指針指向?yàn)榭?
printf("輸入成功\n");
}while (boolean!=0);
fclose(fp);//關(guān)閉文件
fp=NULL;
}
void Delate(List list)
{
FILE *fp;
if((fp=fopen("worker.txt","w+"))==NULL){
printf("文件打開(kāi)失敗\n]");
exit(0);
}
//打開(kāi)文件
int number;//員工號(hào)碼
printf("\n請(qǐng)輸入要?jiǎng)h除的員工信息的員工號(hào)\n");
scanf("%d",&number);
Worker *f=list.head;//臨時(shí)指針,將頭指針賦給它
Worker *p=NULL; //臨時(shí)指針
for(;f;p=f,f=f->next)//f為所求鏈節(jié),p為前一鏈節(jié)
{
if(f->num==number)
{
printf("你正在刪除的員工姓名為%s\n",f->name);
if(f==list.head){//特殊情況,刪除頭節(jié)點(diǎn)
list.head=f->next;
}
else{
if(f==list.tail){//特殊情況,刪除尾結(jié)點(diǎn)
list.tail=p;
list.tail->next=NULL;
}
else{
p->next=f->next;//將前一鏈節(jié)的next指針,指向f的后一鏈節(jié),以此跳過(guò)f,重新連接鏈表
}
}
free(f);//釋放空間
break;
f=NULL;//指針賦空
}
}
printf("刪除成功,正在同步至文本文件\n");
for(f=list.head;f;f=f->next)
{
fprintf(fp,"\n%d %s %f %f %f %f %f %f"
,f->num,f->name,f->base_salay,f->bonus,f->fine,f->salay,f->real_salay,f->tax);
}//將整個(gè)鏈表重新輸入到文件中
printf("同步成功\n");
fclose(fp);//文件關(guān)閉
fp=NULL; //指針賦空
}
void Amend(List list)
{
FILE *fp;//文件打開(kāi)
if((fp=fopen("worker.txt","w+"))==NULL){
printf("文件打開(kāi)失敗\n]");
exit(0);
}
int number;
printf("\n請(qǐng)輸入要修改的員工信息的員工號(hào)\n");
scanf("%d",&number);
Worker *f;
Worker *p=NULL;
//f和p都是臨時(shí)指針
for(f=list.head;f;f=f->next)//鏈表遍歷并尋找該鏈節(jié)
{
if(f->num==number)
{
printf("將要修改信息的員工姓名為%s\n",f->name);
printf("請(qǐng)重新輸入該員工的信息\n"
"依次為 員工號(hào) 姓名 基本工資 獎(jiǎng)金 扣款\n");
scanf("%d %s %f %f %f",&f->num,f->name,&f->base_salay,&f->bonus,&f->fine);
f->salay=f->base_salay-f->fine+f->bonus;//應(yīng)發(fā)工資的計(jì)算
if(f->salay<=5000)
f->tax=0;
else if(f->salay<=6500)
f->tax=(f->salay-5000)*0.03;
else if(f->salay<=9500)
f->tax=(f->salay-5000)*0.1-105;
else if(f->salay<=14000)
f->tax=(f->salay-5000)*0.2-555;
else if(f->salay<=40000)
f->tax=(f->salay-5000)*0.25-1005;
else if(f->salay<=60000)
f->tax=(f->salay-5000)*0.3-2755;
else if(f->salay<=85000)
f->tax=(f->salay-5000)*0.35-5505;
else
f->tax=(f->salay-5000)*0.45-13505;//稅款計(jì)算
f->real_salay=f->salay-f->tax;//實(shí)發(fā)工資
break;
}
}
printf("修改成功,正在同步至文本文件\n");
for(f=list.head;f;f=f->next)
{
fprintf(fp,"\n%d %s %f %f %f %f %f %f"
,f->num,f->name,f->base_salay,f->bonus,f->fine,f->salay,f->real_salay,f->tax);
}//鏈表同步至文件
printf("同步成功\n");
fclose(fp);//文件關(guān)閉
fp=NULL; //指針賦空
}
void Statis(List list)
{//求薪資最高的人的名字,和平均薪資
Worker *f;//臨時(shí)指針,薪資最高
Worker *max;
max=NULL;//指向?yàn)榭? float sum,average;//總和,平均工資
int n=1;//記錄人數(shù)
sum=0;
for(max=f=list.head;f->next;n++,f=f->next)
{
sum=f->real_salay+sum;//求和
if(f->real_salay>=max->real_salay)
{
max=f;//f和f所指的進(jìn)行比較
}
}
average=sum/n;//用和求平均
printf("員工平均薪資為%f\n薪資最高的員工是%s\n",average,max->name);
}
void Sort(List list)
{
FILE *fp;//文件打開(kāi)
if((fp=fopen("worker.txt","w+"))==NULL){
printf("文件打開(kāi)失敗\n]");
exit(0);
}
Worker* dummyHead=(Worker*)malloc(LEN);//啞節(jié)點(diǎn),便于在頭節(jié)點(diǎn)之前插入節(jié)點(diǎn)
dummyHead->next=list.head;
Worker *lastSorted;//已排序的最后一個(gè)鏈節(jié)
Worker *curr;//待插入元素
lastSorted=list.head;//初始時(shí)賦為頭指針
curr=list.head->next;//待插入元素為第二個(gè)鏈節(jié)
while(curr)
{
if(lastSorted->num<=curr->num)//進(jìn)行比較
{
lastSorted=lastSorted->next;
}
else
{
Worker *prev=dummyHead;//待插入節(jié)點(diǎn)的前一個(gè)結(jié)點(diǎn)
while(prev->next->num<=curr->num)
{
prev=prev->next;
}
//遍歷鏈表,找到剛好小于待插入節(jié)點(diǎn)的那一個(gè)結(jié)點(diǎn)prev
lastSorted->next=curr->next;//將已排序的最后一個(gè)鏈節(jié)指向要交換的鏈節(jié)的下一個(gè)鏈節(jié)
curr->next=prev->next;//將待插入節(jié)點(diǎn)與prev的后方的鏈節(jié)相連
prev->next=curr;//將prev與待插入結(jié)點(diǎn)相連
}
curr=lastSorted->next;//待插入結(jié)點(diǎn)重新定位到有序部分的后一個(gè)鏈節(jié)
list.head=dummyHead->next;//如果出現(xiàn)插入到頭節(jié)點(diǎn)前方的現(xiàn)象,可以更新頭節(jié)點(diǎn)
}
Worker *f;
printf("排序完成正在同步至文本文件\n");
//鏈表同步至文件
for(f=list.head;f;f=f->next)
{
fprintf(fp,"\n%d %s %f %f %f %f %f %f"
,f->num,f->name,f->base_salay,f->bonus,f->fine,f->salay,f->real_salay,f->tax);
}
printf("同步成功\n");
}
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧
文章標(biāo)題:工資管理系統(tǒng)/c語(yǔ)言期末大作業(yè)學(xué)習(xí)經(jīng)歷-創(chuàng)新互聯(lián)
轉(zhuǎn)載注明:http://jinyejixie.com/article8/cshcop.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供服務(wù)器托管、建站公司、虛擬主機(jī)、網(wǎng)站營(yíng)銷、商城網(wǎng)站、小程序開(kāi)發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容