由一个蓝桥杯基础题报时助手而引出的常见误区

导读:本篇文章讲解 由一个蓝桥杯基础题报时助手而引出的常见误区,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

文章目录

  • 基础练习——报时助手
  • 常见误区: 在函数中返回一个局部变量的地址
  • 小结

一、报时助手

问题描述

       给定当前的时间,请用英文的读法将它读出来。
  时间用时h和分m表示,在英文的读法中,读一个时间的方法是:
  如果m为0,则将时读出来,然后加上“o’clock”,如3:00读作“three o’clock”。
  如果m不为0,则将时读出来,然后将分读出来,如5:30读作“five thirty”。
  时和分的读法使用的是英文数字的读法,其中0~20读作:
  0:zero, 1: one, 2:two, 3:three, 4:four, 5:five, 6:six, 7:seven, 8:eight, 9:nine, 10:ten, 11:eleven, 12:twelve, 13:thirteen, 14:fourteen, 15:fifteen, 16:sixteen, 17:seventeen, 18:eighteen, 19:nineteen, 20:twenty。
  30读作thirty,40读作forty,50读作fifty。
  对于大于20小于60的数字,首先读整十的数,然后再加上个位数。如31首先读30再加1的读法,读作“thirty one”。
  按上面的规则21:54读作“twenty one fifty four”,9:07读作“nine seven”,0:15读作“zero fifteen”。 

输入格式

  输入包含两个非负整数h和m,表示时间的时和分。非零的数字前没有前导0。h小于24,m小于60。

输出格式

  输出时间时刻的英文。

样例输入

      0 15

样例输出

     zero fifteen

解题思路:

    乍看本题文字很多很复杂,其实认真读两遍就会发现这题目很简单,就是实现一个简单的英文报时功能。复杂点在于24小时制的时间有很多种情况,要分情况地去逐个解决即可。24小时制的时间主要有以下几种形式:

1.分钟位为0,小时位不为0,即整点。如:21:00   输出:twenty one o’clock

2.小时位为0,分钟为不为零,如:00:15   输出:zero fifteen

3.小时位不为0,分钟位为整十数字,如:20:30  输出:twenty thirty 

4.小时为不为0,分钟位为几十几形式,如:21:37  输出: twenty one  thirty seven 

所以函数的大致功能可分为两个,处理小时位上的数字,处理分钟位数字,然后分别返回一个字符串给主函数,在主函数中输出。函数中主要使用switch多重分支语句来完成数字与英文字符串之间的匹配,同时用到C语言中的string库函数,完成字符串的复制与拼接。

完整代码如下: 

​
#include<stdio.h>
#include<string.h>
//设置三个全局字符串数组变量 
char cha[20];
char s3[20];
char minute[20];
//处理" 小时 "位
char* function1(int h){
	//char cha[20];
	switch(h){
		case 0:strcpy(cha,"zero");break;
		case 1:strcpy(cha,"one");break;
		case 2:strcpy(cha,"two");break;
		case 3:strcpy(cha,"three");break;
		case 4:strcpy(cha,"four");break;
		case 5:strcpy(cha,"five");break;
		case 6:strcpy(cha,"six");break;
		case 7:strcpy(cha,"seven");break;
		case 8:strcpy(cha,"eight");break;
		case 9:strcpy(cha,"nine");break;
		case 10:strcpy(cha,"ten");break;
		case 11:strcpy(cha,"eleven");break;
		case 12:strcpy(cha,"twelve");break;
		case 13:strcpy(cha,"thirteen");break;
		case 14:strcpy(cha,"fourteen");break;
		case 15:strcpy(cha,"fifteen");break;
		case 16:strcpy(cha,"sixteen");break;
		case 17:strcpy(cha,"seventeen");break;
		case 18:strcpy(cha,"eighteen");break;
		case 19:strcpy(cha,"nineteen");break;
		case 20:strcpy(cha,"twenty");break;
		case 21:strcpy(cha,"twenty one");break;
		case 22:strcpy(cha,"twenty two");break;
		case 23:strcpy(cha,"twenty three");break;
		case 24:strcpy(cha,"twenty four");break;
		case 30:strcpy(cha,"thirty");break;
		case 40:strcpy(cha,"forty");break;
		case 50:strcpy(cha,"fifty");break;
	}
	return cha;
}
//处理分钟位的十位 
char *function3(int x){
	//char s3[20];
	switch(x){
		case 1:strcpy(s3,"ten ");break;
		case 2:strcpy(s3,"twenty ");break;
		case 3:strcpy(s3,"thirty ");break;
	    case 4:strcpy(s3,"forty ");break;
	    case 5:strcpy(s3,"fifty ");break;
	}
	return s3;
}
//处理"分钟"位  
char *function2(int m){
	//char minute[20];
	if(m%10!=0){
		if(m<10){
			strcpy(minute,function1(m));
		}
		else{
			//因为只有1~20间的数字才有特定英文与之匹配,其它的需要拆解 
			if(m>20&&m<60){
				strcpy(minute,function3(m/10));//传入的参数是分钟位数字的十位 
				strcat(minute,function1(m%10));//传入的参数是分钟位数字的个位 
			}
			//不需要拆解的数字 
			else{
				strcpy(minute,function1(m));
			}
		}
		
	} 
	else{
		strcpy(minute,function1(m));// 当m的个位为零时,即是一个整十数字 
	}
	return minute;
}

int main(){
	int h,m;
	char hour[20],minute[20];
	scanf("%d%d",&h,&m);
	if(m!=0){
		strcpy(hour,function1(h));
		strcpy(minute,function2(m));
		printf("%s %s",hour,minute);
	}
	else{
		strcpy(hour,function1(h));
		printf("%s o'clock",hour);
	}
	return 0;
}

​

运行结果:

由一个蓝桥杯基础题报时助手而引出的常见误区

 由一个蓝桥杯基础题报时助手而引出的常见误区

 

二、常见误区

1.不能在函数中返回局部变量的地址

错误示例:

由一个蓝桥杯基础题报时助手而引出的常见误区

编译器给出警告:

由一个蓝桥杯基础题报时助手而引出的常见误区

2.错误原因分析

     使用字符数组的时候,会在栈区新建一个备份,会随着函数被调用而新建,会随着函数结束而被自动销毁。即使返回的是一个地址,但是在这个函数结束的时候,这个地址指向的那块内存空间放置的内容已经被释放了,所以通过那个返回的地址已经找不到那块地址对应的内容了,所以在函数中返回一个地局部变量的地址是错误的。

3.解决方案

(1)使用全局变量

   因为全局变量具有静态存储区,只有当整个程序执行结束时,内存中所存放的数据才会被释放。

(2)使用字符指针

   当使用字符指针时,该字符串是存储在静态存储区的(堆区),所以返回的地址指向的内容(在堆区)不会被释放,因此能够被找到。但是这种写法有一个缺点,即定义好了字符串指针之后,就不能改变其指向的字符串了,改了之后可能会出现意想不到的错误)。

(3)使用static关键字

   使用static关键字将其声明为静态变量,与方法1原理相同。


三、小结

1.static 静态变量

   static当用于函数定义时或者用于代码块之外的变量声明时,用于修改标识符的链接属性,从外部链接变成内部链接,但是存储类型和作用域不受影响,用这种方式声明的函数或变量只能在他们的源文件中访问。

   当它用于代码块内部的变量声明时,用于修改变量的存储类型,从自动变量修改为静态变量,但是链接属性和作用域不受影响。

2.函数可以返回局部变量,但不能返回局部变量的地址(指针)

  局部变量的作用域在函数的内部,函数返回后,局部变量内存已经释放掉了。因此,如果函数返回的是局部变量的值,不涉及地址,程序不会出错。故函数是可以返回局部变量的。但是如果函数返回的是局部变量的地址(指针)的话,程序运行就会报错。因为只是把指针(地址)复制后返回了,而指针指向的内存(存储的内容)已经被释放了,这样指针无访问该内存的权限,调用后就会报错。准确地说,函数不能通过返回指向栈内存的指针!注意这里指的是栈,返回指向堆内存的指针是可以的,因为堆内存里面的内容是在整个程序结束才释放。
 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由半码博客整理,本文链接:https://www.bmabk.com/index.php/post/93512.html

(0)
小半的头像小半

相关推荐

半码博客——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!