W3 school 菜鸟教程 我要自学网 信息学奥赛NOI 花哥的博客 不逼自己一把,怎知自己有多优秀——校长语录

C++初学者常犯的错(持续更新)

      对于一个初学者来说,常犯错是很正常的,就算是有了定功底的人也会犯一些低级错误,这很正常。现对我和学员常犯的错作一点整理,与大家共勉

1、一个变量未初始化就开始使用(如果定义在全局,变量会自动初始化,不在此列)。比如
    int a,sum;        cin>>a;    sum+=a;    cout<<sum;
2、相等判断“日常化”。比如比较两数大小
    if(a>b)cout<<">";         else if(a=b)cout<<"="; (应该是if(a==b))               else cout<<"<";
3、忘记写输入语句或输入语句放在了计算之后。比如int a,b,c;    if(a>b)c=0;    cin>>a>>b;
4、输入语句错误用法。比如cin>>a>>' '>>b>>endl;(这把输出的格式搞到输入);     cin>>a,b,c;         cin>>a(0<a<100);(把数据范围也加进了输入语句中),还有就是scanf输入格式与后面变量类型不匹配,忘记加&等
5、if语句嵌套错误。比如

if(a>b)cout<<'>';
if(a<b)cout<<'<';
else cout<<'=';
比较两数大小

 

错误原因:当遇到分支不只两种时,不想写else或漏写else。如上例上就会出现输入的数a>b,结果将会是输出了“>”和"="两个符号。这与switch语句中漏写break语句的结果相似。

6、数据类型不正确使用。比如

1013:温度表达转化

时间限制: 1000 ms         内存限制: 65536 KB
提交数: 22130     通过数: 12925 
【题目描述】
利用公式 C=5×(F−32)÷9C=5×(F−329(其中CC表示摄氏温度,FF表示华氏温度)进行计算转化,输入华氏温度FF,输出摄氏温度CC,要求精确到小数点后55位。

【输入】
输入一行,包含一个实数FF,表示华氏温度。(F≥−459.67)(F≥−459.67)
【输出】
输出一行,包含一个实数,表示对应的摄氏温度,要求精确到小数点后55位。

【输入样例】
41
【输出样例】
5.00000
1013:温度转换

 

#include<iostream>
#include<iomanip>
using namespace std;

int main(){
    int f;
    cin>>f;
    cout<<fixed<<setprecision(5)<<(f-32)/9*5;
    return 0;
}
View Code

错误原因:公式中都是整数运算,结果当然是整数,输出的虽然是有小数位,但那是运算结果取整后再加小数。

#include<iostream>
#include<iomanip>
using namespace std;

int main(){
    int f;
    cin>>f;
    cout<<fixed<<setprecision(5)<<float((f-32)/9*5);
    return 0;
}
View Code

 

错误原因:虽然的类型转换,但这个转换跟没有一样效果。因为转换前全是整数,运算出来的也自然是整数,再加上类型转换为时己晚。

修改方法:最好第一次运算就先提升数据类型或损失精度前转换。比如运算式改为c=5*(1.0*f-32)/9或者c=5.0*(f-32)/9都是可以的。注意1.0*f实际上是把整个的数据类型隐形转换成了float。当然也可以直接把int f改为double f一样能过。

7、循环变量书写错。比如把for(int j=1;i<100;j++)写成for(int j=1;i<100;j++)或者for(int j=1;j<100;i++),还有把for(int i=100;i>0;i--)错误地写成for(int i=100;i>0;i++)等,这些都很容易陷入死循环。

8、在使用float类型,特别是double类型时不注意这类数的误差而造成错误。可参看https://www.cnblogs.com/wendcn/p/10475883.html。

在float或double类型的数据相等时一般用|a-b|<1e-12的类似方式,而不适合直接用a==b进行判断。

1058:求一元二次方程

时间限制: 1000 ms         内存限制: 65536 KB
提交数: 26564     通过数: 4307 
【题目描述】
利用公式x1=−b+b2−4ac√2a,x2=−b−b2−4ac√2ax1=−b+b2−4ac2a,x2=−b−b2−4ac2a,求一元二次方程ax2+bx+c=0ax2+bx+c=0的根,其中aa不等于00。结果要求精确到小数点后55位。

【输入】
输入一行,包含三个浮点数a,b,ca,b,c(它们之间以一个空格分开),分别表示方程ax2+bx+c=0ax2+bx+c=0的系数。

【输出】
输出一行,表示方程的解。

若两个实根相等,则输出形式为:“x1=x2=...x1=x2=...”;

若两个实根不等,在满足根小者在前的原则,则输出形式为:“x1=...;x2=...x1=...;x2=...“;

若无实根输出“No answer!”。

所有输出部分要求精确到小数点后5位,数字、符号之间没有空格。

【输入样例】
-15.97 19.69 12.02
【输出样例】
x1=-0.44781;x2=1.68075
问题1058:求一元二次方程的根
#include<iostream>
#include<cmath>
#include<iomanip>
using namespace std;

int main(){
    float a,b,c,d,x1,x2;
    cin>>a>>b>>c;
    d=b*b-4*a*c;
    if(d<0)cout<<"No answer!";
    else if(d>0){
        x1=(-b+sqrt(d))/2/a;
        x2=(-b-sqrt(d))/2/a;
        if(x1>x2)swap(x1,x2);
        cout<<"x1="<<fixed<<setprecision(5)<<x1;
        cout<< ";x2="<<fixed<<setprecision(5)<<x2;
    }    
    else cout<<"x1=x2="<<fixed<<setprecision(5)<<-b/2/a<<endl;
    
    return 0;
}
错误代码 

 错误原因:这里的t是float类型,不能用t=0来判断是否等于0,而要用fabs(t)<1e-16来判断相等(用1e-12好像也可以)。

#include<iostream>
#include<cmath>
#include<iomanip>
using namespace std;

int main(){
    double a,b,c,d,x1,x2;
    cin>>a>>b>>c;
    d=b*b-4*a*c;
    if(fabs(d)<1e-16)cout<<"x1=x2="<<fixed<<setprecision(5)<<-b/2/a<<endl;
    else if(d>0){
        x1=(-b+sqrt(d))/2/a;
        x2=(-b-sqrt(d))/2/a;
        if(x1>x2)swap(x1,x2);
        cout<<"x1="<<fixed<<setprecision(5)<<x1;
        cout<< ";x2="<<fixed<<setprecision(5)<<x2;
    }    
    else cout<<"No answer!";
    
    return 0;
}
上服务器能过的代码

  9、广搜时标记不及时的错。详情参看一道广搜的错https://www.cnblogs.com/wendcn/p/10441543.html

10、大数据取模运算中可能出现的错。详情参看https://www.cnblogs.com/wendcn/p/10481511.html

11、变量名的不正确使用而出现的错。在定义变量时,不可重得定义,也不可有歧义的定义。比如:int a;  char a[100];那在程序中cout<<a;那输出这单个的int变量a还是输出字符数组a?因为这里的a也可以看做是数组变量的首地址。再比如:在全局定义一个变量int max;这个程序在编译的时候也会报错。因为有一个函数max(int,int),这可以理解为一个变量名被同时定义了两次。这是不允许的。但如果不是全局而是在某个函数体内(也可以是main())那就可以了,我们可以理解为是函数内的私有变量,跟全局变量不冲突。

  

如果你能把你遇到的错误发给我,整理到一起,我们非常感谢你!

posted @ 2019-03-05 13:49  耍人  阅读(815)  评论(0编辑  收藏  举报