青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

[翻譯]嵌入式C++編程準則

   譯自:http://www.caravan.net/ec2plus/guide.html


 

 

 A     代碼從C語言到C++語言的移植

A1     字符常量

              注解

                     C中,字符常量是int類型,而在C++中,其類型為char.

 

              示例

                     I = sizeof(‘a’);

 

C中,i保存的實際內容是sizeof(int)的計算結果值,該值要比1大。而在C++中,i存儲的實際內容是sizeof(char),該值總是為1

             

              準則

當將C代碼移植為C++代碼時,所有對字符常量的sizeof有依賴關系的表達式都要被移除。


 

 

A2     文件范圍內的對象聲明

              注解

C++中,在文件范圍內,聲明一個沒有指定存儲類型標志符的對象時,實際上是定義該對象為外部鏈接符號(extern)。如果這個定義中沒有初始化表達式,那么該對象將被初始化為0。相比較于C來說,C++程序中聲明的對象會被明確的定義且只定義過1次。

而在C中,這將被視為一個暫時的定義,這種定義方式在一個translation unit中允許出現多次。

 

示例

          int a;          /* (1) */
          int a = 10;     /* (2) */

C中,(1)是一種暫時性的定義。由于(2)被看作是確切的定義,(1)被看作是只是聲明一個變量。

C++中,(1)、(2)都被認為是定義式。由于存在(1)、(2)兩個重復定義式,因此是一個錯誤。

 

              準則

C++中,如果想在文件范圍內僅聲明一個對象(而不是定義該對象),那么該對象不能擁有初始化表達式,并且需要使用extern來修飾。

聲明于文件范圍內的每一個對象只能顯式的被定義一次。除了一次聲明外,其余所有聲明都必須具有extern修飾并且沒有初始化表達式。


 

 

A.3   const 類型修飾符
      注解
     C中,在文件范圍內,一個使用const修飾而未指明存儲類型的對象具有外部鏈接屬性。而在C++中,它具有內部連接屬性。
 
示例
          +- file1 --------------------+
          |      extern const int n;   |
          +----------------------------+
          +- file2 --------------------+
          |      const int n = 10;     |
          +----------------------------+
C中,文件file2中的對象n具有外部連接屬性,因此,文件file1中對象n(該對象同樣具有外部鏈接屬性)可以引用它。在C++中,文件file2中的對象n具有的屬性是內部鏈接的,因此,file1中的對象n無法引用到它。
          
      準則
           使用extern顯示修飾const對象,使該對象具有外部鏈接屬性。


 

 

A.4    void*的轉型
      注解
          C語言標準允許void*轉換為T*T表示任何對象),而在C++中沒有這樣的標準。在C++中類似的轉換需要顯示轉換來完成。
  下面這些C標準庫函數都返回void*
              calloc, malloc, realloc, bsearch, memcpy, memmove,
              memchr, memset
   C++中,將這些函數的返回值賦值給一個非void*的指針時,需要
顯示轉換。
      示例
          int* p;
          p = malloc(10 * sizeof(int));
 
          C++中,對指針p的賦值需要顯示的轉換,如:
 
          p = (int *)malloc(10 * sizeof(int));
 
      準則
  C++中使用new來代替callocmallocrealloc(參考A.12);
忽略memcpy, memmove, 以及memset的返回值(通常這些返回值由函數的第一個參數轉換而來);對于其他所有返回void*函數(包括標準庫函數和用戶自定義函數),需要使用顯式的轉換來將返回值轉換為其他指針類型。


 

 

A.5   枚舉類型
      注解
           C中的枚舉變量是整型。程序中,枚舉類型和整型可以互相轉換,而不需要顯式的轉換。C程序允許枚舉類型對象進行++--運算。
           C++中的枚舉是一種用戶自定義類型。C++標準允許枚舉類型轉換為整型,但從整型轉換為枚舉類型是非法的。C++程序中還不能將內置的++以及符合運算符(如+=)作用于枚舉類型變量上。
      示例
          enum RGB { red, green, blue } rgb;
          ++rgb;
         
         如果表達式(++rgb)采用內置的++運算符,那么在C++中這是一個錯誤表達式。該表達式的語意相當于:
         rgb = rgb + 1;
          上面的表達式在C++中還是錯誤的。而像下面這樣,對枚舉值進行顯示的轉換就是正確的:
          rgb = RGB(rgb + 1);
          最好的解決方法是為枚舉類型RGB實現一個++運算符。
          RBG &operator++(RGB &x)
          {
              return x = RGB(x + 1);
          }
        
      準則
     C程序移植為C++程序時,在需要的時候,要為枚舉類型實現類型安全的++--操作符。
 


 

 

A.6    在轉型、參數聲明、sizeof中定義類型
       注解
          C中,轉型表達式、參數聲明以及sizeof表達式中都可以進行類
型聲明,而在C++中則不能。
 
示例
          void func(struct TAG { int a; } st)
          {
              ...
          }
         如上所示,TAG在參數聲明是被定義。
        準則
          把在參數中聲明的類型的定義式,挪到函數聲明式作用域開始處,或者大于該作用域的某處。
 
           在轉型和sizeof表達式作用域開始處,或者大于該作用域的某處定義類型。


 

 

A.7   忽略局部對象定義式的控制流程跳轉
        注解
         C中,gotoswitch語句可以使控制流程跳過塊作用域內的局
部對象聲明式,甚至有可能是對象的初始化式。而在C++中不存在這種跳轉。
 
示例
          goto LABEL;
          {
              int v = 0;
              ...
          LABEL:
              ...
          }
           C中,上面的代碼是合法的,它假設標簽LABEL之后的代碼不依賴于整型變量v的初值0。而在C++中,這段代碼總是不能通過編譯。
       準則
            確保gotoswitch語句沒有跳過局部對象的初始化式。


 

 

A.8   字符數組的初始化
       注解
          C中,允許使用字符串來初始化一個字符數組。初始化表達式中,數組可以比字符串少一個字符空間(‘\0’字符)。在C++中數組則必須能完全容納字符串。
      示例
          char s[3] = "abc";
           盡管常量字符串為4個字符大小,但數組s的大小為3。這種做法在C中合法,而在C++中非法。
      準則
          為了容納‘\0’,請確保字符數組大小要比字符串長度大1。因而,有必要將字符數組大小指定為字符串長度+1。(也即:char s[4] = "abc";
          然而,為了使定義式自適應于不同的常量字符串,在定義式中不指定數組大小不失為一種好方法(即:char s[] = "abc";)。


 

 

A.9   原型聲明
       注解
          C++程序要求在使用函數之前必須聲明該函數原型。此外,C++程序會將函數聲明式f()解釋為f(void)----不帶參數的函數。而在C中,這樣的行為是不確定的。
      示例
          extern void func();
          ....
          sub();
          func(0);
          因為沒有sub函數的聲明,因此調用該函數是錯誤的。由于聲明式中函數不帶參數,因此以0為參數調用func也是個錯誤。
      準則
          確保被調用的函數已經被聲明。為了強調函數f不帶參數,好的做法是在聲明函數時,將參數聲明為void,即聲明式為:f(void).


 

 

A.10 C++增加的關鍵字
     注解
          C中沒有下面的C++關鍵字:
          asm             bool            catch           class
          const_cast      delete          dynamic_cast    explicit
          false           friend          inline          mutable
          namespace       new             operator        private
          protected       public          reinterpret_cast
          static_cast     template        this            throw
          true            try             typeid          typename
          using           virtual         wchar_t

示例

          int class, new, old;

         準則

                   確保沒有使用C++關鍵字作為標記符。


 

 

A.11 嵌套類型的作用域
     注解
          C結構體或聯合體內定義嵌套類型,該類型的作用域終止點和該結構
體或聯合體相同。而C++中定義的嵌套類型作用域終結于該結構或聯合體。
示例
          struct S {
              int a;
              struct T {
                  int t;
              } b;
              int c;
              enum E { V1, V2 } e;
          };
 
          struct T x;
          enum E y;
         xy的聲明在C程序中是合法的,但在C++中非法。在C++程序中,
在類S中定義的類型TE的作用域不會超過類S的定義范圍。
準則
    除非只是在結構體或聯合體內使用定義的嵌套類型,否則不在嵌套作用域內定義類型。


 

 

A.12 動態內存管理
     注解
          newdeletemallocfree沒有采用相同的內存管理策略。因此,
除非已經使用new獲取了內存,否則應用程序中不能使用delete來釋放內
存。同樣,除非使用了malloc分配內存,否則不能使用free來釋放內存。
 示例
          int (*p)[10];
          p = (int (*)[10])malloc(sizeof(*p));
          ....
          delete p;
 
          這里的delete具有未定義的行為。
     準則
        C++中避免使用malloccallocreallocfree函數,而僅使用
new/delete.


 

 

A.13 '/'之后的'/*'
     注解
        C++程序具有‘//’的注釋風格,因此緊接在符號‘/’之后的C風格
注釋‘/**/’,會被C++程序作為理解為‘//’后接‘**/’
示例
          i = j //* comment */ k ;
         //’被解釋為注釋分隔符,因而表達式被解釋為‘i=j’而不是‘i=j/k’。
準則
    盡量避免緊接著符號‘/’后寫C風格注釋‘/**/’.

 


 

 

B.    關于代碼容量的準則
B.1   對象初始化
       注解
有很多方法來初始化某個對象,有些初始化方法將會產生不必要的
臨時對象,從而導致代碼量膨脹。
     例如:
          T x(i)        // (1)
 
          T x = i;      // (2)
 
          T x = T(i)    // (3)
 
          T x;          // (4)
          x = i;        //
(1) 直接使用構造函數來初始化對象x,這樣就不會產生臨時對象。
調用形式類似于:
x.T(i);             // x對象調用構造函數
(2) 在某些實現中,方法(2)類似于方法(1),即對象x直接調用
構造函數。而在另外一些實現中,該方法會先使用構造函數生成一個臨時對象,然后將該臨時對象作為對象x的初始值。調用形式類似于:
              temp.T(i);        // 生成temp
              x.T(temp);        // x調用拷貝構造函數
              temp.~T();        // 析構temp
(3) 等同于(2
(4) 使用T的默認構造函數來初始化x,然后調用賦值操作符將新值
賦給x。賦值操作符可能會釋放x正在使用的資源,并重新為x獲取新的資源。
              x.T();           // x調用默認構造函數
              x.operator=(i); // x調用賦值操作符
       準則
            在上面的四種方法中,優先考慮方法(1)。
 


 

 

B.2   inline標記符
     注解
          內聯減少了函數進出棧上的管理開銷,但這也同時增加了代碼容量。
          在內內部定義的成員函數默認是內聯的。
     準則
          僅對小函數進行inline修飾。在類體之外定義所有不適合作為內聯函數的成員方法,從而使得該成員不是內聯函數。


 

 

B.3   返回值中的臨時對象
     注解
         函數按值返回一個對象時,可能需要創建并銷毀一個臨時對象,從而
導致代碼量增加并且帶來運行時開銷。
 示例
          class Matrix {
              int a, b;
          public:
              Matrix &operator+=(const Matrix &);
              friend
                  Matrix operator+(const Matrix &, const Matrix &);
          };
 
          Matrix operator +(const Matrix &, const Matrix &)
          {
              ...
          }
 
          void func()
          {
              Matrix a,b;
              a = a + b;        // (1)
              a += b;           // (2)
          }
          函數func在(1)處調用了+操作符,該操作符按值返回一個Matrix
對象。在某些編譯器實現中,會先構造一個Maxtrix臨時對象,然后銷毀
該臨時對象。
          函數func在(2)處調用+=操作符,該操作符返回一個Matrix對象
引用,因而不會構造臨時對象。
     準則
         對于類類型對象,使用復合賦值操作符(如使用‘+=’而不是‘+’和
=’)來避免編譯器生成再銷毀不必要的臨時對象。
 
注:個人認為這個準則有失準確。此例中,+=操作符不產生臨時對象的原因在于該操作符按引用返回對象而非按值返回對象。因此,準確的說法是,使用按引用或指針返回對象的函數來避免構造不必要的臨時對象。


 

 

B.4   newdelete操作符
     準則
        在必要時,實現類屬的newdelete操作符,從而提升管理動態內存
的速度和內存利用率。


 

 

B.5   全局對象的初始化
     注解
          全局對象初始化的順序依賴于編譯器的實現。但可以肯定的是,在同一個解釋單元其初始化順序和對象的聲明順序相同。
    示例
 
          文件1           文件2             文件3
 
          int a = f();    int b = f();      int f(void)
                                            {
                                                static int a = 0;
                                                return a++;
                                            }
        程序可能將a初始化為0,而b1,或者反過來。這依賴于編譯器如何選擇他們的初始化順序。
         如果將文件2中變量b的聲明移到文件1中,那么兩變量的初始化順序就隨即確定了,即:
          文件1           文件2             文件3
 
          int a = f();                      int f(void)
          int b = f();                      {
                                                static int a = 0;
                                                return a++;
                                            }
         這種情況下,a要先于b被初始化。
         避免編寫依賴于不同解釋單元內全局對象初始化順序的代碼。


 

 

C.    關于速度的準則
C.1   元素為類對象的數組中的newdelete
     注解
         聲明元素為類對象的數組時,編譯器會為該數組每一個元素調用構造
函數。在超出該數組的作用域范圍時,又會一一調用每個元素的析構函數。構造/析構可能占用超乎想象的時間,這在實時過程系統中是一個問題。
準則
    在對時間要求比較高的過程系統中,避免創建/銷毀大型的元素為類對象的數組。


 

 

C.2   循環體內的對象聲明
注解
         如果在循環體內聲明類變量,那么在循環的每次迭代時都需要構造并
析構該對象。這種構造并析構帶來的問題就是循環執行速度降低。
示例
          for (i = 0; i < 1000; i++)
          {
              FOO a;
              ...
          }
     準則
        在循環體外部聲明類類型變量,而避免在內部聲明。


 

 

D.    編寫只讀型代碼準則
D.1   ROM中的const對象
     注解
          通常,如果const對象具有如下一些屬性,則可以存儲在ROM中:
          -- 具有static存儲時長
          -- 由常量表達式初始化
          -- 是一個PODplain old data)類型對象
          POD類型對象具有如下屬性:
          -- 一個無屬性(scalar)類型(數字, 枚舉和指針) 
          -- 類/結構/聯合體中所有數據成員都是public訪問權限并且是
POD類型, 同時類中沒有用戶自定義的構造函數/析構函數,沒有基類和虛函數
          -- 所有元素都是POD類型的數組
      示例
          static const char lang[] = "EC++";
          class A {
              int a;
          public:
              A();
              ~A();
          };
          const A x;
 
          'lang'可能存儲于ROM中,而‘x’則不會。
      準則
          欲將對象存儲于ROM中,則將對象聲明為POD類型,并使用常量初始化該對象。


 

 

NOTE: The form of presentation used here, and several of the specific
guidelines, were inspired by the excellent book by Thomas Plum and
Dan Saks, 'C++ Programming Guidelines' (Plum Hall Inc., 1991).

 

posted on 2009-04-29 14:02 Wealth 閱讀(1862) 評論(0)  編輯 收藏 引用 所屬分類: C++Translation

<2009年4月>
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789

導航

統計

常用鏈接

留言簿

隨筆分類(8)

隨筆檔案(8)

文章分類

Around Web

CoBlog

Develop Usage Link

搜索

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            香蕉成人伊视频在线观看| 日韩视频免费| 免费观看成人鲁鲁鲁鲁鲁视频| 亚洲欧美中文日韩v在线观看| 亚洲欧美春色| 欧美一级淫片aaaaaaa视频| 久久激情视频| 欧美精品久久99| 国产精品一二一区| 影音先锋亚洲视频| 日韩视频精品在线| 久久国产精彩视频| 欧美不卡在线视频| 在线性视频日韩欧美| 欧美一级在线视频| 欧美刺激性大交免费视频| 欧美午夜片欧美片在线观看| 国产一区二区三区四区| 亚洲美女视频在线观看| 欧美伊人精品成人久久综合97| 久久亚洲春色中文字幕| 亚洲日本一区二区| 亚洲电影第三页| 亚洲综合三区| 欧美激情片在线观看| 国产视频亚洲| 亚洲天堂黄色| 亚洲第一毛片| 午夜精品久久久久| 欧美喷潮久久久xxxxx| 中文久久精品| 国产欧美一二三区| 亚洲激情电影在线| 久久国产精品毛片| 99re6热只有精品免费观看| 欧美一区二区在线看| 欧美日韩美女在线| 亚洲国产精品精华液网站| 亚洲综合色自拍一区| 欧美岛国激情| 久久精品国产999大香线蕉| 国产精品高清在线| 夜夜爽av福利精品导航| 欧美激情女人20p| 久久国产精品久久久久久久久久| 欧美亚韩一区| 在线亚洲免费| 亚洲国产精品日韩| 久久亚洲综合| 136国产福利精品导航网址应用 | 久久人人爽人人爽爽久久| 99在线精品观看| 欧美精品自拍| 99视频在线观看一区三区| 欧美成年人视频| 久久男女视频| 在线欧美福利| 亚洲高清电影| 嫩草影视亚洲| 99国产一区二区三精品乱码| 亚洲国产精品成人va在线观看| 久久综合婷婷| 91久久在线视频| 亚洲国产另类精品专区 | 欧美福利视频在线| 久久久亚洲精品一区二区三区| 国产主播精品在线| 久久久久一区| 久久人人97超碰国产公开结果| 伊人伊人伊人久久| 欧美激情精品久久久久久免费印度| 久久综合一区| aⅴ色国产欧美| 亚洲午夜av电影| 国产一区二区三区电影在线观看| 久久久久九九九| 麻豆精品在线播放| 99视频有精品| 午夜精品网站| 亚洲激情另类| 一区二区三区国产精华| 国产午夜精品久久久久久免费视| 久久中文字幕一区| 欧美国产一区二区| 欧美一区二区三区在线播放| 国产精品视频你懂的| 亚洲日产国产精品| 亚洲视频日本| 国产性猛交xxxx免费看久久| 免费不卡亚洲欧美| 欧美日韩色综合| 欧美在线视频导航| 欧美成人午夜77777| 亚洲欧美一区二区三区在线| 久久人体大胆视频| 亚洲欧美欧美一区二区三区| 久久精品国产久精国产思思| 在线性视频日韩欧美| 欧美在线观看一区| 一本一道久久综合狠狠老精东影业| 亚洲欧美日韩国产成人| 亚洲黄色片网站| 香蕉久久精品日日躁夜夜躁| 亚洲精品男同| 久久久www成人免费精品| 一本色道久久综合狠狠躁的推荐| 久久精品国语| 亚洲欧美三级伦理| 欧美精品一区二区三区一线天视频| 欧美一区二区三区婷婷月色| 欧美好吊妞视频| 欧美~级网站不卡| 国产婷婷精品| 亚洲一区国产| 亚洲一区不卡| 欧美日本中文字幕| 亚洲国产mv| 亚洲国产va精品久久久不卡综合| 午夜精品福利一区二区蜜股av| 亚洲社区在线观看| 欧美黄色大片网站| 欧美激情1区2区3区| 狠狠色狠狠色综合日日小说| 亚洲欧美在线播放| 性伦欧美刺激片在线观看| 欧美吻胸吃奶大尺度电影| 亚洲精品美女91| 亚洲精品乱码久久久久久蜜桃91 | 亚洲欧洲精品一区| 久久aⅴ乱码一区二区三区| 午夜免费在线观看精品视频| 欧美日韩的一区二区| 亚洲黑丝在线| 亚洲老司机av| 欧美日韩国产页| 亚洲精品一区二区三区在线观看| 亚洲精品国产精品乱码不99按摩 | 欧美精品在线免费播放| 亚洲电影视频在线| 亚洲精品欧美专区| 欧美久久一区| 一区二区欧美激情| 欧美影院在线| 国产综合激情| 久久免费一区| 亚洲激情婷婷| 中文久久乱码一区二区| 欧美天堂亚洲电影院在线观看 | 久久久av水蜜桃| 久久亚洲精品伦理| 亚洲国产岛国毛片在线| 欧美成人资源网| 一区二区三区国产| 久久精品官网| 尤物网精品视频| 欧美成人亚洲成人日韩成人| 亚洲精品三级| 午夜久久影院| 一区二区三区在线视频免费观看 | 欧美高清视频免费观看| 亚洲免费av网站| 国产精品免费网站| 久久精品成人一区二区三区蜜臀 | 夜夜精品视频一区二区| 亚洲欧美日韩中文视频| 国产午夜精品久久久| 你懂的成人av| 亚洲午夜91| 欧美电影在线免费观看网站| 一本色道久久综合亚洲二区三区| 国产乱码精品| 欧美激情视频网站| 性欧美videos另类喷潮| 亚洲国产精品热久久| 欧美在线观看一区| 日韩视频免费在线| 韩国精品久久久999| 欧美日韩视频一区二区三区| 欧美一区二区在线免费播放| 最新国产成人在线观看| 欧美资源在线| 中日韩午夜理伦电影免费| 精东粉嫩av免费一区二区三区| 欧美日韩伦理在线免费| 久色婷婷小香蕉久久| 亚洲欧美日韩区| 亚洲美女在线视频| 欧美国产专区| 久久伊伊香蕉| 欧美一区二区三区四区在线观看地址 | 欧美激情a∨在线视频播放| 亚洲欧美日韩一区二区三区在线| 亚洲国产清纯| 久久婷婷人人澡人人喊人人爽| 亚洲欧美日韩综合一区| 亚洲视频1区2区| 日韩视频免费| 亚洲人成人77777线观看| 国内伊人久久久久久网站视频 | 亚洲午夜久久久|