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−32)÷9(其中CC表示摄氏温度,FF表示华氏温度)进行计算转化,输入华氏温度FF,输出摄氏温度CC,要求精确到小数点后55位。 【输入】 输入一行,包含一个实数FF,表示华氏温度。(F≥−459.67)(F≥−459.67) 【输出】 输出一行,包含一个实数,表示对应的摄氏温度,要求精确到小数点后55位。 【输入样例】 41 【输出样例】 5.00000
#include<iostream> #include<iomanip> using namespace std; int main(){ int f; cin>>f; cout<<fixed<<setprecision(5)<<(f-32)/9*5; return 0; }
错误原因:公式中都是整数运算,结果当然是整数,输出的虽然是有小数位,但那是运算结果取整后再加小数。
#include<iostream> #include<iomanip> using namespace std; int main(){ int f; cin>>f; cout<<fixed<<setprecision(5)<<float((f-32)/9*5); return 0; }
错误原因:虽然的类型转换,但这个转换跟没有一样效果。因为转换前全是整数,运算出来的也自然是整数,再加上类型转换为时己晚。
修改方法:最好第一次运算就先提升数据类型或损失精度前转换。比如运算式改为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
#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())那就可以了,我们可以理解为是函数内的私有变量,跟全局变量不冲突。
如果你能把你遇到的错误发给我,整理到一起,我们非常感谢你!