• 新手最常见的误解和错误


    编译问题(该问题只与VC相关,与Codeblocks无关)

     fatal error C1010: unexpected end of file while looking for precompiled header directive 
     

    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 }

     在函数里面开辟大数组

    下面的代码是错的:

    int main()
    {
        int a[1000000];
        ...
    }

    程序运行直接出错。原因局部变量分配在栈上,栈的空间往往有限制,比如Windows下的VS编译栈空间大小默认1MB,见https://msdn.microsoft.com/zh-cn/library/tdkhxaks.aspx。

    解决办法:

    (1)将a定义为全局变量,推荐同学们使用

    (2)使用malloc动态分配空间

    (3)见上面的链接,设置编译器选项,调整栈大小。不推荐,因为OJ题目上交上去不一定本地机器的编译器了

  • 相关阅读:
    使用Systrace分析UI性能
    android官方推荐的网络调优器AT&T ARO
    HttpResponseCache 网络缓存使用
    SectionIndexer中的getSectionForPosition()与getPositionForSection()
    MVVM_Android-CleanArchitecture
    Android UI:机智的远程动态更新策略
    Data Binding
    Android实战之你应该使用哪个网络库?
    View以自身中心旋转的代码解惑
    为什么要使用puppet 及初步接触
  • 原文地址:https://www.cnblogs.com/4bytes/p/4180389.html
Copyright © 2020-2023  润新知