C语言课程设计-计算年龄问题

题目:

计算年龄

【教学目标】

关键词:指针,字符串

知识和能力目标:

能够熟练、规范使用流程图描述算法。熟练使用数组、循环结构进行排序操作。理解冒泡排序的方法,并能编程实现。能够选用优化的冒泡排序算法。

价值目标: 

工程素质:信息编码(Information Coding)是指在进行信息处理时,赋予信息元素以代码的过程,其目的是为了方便信息的存储、检索和使用。信息编码的基本原则是在逻辑上满足使用者的要求,又适合于处理的需要。编码的结构应易于理解和掌握,编码还应有广泛的适用性,易于扩充。

【问题描述】

中国国家质量技术监督局于1999年实施的GB11643-1999《公民身份号码》中明确规定了18位身份证标准。其中,前6位为地址码;第7至14位为出生日期码;第15至17位为顺序码,第18位为校验码。校验码是根据前面17位数字码,按照ISO7064:1983.MOD11-2校验码计算得到,其取值范围是0至10。其中,10用罗马数字符X表示。

【问题说明】

(1) 本问题中,计算年龄的对应时间不确定。

(2) 请自行编写主程序验证函数,输出格式不限。

【实验结果】

1. 请编写实验《课程报告》,格式见附件一。

2. 讨论一下。

请在《课程报告》中回应以下问题。

(1) 我国的身份证编码是如何体现了广泛适用性特点的?请简述你的看法。

(2) 教师提出的其他问题。

课程报告:

计算年龄

0 题目

计算年龄问题

1 问题描述

本问题要求从键盘输入一个身份证号码(存在罗马数字X),并根据当前日期来计算此人是否成年。

2 问题分析

输入:已知身份证号码中第7至14位为出生日期码且可能存在罗马数字X,因此可用字符串存储。

输入数据描述:char input[19];

输出:字符串:”此人已成年\n”/”此人未成年\n”

3. 实验结果记录

实验数据共六组:成年人的身份证号,未成年人的身份证号,存在罗马数字X的身份证号,并有意测试边界条件。

(1)测试数据1

(2)测试数据2

(3)测试数据3

(4)测试数据4

(5)测试数据5

(6)测试数据6

4 实验分析及结论

4.1 实验心得

经过反复测试和调试,最终达到了问题要求。总结本次实验中遇到的问题,主要有三方面。

(1)从身份证中提取目标信息方法不适宜

     编码时尝试使用for循环来提取身份证中的出生年月日信息,但发现需要添加很多条件判断语句,使得代码逻辑复杂,更为臃肿,效率低下。

修改:因为身份证上的出生日期位置确定,可以直接使用字符数组的下表访问元素并使用,故修改为:

2)条件判断表达式书写错误

测试时发现相等运算符”==”错误书写为赋值运算符”=”。将if (time[1] = month)修改为if (time[1] == month)

(3)需要注意日期的边界问题

本次编码时特地注意了对边界条件的判断,在修改完语法上的错误和编码时的误操作后,并未发现逻辑上的遗漏。如测试数据1:2000年1月1日出生的人在2018年1月1日刚好成年,程序成功判断为成年人。但是在今后的编码时仍当注意检查对边界条件的判断。

4.2 实验结论

本实验是对当前日期和身份证上的出生日期进行运算,判断身份证持有人是否成年。从6组测试数据的结果看,程序符合预期,全部测试结果均符合题目要求。本题采用了字符串存储身份证号,并在后续的程序中进行数据提取。但实际上由于输入的身份证号并不存在空格,可以使用scanf与for语句在输入的时候直接提取,不使用字符串数组,可以节省更多空间。在后续学习过程中,将进一步对各种输入和数据处理方式进行研究和比较。

5 讨论一下

    回应案例的“讨论一下”中的问题

(1) 我国的身份证编码是如何体现了广泛适用性特点的?请简述你的看法。

通过前6位表示出生地区,中间8位表示出生日期,不仅表明了身份证持有人的部分基本信息,还是一种生成身份证编码的一种限定条件:在前两种信息的限制下,后4位编码在罗马数字X的帮助下,完全可以表示同一地区一天的所有新生儿的编号,并表明该新生儿的性别。因此我国省份证编码具有广泛适用性的特点。

(2) 教师提出的其他问题。

希望老师不会发现我自己引用自己发的贴子还把题目变复杂了。

6 程序代码

#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define gets gets_s
int main()
{
	char input[19] = { 0 };
	int time[3],judge=0;
	printf("请以a b c的形式输入当前的年月日(例:2000年1月1日:输入\"2000 1 1\")\n当前日期:   ");
	scanf("%d%d%d", &time[0], &time[1], &time[2]);
	printf("身份证号码: ");
	rewind(stdin);
	gets(input,19);
	int year,month,day;
	year = (input[6] - '0') * 1000 + (input[7] - '0') * 100 + (input[8] - '0') * 10 + (input[9] - '0');
	month = (input[10] - '0') * 10 + (input[11] - '0');
	day = (input[12] - '0') * 10 + (input[13] - '0');
	if (time[0] - year > 18)
		judge = 1;
	if (time[0] - year == 18)
	{
		if (time[1] > month)
			judge = 1;
		if (time[1] == month)
			if (time[2] >= day)
				judge = 1;
	}
	if (judge)
		printf("输出:此人已成年\n");
	else
		printf("输出:此人未成年\n");
	return 0;
}

  • 23
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值