程序出过的错合集
1.
错误类型:output limit exceed:
-
-
#include <iostream> #include <cmath> using namespace std; int main() { long long a;//此处使用的int,在输入为159487时,越界为负数,从而无限循环输出下去。 scanf("%lld",&a); while(a!=1){ if(a%2){ long long odd_value = a*3+1; printf("%lld*3+1=%lld\n",a,odd_value); a=odd_value; } else{ long long even_value=a/2; printf("%lld/2=%lld\n",a,even_value); a=even_value; } } printf("End\n"); return 0; }
总结:
Output Limit Exceeded 多数发生在递归遍历的过程中,多输出了一些内容(比如说空格)。Output Limit Exceeded还指如果输入某一组数据,你的程序返回的结果是一直输出某个结果,死循环输出的那种。
Time Limit Exceeded,如果你相信你的算法是最优的,那就检查一下什么地方在什么数据下出现了死循环。否则还是考虑换个思路解题的好。TLE除了死循环就是算法问题。
输入的数据是由系统提供,一般不需要写上i>=或者i<=这样的判断条件,否则也会出现超时的情况。
2:
在TDM-GCC 4.7.1 64-bit中:
int a; int b[a];
居然合法!而且可直接通过b[i]访问。
3:
写一个稍微复杂一点的程序之前,一定要认真阅读需求,做好顶层设计,比如画好流程图、做好数据结构设计、功能模块划分以及定义等等。
只有做好前期分析工作,然后把分析的结果具体化为代码。这样可以少出很多错,而且即使出了问题,由于思路更清晰,也更容易分析哪个模块出了问题。
如:
#include <iostream> #include <cmath> using namespace std; void to0(int a[],int n) { for(int i=0;i<n;i++) { a[i]=0; } } int matrix[99][99]; int cum[99],line[99]; int main() { int num[2]={0,0}; int n1; scanf("%d",&n1); while(n1) { for(int i=0;i<n1;i++) { for(int j=0;j<n1;j++) { scanf("%d",&matrix[i][j]); } } for(int i=0;i<n1;i++) { int temp=0; for(int j=0;j<n1;j++) { if(matrix[i][j]) temp++; } if(temp%2) { cum[i]=1; num[0]++; } } for(int i=0;i<n1;i++) { int temp=0; for(int j=0;j<n1;j++) { if(matrix[j][i]) temp++; } if(temp%2) { line[i]=1; num[1]++; } } if(num[0]==0 && num[1]==0) { printf("OK\n"); } else if(num[0]!=1 || num[1]!=1) { printf("Corrupt\n"); } else { int i,j=-1; for(int k=0;k<100;k++) { if(cum[k]) { i=k; } if(line[k]) { j=k; } } printf("Change bit (%d,%d)\n",i+1,j+1); } to0(cum,100);//恢复环境 to0(line,100); num[0]=num[1]=0; scanf("%d",&n1); } return 0; }
tips:
做这道题时,最开始思路不清晰,是写一步想一步,导致前后需要连贯的地方出了很多很基本的错误。
比如忘记最后需要恢复环境,一部分代码拷贝时,没有做很细小却必要的改动,导致出错,浪费一些时间在不必要的调试上。
还有今天在做另一道题时,出现了:
double b=3.0; printf("%d",b);
由于那道题的代码中b的定义隔printf函数有点远,我一时间没意识到b是double,结果总是输出的0。浪费了几分钟在其他地方找问题,最后才意识到b是double。
4:
编写一个 MyMax函数,可以用来求任何数组中的最大值 使得程序按要求输出
/************************************
* dest:一维数组的起始地址
* size:单个元素大小
* nelem:元素个数
* p:比较任意两个元素的大小的函数指针。
*******************************************/
void * MyMax(void * dest,int size,int nelem,int (*p)( void *, void *) ) { void * max = dest; for(int i=1;i<nelem;i++) { //cout<<i<<endl; void * temp = (void *)((char *)dest+i*size); if(p(max,temp)<0) max =temp; } return max; }5:自己编写排序函数 mysort,使得其能够对任意类型的数组排序
-----》下面只列出了核心代码。
struct A { int nouse1; int nouse2; int n; };
A b[20];
void mysort(void *dest,int len,int size,int (*mm)(const void * ,const void * ))
{
char * source = (char *)dest;
char p[100] ;
for(int i=0;i<len-1;i++)
{
for(int j=len-1;j>i;j--)
{
void * front = (void *)(source+j*size);
void * back = (void *)(source+(j-1)*size);
if(mm(front,back)<0)
{
strncpy(p,(char *)back,size);
strncpy((char *)back,(char *)front,size);
strncpy((char *)front,p,size);
}
}
}
}
/*
b[0].n=11; b[1].n=22;
strncpy((char *)b,(char *)(b+sizeof(A)),sizeof(A));//通过这里的测试,可以知道:经过这个strncpy后,b[0]所有位全部变成了0.
//这是因为结构体成员n前面还有nouse1,nouse2两个成员,而且由于都是全局变量,所以所有位都为0.
//而strncpy碰到0后,之后所有的剩下的位都会赋值0.
//因此,mysort实现字节拷贝时,为了通用性,最好直接操作字节复制,不用strncpyfor(int i = 0;i < 2; ++i) cout << b[i].n << "," ;
*/因此正确的mysort应该这样写:
int mysort(void * a,int n,int w, int (* compare)(const void * e1,const void * e2)) { char * s = (char * ) a; for(int i = n-1;i >= 0; -- i) for(int j = 0; j < i; ++ j) { char * p1 = (char*)a + j * w; char * p2 = (char*)a + j * w + w; if( compare(p1,p2) > 0 ) { for(int k = 0; k < w; ++k) { char tmp = p1[k]; p1[k] = p2[k]; p2[k] = tmp; } } } }
6:
描述
编写GetDoubleFromString函数,该函数可以不断从字符串中取出正浮点数或整数,无数可取,则返回值小于0
#include <iostream> #include <iomanip> using namespace std; double GetDoubleFromString(char * str) { // 在此处补充你的代码 } int main() { char line[300]; while(cin.getline(line,280)) { double n; n = GetDoubleFromString(line); while( n > 0) { cout << fixed << setprecision(6) << n << endl; n = GetDoubleFromString(NULL); } } return 0; }
double GetDoubleFromString(char * str) { static char * p; if(str) p=str; for(;*p&&!(*p>='0'&&*p<='9');p++); if(*p==0) return -1; else { double num=0; for(;(*p>='0'&&*p<='9');p++) { num=num*10+(*p-'0'); } if(*p=='.') { double temp=10; p++; for(;(*p>='0'&&*p<='9');p++) { num=num+(*p-'0')/temp; temp*=10; } } return num; } }
总结:
->这道题如果可以使用cstring\cmath中的函数,很容易解出来。
但题目限制不能使用,于是只能用num = num*10+*p-'o'这类办法求值。一时间不一定想得到。
-> 注意到指针p可以直接p++,这会让代码清晰简单很多
->这类题一定要先认真读题,分析清楚再动手写代码,否则极容易被自己的固见带入死胡同。
比如一开始我没注意到1278aa12也需要解析出1278、12分别输出,而以为这样的字符串不符合规定,该直接抛弃,于是忙活半天。调试出来了。结果与要求不符合。
7: error:left is ambiguous
char left[3][7]={"adfg","dd","dddf"},right[3][7]; int main() { cout<<left[1]; return 0; }
显示如下报错。
D:\lianxi\poj\xxx.cpp In function 'int main()':
70 8 D:\lianxi\poj\xxx.cpp [Error] reference to 'left' is ambiguous
43 6 D:\lianxi\poj\xxx.cpp [Error] candidates are: char left [3][7]
43 0 d:\dev-cpp\mingw64\lib\gcc\x86_64-w64-mingw32\4.7.1\include\c++\ios In file included from d:\dev-cpp\mingw64\bin\../lib/gcc/x86_64-w64-mingw32/4.7.1/include/c++/ios
40 d:\dev-cpp\mingw64\lib\gcc\x86_64-w64-mingw32\4.7.1\include\c++\ostream from d:\dev-cpp\mingw64\bin\../lib/gcc/x86_64-w64-mingw32/4.7.1/include/c++/ostream
40 d:\dev-cpp\mingw64\lib\gcc\x86_64-w64-mingw32\4.7.1\include\c++\iostream from d:\dev-cpp\mingw64\bin\../lib/gcc/x86_64-w64-mingw32/4.7.1/include/c++/iostream
1 D:\lianxi\poj\xxx.cpp from D:\lianxi\poj\xxx.cpp
918 3 d:\dev-cpp\mingw64\lib\gcc\x86_64-w64-mingw32\4.7.1\include\c++\bits\ios_base.h [Error] std::ios_base& std::left(std::ios_base&)今天写代码时,遇到这个问题。
原因分析:(通过stackover flow找到答案)
因为namespace std中包含有left、right的变量,于是在自己的代码里自己再定义会冲突。
解决办法:->改名
->不使用using namespace std;而是需要什么,加入什么。如using std::cout;
->把left、right定义在main函数体内,此时在函数体中,left、right是局部变量,覆盖std中的全局的left、right。
8:函数体外不能执行语句。(定义与声明语句可以)
int a,b,c; a=b=c=0;//此处报错,好像函数体外不能执行语句。 int main() { return 0; }
-