程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 小計良好的編程習慣(1),小計編程習慣

小計良好的編程習慣(1),小計編程習慣

編輯:C++入門知識

小計良好的編程習慣(1),小計編程習慣


本文記錄了最近學習過程中,以及在編碼過程中,感受到的比較好的編程習慣。如果有什麼地方您覺得不妥,還請留言指出。


  • 變量(普通變量和指針)的初始化。

    解釋:對於C/C++來說,聲明的變量沒有初始化,那麼裡面的值是有的(以前該內存的數值),所以對於自加自減的運算,在這裡容易出錯。而指針更是危險,聲明的指針沒有賦值的話,裡面也是有值的,此時你不知道聲明的指針指向哪裡,等到你使用的時候,才會給指針賦值,那麼在這期間,如果你使用了指針,修改了裡面的東西,那就是無知的修改,是最可怕的。代碼理解如下:

    #include <QCoreApplication>
    #include <QDebug>
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        int i;
        qDebug()<<++i;//4203055
        int *p;
        qDebug()<<p;//0x22ff88
        p = (int *)malloc(sizeof(int)*1);
        qDebug()<<p;//0x847b38
        //下面是良好的習慣
        int j=0;
        qDebug()<<++j;//1
        int *pointer=NULL;
        qDebug()<<pointer;//0x0
        pointer = (int *)malloc(sizeof(int)*1);
        qDebug()<<pointer;//0x847b48
        qDebug()<<"Hello word!";
        
        return a.exec();
    }
  • 指針的釋放與置空

    程序中為指針動態分配的內存,在程序結尾的時候,不僅養成釋放內存的習慣,還要養成為指針置空的習慣。也就說,結尾你把指針的內存釋放了,但是該指針還是指向這裡的,這樣就存在了一個安全隱患,所以要置空。代碼展示如下:

    #include <stdlib.h>
    #include <iostream>
    using namespace std;
    int main()
    {
        int *pointer=NULL;//指針初始要為NULL
        pointer = (int *)malloc(sizeof(int)*1);
        cout << "Hello World! I am over!" << endl;
        //以下為良好的指針結束方式(來也空空去也空空)
        free(pointer);
        pointer = NULL;
        return 0;
    }
  • malloc申請的動態內存,坑多多,不要用strlen測量

    解釋:這個錯誤曾經導致了整個QQ群的轟動,其實當你查看一下你動態開辟的內存的裡面的內容的時候,你就會恍然大悟。先簡單解釋一下,主要是C語言的strlen函數沒有搞清楚。我們所使用的所有內存,如果沒有初始化,那麼裡面肯定會有內容的(計算機原理),包括了我們動態開辟的內存,而strlen函數的作用,測量字符串的長度(以'\0'結束).未知的世界中永遠存在著未知的可能,未知的內存中,也許中間部分就包括了'\0'奧。那麼使用strlen測量,就會有讓人意外的結果了。代碼展示如下:

    #include <string.h>
    #include <stdlib.h>
    #include <iostream>
    using namespace std;
    int main()
    {
        char *pointer=NULL;//指針初始要為NULL
        pointer = (char *)malloc(sizeof(char)*15);
        cout<<"string:"<<strlen(pointer);//我的輸出3
        cout<<"value:"<<pointer;
        cout<<endl;
        char *pointer1="You Love Me.";//12
        cout<<"string1:"<<strlen(pointer1);
        cout<<endl;
        return 0;
    }
    解釋:在C/C++中判定語句有一種特性,叫做“斷路”。比如:if(條件1&&條件2)這個判定,如果要想為真,則2個條件都必須為真。判定如果為假,在實際中,如果條件1為假的話,那麼程序就不會去判定條件2的真假了。這就是斷路現象。同理,if(條件1&&條件2)只要條件1為真,就不會判定第二個條件了。那麼我們的實例會產生怎樣的錯誤呢?首先我們這句while(NULL != p && item->data > p->data )是正確的,但是如果你把2個條件前後交換,那麼就制造了一個bug.我的思路是,首先判斷p的指向是否存在,存在的話,然後p->data是否為真,如果前後2個條件調換的話,那麼當p=NULL的話,p->data會在哪裡呢?你去哪裡讀數據?程序就這樣被你玩兒死了。

  • 判斷條件句中的變量比較
    #include <iostream>
    using namespace std;
    //下面每個變量都與零值比較,選擇最優的方法
    int main()
    {
        bool flag;
        if(flag == true){}
        if(flag == false){}
        //bool類型的變量應該選擇下面的規范
        if(flag){}//這種方法最優,因為true的值不確定
        if(!flag){}
    
        int value;
        if(value == 0){}//這種方法好,下面的會讓人誤解是布爾類型
        if(value != 0){}
    
        if(value){}
        if(!value){}
    
        float x;
        if(x == 0){}
        if(x != 0){}
        //下面的方法好,因為所有的float和double類型都有精度的,所以轉化為下面的形式比較
        if((x >= -EPSINON)&&(x <= EPSINON)){}
        if((X < -EPSINON) || (x > EPSINON)){}
    
        int *p;
        if(p == NULL){}//這種好
        if(p != NULL){}
    
        if(p == 0){}
        if(p != 0){}
    
        //有的時候,還會這樣寫(想一想這種方法的好處)
        if(0 == value){}
        if(NULL == p){}
        cout << "Hello World!" << endl;
        return 0;
    }
  • 判斷條件中不要使用含有副作用的語句

    解釋:首先,何為副作用,就是會改變程序狀態的語句。看代碼實例:

    if('Y'==getchar() || 'y' == getchar())//getchar()從緩沖區中,讀一個少一個,那麼讀的過程中,程序的狀態是不是改變了,那麼這就容易發生錯誤。
    {}
    //規范的如下:
    char ch=toupper(getchar());//自己體會一下
    if('Y'==ch)
    {}
  • 在定義函數或者變量名的時候,小心和關鍵字沖突或者標准函數沖突。
  • 函數中的形參,在函數體中不改變的話,設置為const常量
  • 對於函數中傳遞過來的參數,要進行安全檢查
  • 變量的定義應該“何時使用,何時定義,何地使用,何時定義”,變量定義的位置,應該和使用的地方緊湊一點。

  • 良好的編程習慣只有在你寫程序的時候才能完全的體會到。同時,如果您有更好的理解,可以在下面留言,一起學習進步。

    1. 上一頁:
    2. 下一頁:
    Copyright © 程式師世界 All Rights Reserved