• 转载
  • 前端开发
  • C++:原来你程序的BUG是这样来的

    2020.03.06 15:04发布

    5962人阅读

    0人评论

    BUG原意是小虫子、昆虫的意思,据传该词被用在编程领域并且成为计算机领域专业术语是因为很久以前一个叫葛丽丝·霍波的”程序员/媛“,她在调试设备时出现故障,拆开设备后,发现有只飞蛾被夹扁在触点中间,从而“卡”住了设备运行。于是,她联想到自己写程序时找问题的场景,诙谐的把程序故障称为“臭虫(BUG)”,把找BUG叫做DEBUG;


    世界上没有不讨厌BUG的程序员,多少程序员为BUG揪掉了满头青丝。那么程序中为什么会出现BUG?这些BUG都是怎么来的呢?


    1.粗心写错、用错


    大部分的BUG都是由于程序员粗心大意,或是用错变量、或是文件路径写错、或者是函数参数传错等。要想避免这种由于粗心大意造成的BUG,除了要细心之外还需要规范自己的代码习惯。如:变量命名严格遵循驼峰原则;灵机一动处的代码逻辑一定要注释清楚,不然后续在维护代码时我保证你会一脸懵逼,强行改动可能就会造成变量用错,逻辑破坏等BUG;多层循环,每层循环变量一定要命名清楚,不要用i,j,k等毫无意义的变量名;


    int a ,b ,c, d, e, f = 0 ;


    string s1,s2,s3 = "";


    for (int i = 0; i < 3; i++)


    {


    for (int j = 0; j < 4; j++)


    {


    for (int k = 0; k < 5; k++)


    {


    }


    }


    }


    小驼峰命名法


    小驼峰式命名规则:firstName, camelCase


    变量一般用小驼峰法标识。驼峰法的意思是:除第一个单词之外,其他单词首字母大写。


    大驼峰命名法:FirstName, CamelCase


    大驼峰法,在小驼峰基础上把第一个单词的首字母也大写了。常用于类名,命名空间等;


    2.基础不扎实


    这个很好理解,就是编程基础不扎实,犯一些基本错误;如:


    string str = "i love u" ;


    if(str.find("y"))cout<<"find"<<endl;


    find函数若是未在目标字符串中找到子串,则会返回-1,这里程序员错误将负数自认为是false,其实不是,在编程界只有0和非0之分;


    又比如:数据类型没弄清楚,忽略了隐式转换:


    double putIn = 123.456;


    double result = 1/3*putIn ;


    这个结果不管putIn是何值,结果都是0,;因为1/3 = 0 ;


    3.考虑不周全,边界极限情况未考虑


    程序员在开发一项业务时,除了需要考虑到要将业务逻辑实现,还需要考虑到各种极限的情况。例如,很多游戏开发人员,只是考虑常规操作玩法,一旦有人进行极端操作可能就会导致程序出现一些莫名的BUG。这一点,就连目前业界顶尖的腾讯诸如王者荣耀、英雄联盟等团队都不能完全避免;例如,最简单的在算两个数相除时:


    double result,dividend,divider = 0 ;


    cin>>dividend>>divider;


    result = dividend/divider ;


    cout<<result<<endl;


    4.未做足够的安全检查


    这一点在C/C++中是经常出现BUG的地方,因为C/C++对安全检查做的不够,很多地方都需要程序员自己去处理可能会出现的异常,不像Python等高级语言,很多异常语言本身已经给你定义好了,出异常时会抛出,对应catch处理就可以。如:常见的C++中vector容器的下标访问不作越界检查,出错时直接中断程序。又或者是用指针时,未对其进行空指针验证,直接就用;


    //数组越界


    vector<int> vecTest(3) ;


    /*N行业务代码*/


    int test_4 = vecTest[4] ;


    //未做空指针验证


    int* ptr = nullptr ;


    /*N行业务代码*/


    *ptr = 1 ;


    正确写法应该是:


    //数组越界


    vector<int> vecTest(3) ;


    /*N行业务代码*/


    int test_4 = 0 ;


    int index = 4 ;


    if(vecTest.size()>=index+1)test_4 = vecTest[index];


    else throw "out of range" ;


    //或者直接用.at()方法


    int test_4 = vecTest.at(4);


    //未做空指针验证


    int* ptr = nullptr ;


    /*N行业务代码*/


    if(ptr!=nullptr)*ptr = 1 ;


    其实也不是什么难事,就是各位在写的时候不要偷懒。


    5.滥用指针,内存泄露


    指针是个好东西,同时它也是一个坏东西,如果用的不好就会导致程序出现严重的BUG,如:内存泄露和野指针。举例:两个指针同时指向同一块内存,但是程序员可能在某处将这块内存通过其中一个指针删除了,此时如果在后面的代码中再去用另外一个指针时一定会出错;又或者就只有一个指针,编程者自己释放了内存,但是指针没有指向NULL,后来又拿来用,同样也一定会出错:


    char* ptr1 = new char[20] ;


    strcpy(ptr1,"i love u") ;


    char* ptr2 = ptr1 ;


    /*N行代码后*/


    delete ptr1 ;


    /*N行代码后*/


    if(ptr2!=nullptr)cout<<ptr2<<endl;


    正确的做法是:释放内存后,将对应的所有指针都指向NULL;


    elete ptr1 ;


    ptr1 = nullptr ;


    ptr2= nullptr ;


    有时后可能不是程序员粗心造成这样,比如对象中存在指针时,如果采用的浅拷贝,极有可能出现这样的情况,而且没有足够经验的程序员是很难察觉到的;


    总结


    就像当初小编的老师说的,没人敢说他没写过BUG。只要大家规范代码,基础扎实,细心,考虑问题全面就一定能写出一手优质代码。


    文章来源于网络,版权归原作者所有,内容为作者个人观点,文章仅供学习,如有侵权请联系客服删除,本站拥有对此声明的最终解释权。

  • C++
  • 前端开发
  • 举报文章

  • 收藏博客:

  • 分享至:
  • 添加评论

    请先登录再评论...

    登录

    评论列表(条评论)

    没有更多评论了