CC++习题与知识
CC++习题与知识
[TOC]
【1】输入错误处理
cin >> int 型变量(C++)
三种情况:
- 输入非法:非数字、超上下限
- 输入合法,但不在用户要求范围内
- 输入合法且在用户要求范围内 √
1 | while (1) { |
实际上也可不要continue,改用else if
1 | while (1) { |
模板:
while (1) {
提示并输入x
if (输入错误) {
清除错误标记
清空缓冲区
}
else if (x >= 0 && x <= 100)
break;
}
scanf(“%d”, &int变量) (C方式)
scanf返回值:正确按指定格式输入变量的个数,也即能正确接收到值的变量个数。
1 | while (1) { |
==cin 与 scanf 在输入超上下限时有差异==
**cin :**状态 false,值上限/随机
**scanf:**无状态观察,返回正确的1,截断赋值
由此引申出错误输入处理的通用规则
-
上述处理规则适用于各种int
不含char/unsigned char,因为输入方式不同。(只是说,运算时可以当作一字节整数处理)
-
如何判断char/unsigned char 型的输入错误?
-
如何判断float/double 型的输入错误?
-
如何判断bool 型的输入错误?
计算机的思维
- 读入1.1时,读完"1"正确,".1"后续留在缓冲区
- 读入126abc,同理
所以一般来说,我们都依次处理每个输入,
若本次输入正确,后续则留在缓冲区
否则,清空全部缓冲区
其他问题
-
对于多个输入,有没有标准处理非法?
没有
-
无特殊约定下的错误处理准则?
一次读一个,cin若false则清空缓冲区,否则不清
-
在实际应用中,如何尽可能地避免输入错误?
多选择,少输入,从用户角度避免输入错误,而不是错误后纠正
【2】打印月历
闰年表达式
1 | leap = (y % 4 == 0 && y % 100 != 0 || y % 400 == 0)? 1 : 0; |
控制输出
1 | if(week == 6) |
【3】光标移动
键盘键
-
普通字符:
一键单码(ASCII码)
-
箭头键:
一键双码
224 + 72/80/75/77(上下左右)
H P K M
用户选项与参数用法
有时比如用户要输入的选项是0-6,那我们可以用这种选项来作为必要的参数输入给函数,控制函数的某种功能是否开启
习惯培养
-
多用符号常量(宏定义)和全局常量(const)
对于一些固定的参数,虽然说对于本题固定,但是尽量不要写死参数
不允许使用全局变量,但是鼓励多用全局常量
-
条件运算符
对于只有两个出口的函数,往往可以用?:来代替,简化代码,看起来也方便
-
多条件的int 整数选择,用switch-case
-
循环的选择,用1,用loop?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16while(loop){
sel = menu();
switch(sel){
case '1':
case '2':
move(hout, 0, sel-'1');
break;
case '3':
case '4':
move(hout, 1, sel-'3');
break;
case '0':
loop = 0; //巧妙
break;
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15while(loop){
switch(_getch()){
case 'L':
case 'l': //两个连用,遇到break才会出switch
if(++x > MAX_X)
x = rool ? 1 : MAX_X;
break;
case 'J':
case 'j':
...
...
default:
continue;
}
}1
2
3
4
5
6
7
8
9case 224:
if(!move_by_arrow)
continue; //奇妙控制是否能够箭头,在要动用的前面截路,加个判断+continue
switch(_getch()){
case 72://'H'
//上
......
}
break;
【4】递归分解正整数
预备知识
1 | int a = -2147483648, b = -a; |
正序
输入:12345
输出:1 2 3 4 5
1 | void convert(int n) |
逆序
输入:12345
输出:5 4 3 2 1
1 | void convert(int n) |