一.进制转换
1.例题
描述: BoBo写了一个十六进制整数ABCDEF,他问KiKi对应的十进制整数是多少。
==输入描述:==无
==输出描述:==十六进制整数ABCDEF对应的十进制整数,所占域宽为15。
备注 printf可以使用使用格式控制串“%md”输出域宽为m的十进制整数。
#include<stdlib.h>
int main(){
int num=0xABCDEF;
printf("%15d\n",num);
return 0;
}
2.知识点回忆:
<1>八进制
八进制:以0开头,数码取值为0-7,无符号数
例:011 0123 0777
典型错误:11(无前缀) 0123A(A不是八进制数码) -0123(出现了-)
<2>十进制
十进制:没有前缀,数码为0-9
例:11 23 234 -11
典型错误:011(十进制无前缀)
<3>十六进制
十六进制:前缀为0x,数值码为0-9,A-F
例: 0xFFF 0x10A 0xC0
典型错误:5A(无前缀) 66H(H不是十六进制数码)
<4>域宽与精度
域宽: 输出内容占的总宽度(浮点数包含小数点)
域宽>总宽度:前面会补充空格或者0
域宽<总宽度:正常输出
==精度:==对于整数和字符串来说不存在精度问题,对于浮点数来说是指小数位宽度。
#include<stdio.h>
int main(){
float x = 12.345; //x1=%6.2f 小数点也被计算在精度之内,%后的“6”为域宽,“.2”为精度
printf("x1=%6.2f\n", x); //按单精度浮点数输出, 宽度为6,精度为2,多出的位数前面默认为空格 x1= 12.35
printf("x2=%07.2f\n", x); //按单精度浮点数输 出,宽度为7,精度为2,多出的位数前面默认为0 x2=0012.35
printf("x3=%2f\n", x); //按单精度浮点数输出, 宽度为2,小于x的长度,则还按单精度浮点数输 出,float默认的为六位小数 x3=12.345000
printf("x4=%e\n",x); //按科学计数法表示 x4=1.234500e+001 (+表示正号,意思是 1.234500*10^1)
return 0;
}
此为运行结果截图
二.四舍五入的实现
1.例题
==描述:==将浮点数转换为整数类型,要求四舍五入。
==输入描述:==随机输入的浮点数
==输出描述:==四舍五入之后的整数
示例1: 输入:14.99
输出:15
#include<stdio.h>
#define round(x) x>0 ? (int)(x+0.5) : (int)(x-0.5)
int main(){
double a;
scanf("%lf",&a);
int b;
b=round(a);
printf("%d",b);
return 0;
}
若想要实现保留三位小数并四舍五入
# include <stdio.h>
int main() {
double a;
scanf("%lf", &a);
a = (int)(a*1000+0.5)/1000.0; //此处必须为1000.0,不然可能会出现隐式的转换
printf("%0.3f", a);
return 0;
}
2.知识点回忆:
<1>思路
用一个刚好可以四舍五入的数字2.5为例
定义一个浮点数a来解释四舍五入实现的思路。int本质上是是向零取整的,这是实现的关键。即正数为向下取整,负数为向上取整。(向上取整:大于自身的最小整数 向下取整:小于自身的最大整数)
首先判断a是正数还是负数。
如果a是正数则让a+0.5,如果a达到了四舍五入的条件(小数部分>=0.5,用2.5来举例,刚好达到四舍五入的条件)a+0.5=3,满足条件;若a=2.6,a+0.5=3.1,此时int(a+0.5)让其向下取整=3,满足条件;若a=2.4,a+0.5=2.9,此时int(a+0.5)让其向下取整=2,满足条件。
如果a是负数则让a-0.5,如果a达到了四舍五入的条件(小数部分>=0.5,用-2.5来举例,刚好达到四舍五入的条件)a-0.5=-3,满足条件;若a=-2.6,a-0.5=-3.1,此时int(a+0.5)让其向下取整=-3,满足条件;若a=-2.4,a-0.5=-2.9,此时int(a+0.5)让其向下取整=-2,满足条件。
<2>常用的取整方式
Floor() 会取不大于自变量的最大整数,即向下取整
Ceil() 会取不小于自变量的最小整数, 即向上取整
Round() 函数,才是咱们须要的四舍五入的函数,它会返回离自变量最近的整数
#include<stdlib.h>
#include<math.h>
int main(){
int a = floor(3.9); //向下取整
printf("%d\n", a);
int b = ceil(3.9); //向上取整
printf("%d\n", b);
int c = round(3.6); //取离自变量最近的整数
printf("%d\n", c);
int d = round(3.4); //取离自变量最近的整数
printf("%d", d);
return 0;
}
运算结果:
三.出生日期输入输出
输入一个人的出生日期(包括年月日),将该生日中的年、月、日分别输出。
数据范围:年份满足 1990 \le y \le 2015 \1990≤y≤2015 ,月份满足 1 \le m \le 12 \1≤m≤12 ,日满足 1 \le d \le 30 \1≤d≤30
==输入描述:==输入只有一行,出生日期,包括年月日,年月日之间的数字没有分隔符。
==输出描述:==三行,第一行为出生年份,第二行为出生月份,第三行为出生日期。输出时如果月份或天数为1位数,需要在1位数前面补0。
示例1
输入:20130225
输出:year=2013
month=02
date=25
#include<stdio.h>
int main(){
int birth,year,month,date;
scanf("%d",&birth); //输入年月日
int birth1=birth/10000; //得出前四位,就是年
printf("year=%d\n",birth1);
int month1=birth%10000/100; //得出月份
int month2=month1/10; //确定月份是不是双位数
if(month2>=1)
printf("month=%d\n",month1);
else printf("month=0%d\n",month1);
int date1=birth%100; //得出日
int date2=date1/10; //确定日是不是双位数
if(date2>=1)
printf("date=%d\n",date1);
else printf("date=0%d",date1);
return 0;
}
下面为牛客大佬写的代码,真的好简单呀家人们😢😢😢😢😢
#include <stdio.h>
int main()
{
int value;
scanf("%d", &value);
printf("year=%d\n", value / 10000);
value %= 10000;
printf("month=%02d\n", value / 100);
printf("date=%02d\n", value % 100);
return 0;
}
四.大小写转换
1.例题
描述:实现字母的大小写转换。多组输入输出。
输入:多组输入,每一行输入大写字母。
输出:针对每组输入输出对应的小写字母。
示例1 输入:A
B
输出:a
b
#include<stdio.h>
int main(){
int ch=0;
while ((ch=getchar())!= EOF){ //此时输入了一个数字和回车,都进入了缓存区
printf("%c\n",ch+32); //数字被读取出缓存区
getchar(); //自动读取缓存区中的\n
}
return 0;
}
2.知识点回忆getchar()
<1>运行机制
getchar():读入函数的一种,从输入缓冲区中读取一个字符
getchar()函数实际上是int getchar(void),返回的是ASCLL值。所以getchar的返回值要用int整型变量来存储。
#include<stdio.h>
int main(){
int ch = 0;
ch=getchar();
while((ch=getchar())!=EOF)
{
putchar(ch);
}
}
原理:在调用到getchar()时,程序就等待用户输入字符并按下回车结束。(字符与回车都会被放入缓存区中) 在用户敲入回车后,getchar()便开始依次读入字符,每次只能读取一个,并将读取的字符显示在屏幕。如果再回车之前用户输入了不止一个字符,这些字符会都全部进入缓存区并保存,等待下一个gerchar()继续读取。也就是说在缓存区没有清空之前gerchar()不会等待用户输入字符,会直接在缓存区中接着读取字符。在这个循环中gerchar()便会自动地读取字符直到遇到文件结尾(EOF)
EOF
(-1) - end of file 文件结束标志 - 键盘上用 ctrl + z 实现
<2>scanf和getchar()的分别
- 对于
scanf
函数,'\n'
会触发scanf
读取输入缓冲区的内容,但遇到'\n'
或空格' '
会停止读取。
#include<stdio.h>
int main(){
char password[20]={0};
printf("请输入密码:");
scanf("%s", &password); //输入了12345 678
return 0;
}
getchar
会直接读取 '\n'
和空格 ' '
<3>getchar()的经典例子:密码输入
#include<stdio.h>
int main(){
char password[20]={0};
printf("请输入密码:");
scanf("%s", &password);
printf("请确认密码:(Y/N)");
int ch = 0;
ch=getchar();
if(ch=="Y")
printf("success");
else
printf("defeat");
}
我们在输入密码之后,并没有让我们来确定密码是否正确,而是直接直接认定密码错误。为什么会这样呢?
在我们输入密码123后,字符’1’ ‘2’ ‘3’ ‘\n’进入了缓冲区。之后scanf便开始读取缓存区的字符’1’ ‘2’ ‘3’,到’\n’时读取结束。在运行到getchar时,getchar发现缓存区中还有还有’\n’,便直接读取了该字符将其赋给了’ch’。很明显ch!= =Y,便运行了printf(“defeat”);
那怎么样才能让getchar接收到我们输入的Y/N呢?既然getchar可以将缓冲区中的’\n’接收,那么我们便先getchar,在接收’\n’后,再次getchar,并将第二次的getchar赋值给ch。
getchar() // 原代码int ch = 0;
int ch=getchar() //原代码ch=getchar();
但是,当我们在编程之中或多或少会有些字符进入缓冲区,总不能再输入很多的getchar(),这明显不符合我们编程人的风格😈😈😈
#include<stdio.h>
int main(){
char password[20]={0};
printf("请输入密码:");
scanf("%s", &password);
printf("请确认密码:(Y/N)");
//清空缓冲区
int temp = 0;
while ((temp = getchar()) != '\n') //通过这个循环将缓存区中的字符都赋给temp来实现清空缓存区
{
}
//确认密码
int ch = 0;
ch=getchar();
if(ch=="Y")
printf("success");
else
printf("defeat");
}
家人们,你们get到了么😃😃😃
<4>为什么要用缓冲区
为啥用缓冲区呢?因为计算机CPU的处理速度是很快的,我们用键盘输入速度比不上CPU的处理速度,CPU就得等键盘输入完,很浪费资源,所以,当键盘输入完了,让CPU一次性处理,可以大大提高效率。