啦啦啦,进了计算机系。不用说学习C语言当然少不了。说到写程序少不了是什么?对就是Bug。
什么你还不知道什么是Bug?
Bug是计算机领域专业术语,bug原意是“臭虫”,现在用来指代计算机上存在的漏洞,原因是系统安全策略上存在的缺陷,有攻击者能够在未授权的情况下访问的危害。
名称由来:
为马克2号(Harvard Mark II)编制程序的葛丽丝·霍波(Grace Hopper)是一位美国海军准将及计算机科学家,同时也是世界最早的一批程序设计师之一,有一天,她在调试设备时出现故障,拆开继电器后,发现有只飞蛾被夹扁在触点中间,从而“卡”住了机器的运行。于是,霍波诙谐的把程序故障统称为BUG(飞虫),把排除程序故障叫DEBUG,而这奇怪的“称呼”,竟成为后来计算机领域的专业行话。
以上引自百度百科:bug (计算机领域漏洞)
经过这些天的学习,我整理了我与我的同学们在上机过程中遇到的Bug。有句话说得好:“那些受过的伤,终究会成为我们身上的勋章”。有错误是件好事,它可以让我们变成“大神"又进一步。好了,废话不多说,Follow me 开始Debug吧!

一.变量初始化不规范导致的错误
#include <stdio.h>
#include <stdlib.h>
int main()//这是个运动会奖牌数目统计
{
int n,z;
//count1表示金牌数目,以此类推count2,count3
int count1,count2,count3;//这里属于局部变量初始化不规范
printf("请输入运动会天数:");
scanf("%d",&n);
for(int i=0;i<n;i++)
{
for (int j=1;j<=3;j++)
{
scanf("%d",&z);
if (j==1)
count1=count1+z;
if (j==2)
count2=count2+z;
if (j==3)
count3=count3+z;
}
}
printf("金牌数目为:%d",count1);
printf("银牌数目为:%d",count2);
printf("铜牌数目为:%d",count3);
return 0;
}
这个程序的运行图:

很显然银牌数目是错的,3+5+5怎么可能等于29呢?经过我的debug发现一开始变量count2的值就不为零。但是为什么呢?于是我去查了一下资料,找到了问题所在:
原来啊,这是由于变量存放的位置是不同导致的。全局变量、静态变量处于数据区,默认初始值为0(指定的话就为指定值),而局部变量处于堆栈区,它的值为内存中的值,是随机的。
这里我根据这个理解我给出了两种改法
法1:把int count1,count2,count3;变成全局变量
#include <stdio.h>
#include <stdlib.h>
int main()//这是一段关于密码输入判断的代码
{
char String[5]//这里忘写”;“了
printf("请输入4位数的密码:\n");
gets(String);//接收用户的输入密码
int Stringlength=strlen(String);
if(Stringlength==4)//判断输入的数是否超位
{
if(strcmp(String,"1234")==0)//设定的密码是:1234
{
printf("密码正确");
}
else
{
printf("密码错误");
}
}
else
{
printf("格式错误!你输入了%d位的密码",Stringlength);
}
return 0;
}
法2:对局部变量进行初始化赋值
#include <stdio.h>
#include <stdlib.h>
int main()//这是个运动会奖牌数目统计
{
int n,z;
//count1表示金牌数目,以此类推count2,count3表示银牌,铜牌
int count1=0,count2=0,count3=0;//这里对局部变量进行初始化赋值
printf("请输入运动会天数:");
scanf("%d",&n);
for(int i=0;i<n;i++)
{
for (int j=1;j<=3;j++)
{
scanf("%d",&z);
if (j==1)
count1=count1+z;
if (j==2)
count2=count2+z;
if (j==3)
count3=count3+z;
}
}
printf("金牌数目为:%d",count1);
printf("银牌数目为:%d",count2);
printf("铜牌数目为:%d",count3);
return 0;
}
它们都是正确的,运行图:

感悟: 必要的初始化是重要的,不要指望编译器的默认规则。养成良好的编程习惯。
二.忘写分号
#include <stdio.h>
#include <stdlib.h>
int main()//这是一段关于密码输入判断的代码
{
char String[5]//这里忘写”;“了
printf("请输入4位数的密码:\n");
gets(String);//接收用户的输入密码
int Stringlength=strlen(String);
if(Stringlength==4)//判断输入的数是否超位
{
if(strcmp(String,"1234")==0)//设定的密码是:1234
{
printf("密码正确");
}
else
{
printf("密码错误");
}
}
else
{
printf("格式错误!你输入了%d位的密码",Stringlength);
}
return 0;
}
感悟:这种错误是比较容易犯的,特别是零基础的小白和那些先学Python后学C语言的人(因为Python语句结束不用在它后面加" ; ",会有点不习惯)。
改过后的代码以及它的运行图,如图:

左边为正确的代码,右边为它的运行图
三.半角与全角问题(中英文符号问题)
#include <stdio.h>
#include <stdlib.h>
int main()
{
char String[5];
printf("请输入4位数的密码:\n");
gets(String);//接收用户的输入密码
int Stringlength=strlen(String);
if(Stringlength==4)//判断输入的数是否超位
{
if(strcmp(String,"1234")==0)//密码是:1234
{
printf("密码正确");//这里写的”;“是中文的符号,要改为英文的”;“(这里有一点看不出来)
}
else
{
printf("密码错误");
}
}
else
{
printf("格式错误!你输入了%d位的密码",Stringlength);
}
return 0;
}
感悟:这个问题还好,用个好一点的编程软件就好了(因为你输入的中文标点符号和英文的标点符号在编程软件中的颜色是不一样的)。只不过如果你是用VC6来写代码,就没有这功能,很难看出二者的区别。(我用的是CodeBlocks,还不错!)
它俩区别在编程软件上的效果图:

上面黑色的分号是中文符号,下面红色的是英文符号
四.数学表达式上的惯性思维
#include <stdio.h>
#include <stdlib.h>
int main()
{
int x=5;
int a=2x-1;//这里少写了*,应改为“int a=2*x-1;”
printf("%d",a);//将输出9
return 0;
}
感悟:哈哈哈,这个问题我就经常犯[捂脸]。经常漏掉”*“运算符。 逻辑上没错,但表达上错了 。
运行效果图:

五.char类型赋值时单引号写成了双引号
#include <stdio.h>
#include <stdlib.h>
int main()
{
char a="a"; //单引号写成了双引号.要改成“ char a='a'; ”
printf("%c",a);//将输出a
return 0;
}
感悟: 乱迁移printf(" ");这种双引号表达,char类型要用单引号。
当然关于char也可以这么写:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char a=97; //单引号写成了双引号.要改成“ char a='a
printf("%c",a);//将输出a
return 0;
}
以上两种表达运行效果是一样的,都是输出a
如图:

六.乱迁移printf语句的指定数据宽度和小数位数用法在scanf语句上
#include <stdio.h>
#include <stdlib.h>
int main()
{
float a=0;
scanf("%.2f",&a);
printf("%.2f",a);
return 0;
}
感悟:以为printf("%.2f",a);可以这么表达,那scanf("%.2f",&a);也可以这么表达。这是错误的!
说到scanf函数不得说一下它的定义宽度的问题:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a=0;//对变量a进行初始化
scanf("%2d",&a);//输入数字(只读入2个字符)
printf("%d",a);//它将输出你刚刚输入的数字的前两位字符
return 0;
}
运行效果图:

后面的3456以整型的方式存在于缓存中
好了,我的总结到此结束!谢谢大家的耐心阅读[笑]
大家一起进步!