码迷,mamicode.com
首页 > 其他好文 > 详细

新手最常见的误解和错误

时间:2014-12-23 23:53:20      阅读:622      评论:0      收藏:0      [点我收藏+]

标签:

=scanf  忘记 &  

输入与输出的次序

有题目的要求如下

http://125.221.232.253/JudgeOnline/problem.php?cid=1090&pid=1

样例输入

4
3 4 4
3 4 5
3 4 6
3 4 7
样例输出
Acute triangle
Right triangle
Obtuse triangle
NO

 

这个题目有多组数据(示例中是4组), 是不是要全部先读入所有的数据, 然后再产生所有的输出呢? 答案是你可以这样做,但是没有必要。完全可以读入一个,处理一个,也就是,在屏幕上的输入输出效果如下也是正确的:

4
3 4 4
Acute triangle
3 4 5
Right triangle
3 4 6
Obtuse triangle
3 4 7
NO

输入的约束条件

比如下面的题目:

 编写程序,给出一个其值不超过12345678的正整数,求出它是几位数。

有些同学的代码类似下面的

1 int n;
2 scanf("%d", &n)
3 if(n <= 12345678)

第3行的判断是没有必要,每个题目提交以后OJ都会用数据来测试你的程序,题意保证测试你程序的数据不超过12345678,并不需要你自己来检查。

题目中给定条件约束往往决定了能使用什么方法,比如下面的题目:

2010省赛题:数字整除
题目描述
定理:把一个至少两位的正整数的个位数字去掉,再从余下的数中减去个位数的5倍。当且仅当差是17的倍数时,原数也是17的倍数 。例如,34是17的倍数,因为3-20=-17是17的倍数;201不是17的倍数,因为20-5=15不是17的倍数。输入一个正整数n,你的任务是判断它是否是17的倍数。
输入
输入文件最多包含10组测试数据,每个数据占一行,仅包含一个正整数n(1<=n<=10100),表示待判断的正整数。n=0表示输入结束,你的程序不应当处理这一行。

 

注意到n的范围远远超过了int,long long所能表示的范围,所以你无法用一个整数类型存储n,解决的方法是用字符串来存储n,再模拟除法。

 

范围往往决定了你需要的存储空间,比如下面的题目

问题 G: 实验7_3:多行字符串反转输出

题目描述
输入多行字符串,把这些字符串逆序且反转输出。

输入
输入多个(小于30个)字符串,每行一个字符串,字符串长度不超过30

 

这意味你可以定义一个字符数组 char s[30][31]; 来存储所有的输入 

多组数据状态的初始化

先来看一组数据的例子,求1到n的总和 

 1 #include <stdio.h>
 2 
 3 int main()
 4 {
 5     int i, n;
 6     int sum = 0;
 7 
 8     scanf("%d", &n);
 9     for(i = 1; i <=n; i++)
10         sum += i;
11     printf("%d\n", sum);
12 
13     return 0;
14 }

sum初始化为0是大家熟悉的, 但是如果要求输入多个n,分别求1到n的总和呢?许多同学会犯错,见下面的第6行,sum 清0只进行了一次,后面sum的计算是在前一次的基础上进行的

 1 #include <stdio.h>
 2 
 3 int main()
 4 {
 5     int i, n;
 6     int sum = 0;
 7 
 8     while(scanf("%d", &n) != EOF) {
 9         for(i = 1; i <= n; i++)
10             sum += i;
11         printf("%d\n", sum);
12     }
13 
14     return 0;
15 }

对于多组数据,如果状态是针对每一组数据,则每一组数据都应该初始化其状态一次,见下面的第9行

 1 #include <stdio.h>
 2 
 3 int main()
 4 {
 5     int i, n;
 6     int sum;
 7 
 8     while(scanf("%d", &n) != EOF) {
 9         sum = 0;
10         for(i = 1; i <= n; i++)
11             sum += i;
12         printf("%d\n", sum);
13     }
14 
15     return 0;
16 }

 

读整数后再读入字符串

 一个常见的情况是先读入整数n,再读入n个字符串(我们假定是各自有独立的行)

如果字符串中没有空格,则可以使用下面的代码

 1 #include <stdio.h>
 2 
 3 int main()
 4 {
 5     int n;
 6     char s[80];
 7 
 8     scanf("%d", &n);
 9     while(n--) {
10         scanf("%s", s);
11         puts(s);
12     }
13 
14     return 0;
15 }

但是字符串有空格的话,你必须用类似gets的函数,比如下面的样例

样例输入
2
zhe shi hui yin ni dong ma?
yukkuri shite itte ne!!!

 

你必须使用类似下面的代码,注意第9行。 因为样例的整数 2后面有回车, 如果是scanf("%s", s);则会跳过回车接收后面真正的字符串;但是gets不会,它直接碰到回车的话会认为接收到了一个空串。为了避免该情况的发生,我们用getchar()吃掉回车键。然后再用gets接收就没有问题了。

 1 #include <stdio.h>
 2 
 3 int main()
 4 {
 5     int n;
 6     char s[80];
 7 
 8     scanf("%d", &n);
 9     getchar();
10     while(n--) {
11         gets(s);
12         puts(s);
13     }
14 
15     return 0;
16 }

 

下面第8行的做法也是可行的,scanf里面的\n会忽略调换行,但不推荐同学们这样写。

 1 #include <stdio.h>
 2 
 3 int main()
 4 {
 5     int n;
 6     char s[80];
 7 
 8     scanf("%d\n", &n);
 9     while(n--) {
10         gets(s);
11         puts(s);
12     }
13 
14     return 0;
15 }

 

新手最常见的误解和错误

标签:

原文地址:http://www.cnblogs.com/4bytes/p/4180389.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!