注:此blog为个人学习C语言总结之用,不定时补充更新,欢迎收藏与留言~
情况1:
错解:
scanf("%d%d",a,b);
运用输入函数scanf时,a,b前未加取地址符&。
正解:
scanf("%d%d",&a,&b);
情况2:
二维或三维数组开的太大导致空间不够,程序无法运行!!!
比如:data[500][500]
这个数量级我的vscode就带不动了,目测三维数组只能开100左右。
但是在各大刷题网站比如洛谷,PTA,leetcode上提交程序时可以开大一点,虽然你自己电脑带不动,但是各大平台的测评系统是可以的。(限制内存另说哈)
主函数里有这样一段:
int sum;
int a,b;
char c;
scanf("%d%d",&a,&b);
scanf("%c",&c);
printf("%c",c);
sum=a+b;
printf("%d",sum);
若这样输入,那么你会发现,在输完a,b的值后习惯性按下回车开始输入c的值,却发现屏幕上已经显示了sum,说明此时程序已经越过输入c的那一行了。
3 4//输入
//输出
7
细心的朋友会发现,此时c的值实际上是'\n'
正解:
int sum;
int a,b;
char c;
scanf("%d%d\n",&a,&b);//在输入a,b之后加一个回车
scanf("%c",&c);
printf("%c",c);
sum=a+b;
printf("%d",sum);
错解:
int map[20][20];
for(k=0;k<edge_num;k++)
{
//scanf("%d%d",&i,&j);
scanf("%d%d%d",&i,&j,&map[i][j]);
}
正解:
int map[20][20];
for(k=0;k<edge_num;k++)
{
scanf("%d%d",&i,&j);
scanf("%d",&map[i][j]);
}
也许三个数同一行同时输入时,输入的数字还留在缓冲区,所以计算机没办法确定最后一个数组的下标。
错解:
#define INF 1000000;
正解:(不能有分号!!!)
#define INF 1000000
详见:【c语言】malloc函数详解
int* p;
p = (int *) malloc (sizeof(int));
int **a;
a = (int **) malloc(sizeof(int *) * r);//注意申请的指针格式
普通变量只要定义了之后就自动分配了储存空间
int a;
但是指针变量定义之后一定要记得分配内存空间!!!
Graph *g
g= (Graph *)malloc(sizeof(struct Graph));
比如这样一个结构体
typedef struct{
int vex1; //边的起始顶点
int vex2; //边的终止顶点
int weight; //边的权值
}Edge;
Edge arr[SIZE];
想要交换arr[low]&arr[high]
时:
不需要这么麻烦:
void swap(Edge arr[],int low,int high)
{
int t1;
t1 = arr[low].vex1;
arr[low].vex1 = arr[high].vex1;
arr[high].vex1 = t1;
int t2;
t2 = arr[low].vex2;
arr[low].vex2 = arr[high].vex2;
arr[high].vex2 = t2;
int weight;
weight = arr[low].weight;
arr[low].weight = arr[high].weight;
arr[high].weight = weight;
}
只需要:
void swap(Edge arr[],int low,int high)
{
Edge temp;
temp = arr[low];
arr[low] = arr[high];
arr[high] = temp;
}
比如这样写时:
int Harry(int A[][SIZE],int n)
{
int i,j;
int max[n];
int MIN;
int tag;
}
最好在定义数组之前写上:
#define MAXSIZE 1000000
这样就可以不需要用到形参中的n作为数组长度了(这并不能从根本上解决空间浪费的问题,但至少这一步函数可以正常调试了[vscode运行这一步不会出问题],如果有好的方法,还望告知,谢谢!)
int Harry(int A[][SIZE],int n)
{
int i,j;
int max[MAXSIZE];
int MIN;
int tag;
}
这个问题为个人的小众问题
STACK_1190_反转每对括号间的子串
char* reverse(char* str,int left,int len)
{
int right ;
// ........对传入参数字符串str做了改动
// 由于整个函数的参数都是传指针,所以此函数应该改为void类型即可满足要求,如果要用另一个变量再储存返回值呢?
str[left] = '.';
str[right] = '.';
return str;//返回的是一个地址
char* res = malloc(sizeof(char)*2001);// 那么我们必须再申请一块空间!
strcpy(res,str);
return res;//返回一定要为另一个地址,否则函数类型必须设为空函数!
}
如果上述函数返回一个相同的地址,那么会有大问题!
char* temp = reverse(s,i,len);
//此时temp的地址是和s相同的
strcpy(s,temp);//不能把两个相同的地址再次赋值(temp和s地址完全相同)
此操作非法!!!
不能对两个相同的地址做strcpy操作!
AddressSanitizer: strcpy-param-overlap: !
10.堆溢出
堆内存溢出heap-buffer-overflow on address
11.函数参数写法
int len;
int res = evalRPN( convert(infix,13,&len),len);
这种写法是有问题的,因为编译这一行的时候len的大小是未知的,不会先通过第一个参数里函数的调用确定len的值,而是同时对两个参数进行编译,所以如果这样写,在调用evalRPN函数时len为乱码值。
我们应该改成下面这样的写法:
int len;
char** postfix = convert(infix,13,&len);
int res = evalRPN(postfix,len);