C语言编程基础之知识总结
前言
小编学习C语言也有一段时间啦,这一篇博客就来总结一下所学的知识以及做过的一些程序,作为一个学习路上的小小印记吧。
一、C语言基础思维导图
二、打卡机制作
1、设计要求
应市场需求,某工程师现设计了一款新上下班打卡机,打卡机具有以下功能:
(1)上班打卡,员工具有编号(首位为 1 的六位编号),输入编号后,再输入校验码,校验码生成规则:员工编号除首位反序,再与员工编号和,如:员工编号,110086,校验码为 178087。校验码错误即打卡失败。记录打卡时间 。
(2)下班打卡,只需输入员工编号即可。记录打卡时间,显示该人员今天上班时长,如果上班时长不够,显示早退 xx 分钟。可以更新下班打卡时间。无下班打卡显示缺卡。
(3)可以设置规定上班时长,如 9 小时
(4)测试需要可以规定 6 秒=实际 1 小时,每次测试,输入指令后,开启打卡机,打卡机开启模拟时间为:周一早上七点。程序运行结束为周五晚 12 点。
(5)实行弹性打卡制,如前一天上班时长超过规定时长 3 小时以上,第二天迟到 2 小时以内不算迟到。
(6)打卡机运行结束之前,每周该打卡机会生成每周考勤周报,显示周平均上班时长,周迟到,早退,缺卡次数等。
要求:合理定义所需函数,主函数中只允许有 clockin_machine_start() 调用。
2、设计思路
代码实现
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
//测试说明:程序执行一次为一天,上班打卡-下班打卡操作需要执行五次才能输出周报
//声明函数
void get_startwork_time();//获得上班时间
void show_startwork_time();//展示上班时间
void gettime_knock_off();//得到下班时间
void showtime_knock_off();//展示下班时间
//定义结构体,用来储存数据
struct member
{
int number;//员工编号
int staff_code;//校验码
int hour;//上班时
int minute;//上班分
int sec;//上班秒
int hour_back;//下班时
int minute_back;//下班分
int sec_back;//下班秒
}member1;
//定义全局变量
static double working_time,worktime;//工作时间
static int timelate,leave_early,lack_punch_card;//迟到,早退,缺卡
static int buffer_mechanism;
void clockin_machine_start()//主函数部分
{
int staff_code=0,staff_number=0,staff_number_2=0;
printf("[tips:110086]\n请输入员工编号:");
scanf("%d",&staff_number); //staff_number=110086
member1.number = staff_number; //将员工编号传给结构体
staff_number_2=staff_number-100000; //staff_number_2=10086
while (staff_number_2) //迭代算法 10086->68001
{
staff_code=staff_code*10+staff_number_2%10;
staff_number_2=staff_number_2/10;
}
staff_code=staff_code+staff_number;//staff_code=178087
member1.staff_code = staff_code; //将得到的校验码传给结构体
int verification_code= 0;//定义输入验证码变量
printf("[tips:178087]\n请输入验证码:");
scanf("%d",&verification_code);
while(member1.staff_code != verification_code)//判断输入是否正确,直到输入成功为止->扩展(未实现):三次输入机会,不然就打卡失败。
{
printf("校验码错误,请重新输入:");
scanf("%d",&verification_code);
}
printf("正确,打卡成功!\n");
printf("---------------------------------\n");
//获取当前上班时间,并传递给结构体
get_startwork_time();
//向用户展示当前上班时间和是否迟到
show_startwork_time();
printf("---------------------------------\n");
//下班要求用户输入员工编号完成打卡
printf("下班请打卡:\n");
printf("[tips:110086]\n请输入员工编号:\n");
int number_back = 0;//定义输入变量
int number = member1.number;//从结构体数据,获取一次员工编号
do
{
scanf("%d",&number_back);
if (number_back != member1.number)//判断是否与之前输入的相等,若不相等则重新要求用户输入
{
printf("编号错误,请重新输入!\n");
}
}while(member1.number != number_back);
gettime_knock_off();//获取下班时间,并传递给结构体
if(member1.hour_back == 0)//若没有下班时间,则显示缺卡,且缺卡次数加一,否则显示下班时间、当天的工作时长、是否实行缓冲机制
{
printf("缺卡!\n");
lack_punch_card++;
}
else{
showtime_knock_off();
}
printf("---------------------------------\n");
}
//自定义子函数部分
void get_startwork_time()//获取系统时间函数作为上班打卡时间点
{
//获取上班时间
time_t t;
struct tm* It;
time(&t);
It = localtime(&t);
//将时间传递给结构体
member1.hour = It->tm_hour;
member1.minute = It->tm_min;
member1.sec = It->tm_sec;
//展示当前时间
printf("当前时间:%d年%d月%d日 星期%d %d:%d:%d\n",(1900 + It->tm_year),(1 + It->tm_mon),It->tm_mday,It->tm_wday,It->tm_hour, It->tm_min, It->tm_sec);
}
void show_startwork_time()//展示上班时间,统计记录时间信息
{
//展示员工编号和上班时间
printf("员工编号:%d\n",member1.number);
printf("上班时间:%d:%d:%d\n",member1.hour,member1.minute,member1.sec);
//上班时间为7点前,在7点到9点之间属于迟到,9点后属于缺卡
//如果触发了缓冲机制,则判断上班时间是不是迟到两小时内
if(member1.hour >= 9)
{
printf("上午缺卡\n");
lack_punch_card++;//缺卡+1次
}
else if(member1.hour < 9 && member1.hour >= 7)
{
printf("您迟到了!\n");
printf("迟到:%d小时%d分钟\n",(member1.hour-7),member1.minute);//展示迟到时长
timelate++;//迟到+1次
}
else if(member1.hour < 7 )
{
printf("上班打卡成功!\n");
}
else
{
printf("上班打卡成功!\n");
}
}
void gettime_knock_off()//获取下班时间
{
time_t t;
struct tm* It;
time(&t);
It = localtime(&t);
//下班时间传递给结构体
member1.hour = It->tm_hour;
member1.minute = It->tm_min;
member1.sec = It->tm_sec;
//方便调试,6秒钟等于1小时
//ti->tm_sec = ti->tm_sec*600;
//member1.hour_back = ti->tm_hour + ((ti->tm_sec - member1.sec));
printf("---------------------------------\n");
//展示当前时间
printf("当前时间:%d年%d月%d日 星期%d %d:%d:%d\n",(1900 + It->tm_year),(1 + It->tm_mon),It->tm_mday,It->tm_wday,It->tm_hour, It->tm_min, It->tm_sec);
}
void showtime_knock_off()
{
printf("员工编号:%d\n",member1.number);//展示员工编号,下班时间,打卡成功
printf("下班时间:%d:%d:%d\n",member1.hour_back , member1.minute_back , member1.sec_back);
printf("下班打卡成功!\n");
//worktime += (member1.hour_back - member1.hour)*60 + (member1.minute_back - member1.minute);//累计每天的上班时间,在周报里展示
//将上班时长传给结构体
//member1.worktime += worktime;
//printf("work=%d",worktime);
//上班时长为9小时
int time = 9;
//获得用户上班时长
int tmp = member1.hour_back - member1.hour;
switch(tmp){
//上班时长为0\1\2\3\4\5\6\7小时的用户
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
//上班时间刚好为n小时
if(member1.minute_back == member1.minute)
{
printf("早退:%d小时%d分钟\n",(time - (member1.hour_back - member1.hour)),member1.minute - member1.minute_back);
}
//上班时间不足n小时
else if(member1.minute_back < member1.minute)
{
printf("早退:%d小时%d分钟\n",time - (member1.hour_back - member1.hour),member1.minute - member1.minute_back);
}
//上班时间超过n小时,但不足n+1小时
else
{
printf("早退:%d小时%d分钟\n",(time - (member1.hour_back - member1.hour)) , 60 - (member1.minute_back - member1.minute));
}
//以上时段都为早退,则早退次数加一
leave_early++;
break;
case 8:
//上班时间不足8小时
if(member1.minute > member1.minute_back)
{
printf("早退:%d小时%d分钟\n",time - 1 , member1.minute - member1.minute_back);
}
//上班时间刚好或超过8小时
else
{
printf("早退:%d分钟\n",(member1.minute + (60 - member1.minute_back)));
}
//为早退,早退次数加一
leave_early++;
break;
case 9:
//上班时间不足9小时,为早退,早退次数加一
if(member1.minute > member1.minute_back){
printf("早退:%d\n",member1.minute - member1.minute_back);
leave_early++;
}
//上班时长超过9小时,正常下班,打印上班时长
else
{
printf("上班时长:%d小时%d分钟\n",time , member1.minute_back - member1.minute);
}
break;
case 10:
case 11:
case 12:
//上班时长还没超过缓冲机制时间
if(member1.minute > member1.minute_back)
{
printf("上班时长:%d小时%d分钟\n",member1.hour_back - member1.hour - 1 , 60 - member1.minute + member1.minute_back);
}
else
{
printf("上班时长:%d小时%d分钟\n",member1.hour_back - member1.hour , member1.minute_back - member1.minute);
}
break;
case 13:
case 14:
case 15:
case 16:
//上班时长超过缓冲机制时间
if(member1.minute > member1.minute_back)
{
printf("上班时长:%d小时%d分钟\n",member1.hour_back - member1.hour - 1 , 60 - member1.minute + member1.minute_back);
}
else{
printf("上班时长:%d小时%d分钟\n",member1.hour_back - member1.hour , member1.minute_back - member1.minute);
buffer_mechanism = 1;
printf("上班时长超过3小时及以上,第二天迟到2小时以内不算迟到!\n");
}
break;
//工作超过17小时的属于下午缺卡
default:
printf("下午缺卡!\n");
lack_punch_card++;
}
}
int main(int argc,char *argv[])
{
//累加上班天数,一周五天
int j=6;
for(int i=0;i<j;i++)
{
clockin_machine_start();
}
//计算平均上班时长
worktime = (worktime / 5) / 60;
//打印周报
printf("打卡周报:\n");
printf("上班平均时长:%f小时\n",working_time);//功能未实现
printf("周迟到数:%d次\n",timelate);
printf("早退次数:%d次\n",leave_early);
printf("缺卡次数:%d次\n",lack_punch_card);
return 0;
}
这是个基础版的打卡机,还有一些bug,有待进一步改善…
三、日历实现
设计要求:
编写一个日历程序
以1990年为基准(1990年第一天为星期一),要求输入一个年月,输出对应月份的日历表
技能目标:
综合运用循环、判断分支结构,对程序进行格式化输入、输出,结构化编程
#include<stdio.h>
#include<stdlib.h>
int mon[2][13] = { { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
{ 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } };
//判断闰年,是闰年,如果是返回1,不是返回0
int isleap(int year)
{
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
return 1;
else
return 0;
}
//年份的第一天
int first_day_of_year(int year)
{
int base_year = 1990; //定义一个基准年1990年
int first_day = 1; //基准天:1990年1月1号是星期1
int i = 0;
int total = 0; //天数总和
for (i = base_year; i < year; i++)
{
total = total + 365 + isleap(i); //isleap函数用于判断年份是否是闰年,如果是返回1,不是返回0
}
return (total+first_day)%7;
}
//月份第一天
int first_day_of_month(int year, int month, int first_year)
{
int total = 0; //天数和
int i = 0;
for(i = 1; i < month; i++)
{
total = total + mon[isleap(year)][i];
}
return (total + first_year) % 7;
}
//展示日历
void show(int year,int month, int first_month)
{
int i = 0;
printf("一 二 三 四 五 六 日\n");
for (i = 0; i < first_month-1; i++)
{
printf(" "); //月份第一天是从first_month开始的,所以首先打印first_month-1个空格
}
for (i = 1; i <= mon[isleap(year)][month]; i++)
{
printf("%-5d", i);
if ((first_month-1+i) % 7 ==0) //如果(数字+空格数)%7==0,则换行
printf("\n");
}
printf("\n");
}
int main()
{
int year, month;
printf("请按以下格式输入年月:year/month:"); //输入你想打印的年份
scanf("%d/%d", &year, &month);
printf("%d年%d月:\n",year, month);
int first_year = first_day_of_year(year);//年份第一天
int first_month = first_day_of_month(year, month, first_year);//月份第一天
show(year, month, first_month);
system("pause");
return 0;
}
运行结果
四、数字排序
设计要求:
写一段程序,将3,1,5,6,7这5个数进行排序,排序方式不限,形式不限、运用学习的基本变量、基本运算、基本结构的知识完成。
#include<stdio.h>
//将数字由小到大依次输出
int main()
{
int i,j,a[5] = {3,1,5,6,7};//将五个数进行比较,从小到大排序
for ( i = 0; i < 4; i++)//两个数之间比较,需要比较5-1次
{
if(a[i]>a[i+1])//将两个数比较,前面一个数比后面一个数大就进行值交换
{
j=a[i+1];
a[i+1]=a[i];
a[i]=j;
}
}
for(i=0;i<5;i++)//循环输出已经排好序的数字
{
printf("%d\t",a[i]);
}
return 0;
}
运行结果
本次博客分享就到这里啦,谢谢你的过往。