欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
高質(zhì)量C/C++編程(片段)
高質(zhì)量C/C++編程(片段)

這段文字是我從林銳博士的<高質(zhì)量C/C++編程>節選出來(lái)的片段,使其便于快速閱讀

 

【規則1-2-1】為了防止頭文件被重復引用,應當用ifndef/define/endif結構產(chǎn)生預處理塊。

l       【規則1-2-2】用 #include <filename.h> 格式來(lái)引用標準庫的頭文件(編譯器將從標準庫目錄開(kāi)始搜索)。

l       【規則1-2-3】用 #include “filename.h” 格式來(lái)引用非標準庫的頭文件(編譯器將從用戶(hù)的工作目錄開(kāi)始搜索)。

2     【建議1-2-1】頭文件中只存放“聲明”而不存放“定義

--------------------------------

4.3.1 布爾變量與零值比較

l       【規則4-3-1】不可將布爾變量直接與TRUE、FALSE或者1、0進(jìn)行比較。

根據布爾類(lèi)型的語(yǔ)義,零值為“假”(記為FALSE),任何非零值都是“真”(記為T(mén)RUE)。TRUE的值究竟是什么并沒(méi)有統一的標準。例如Visual C++ 將TRUE定義為1,而Visual Basic則將TRUE定義為-1。

假設布爾變量名字為flag,它與零值比較的標準if語(yǔ)句如下:

if (flag)   // 表示flag為真

if (!flag)   // 表示flag為假

其它的用法都屬于不良風(fēng)格,例如:

4.3.2 整型變量與零值比較

l       【規則4-3-2】應當將整型變量用“==”或“!=”直接與0比較。

  假設整型變量的名字為value,它與零值比較的標準if語(yǔ)句如下:

if (value == 0)

if (value != 0)


4.3.3 浮點(diǎn)變量與零值比較

l       【規則4-3-3】不可將浮點(diǎn)變量用“==”或“!=”與任何數字比較。

  千萬(wàn)要留意,無(wú)論是float還是double類(lèi)型的變量,都有精度限制。所以一定要避免將浮點(diǎn)變量用“==”或“!=”與數字比較,應該設法轉化成“>=”或“<=”形式。

  假設浮點(diǎn)變量的名字為x,應當將  

if (x == 0.0)   // 隱含錯誤的比較

轉化為

if ((x>=-EPSINON) && (x<=EPSINON))

其中EPSINON是允許的誤差(即精度)。


4.3.4 指針變量與零值比較

l       【規則4-3-4】應當將指針變量用“==”或“!=”與NULL比較。

  指針變量的零值是“空”(記為NULL)。盡管NULL的值與0相同,但是兩者意義不同。假設指針變量的名字為p,它與零值比較的標準if語(yǔ)句如下:

    if (p == NULL)   // p與NULL顯式比較,強調p是指針變量

    if (p != NULL)

-------------------------

循環(huán)語(yǔ)句的效率

--------------------------
const數據成員的初始化只能在類(lèi)構造函數的初始化表中進(jìn)行,例如

  class A

  {…

    A(int size);     // 構造函數

    const int SIZE ;

  };

  A::A(int size) : SIZE(size)   // 構造函數的初始化表

  {

    …

  }

  A a(100); // 對象 a 的SIZE值為100

  A b(200); // 對象 b 的SIZE值為200

---------------------------------

規則6-1-3】如果參數是指針,且僅作輸入用,則應在類(lèi)型前加const,以防止該指針在函數體內被意外修改。

例如:

void StringCopy(char *strDestination,const char *strSource);

       【規則6-1-4】如果輸入參數以值傳遞的方式傳遞對象,則宜改用“const &”方式來(lái)傳遞,這樣可以省去臨時(shí)對象的構造和析構過(guò)程,從而提高效率。


-------------------------------------


7.1內存分配方式
內存分配方式有三種:

(1)     從靜態(tài)存儲區域分配。內存在程序編譯的時(shí)候就已經(jīng)分配好,這塊內存在程序的整個(gè)運行期間都存在。例如全局變量,static變量。

(2)     在棧上創(chuàng )建。在執行函數時(shí),函數內局部變量的存儲單元都可以在棧上創(chuàng )建,函數執行結束時(shí)這些存儲單元自動(dòng)被釋放。棧內存分配運算內置于處理器的指令集中,效率很高,但是分配的內存容量有限。

(3)     從堆上分配,亦稱(chēng)動(dòng)態(tài)內存分配。程序在運行的時(shí)候用malloc或new申請任意多少的內存,程序員自己負責在何時(shí)用free或delete釋放內存。動(dòng)態(tài)內存的生存期由我們決定,使用非常靈活,但問(wèn)題也最多。

--------------------------------------


u     內存分配未成功,卻使用了它。

編程新手常犯這種錯誤,因為他們沒(méi)有意識到內存分配會(huì )不成功。常用解決辦法是,在使用內存之前檢查指針是否為NULL。如果指針p是函數的參數,那么在函數的入口處用assert(p!=NULL)進(jìn)行檢查。如果是用malloc或new來(lái)申請內存,應該用if(p==NULL) 或if(p!=NULL)進(jìn)行防錯處理。

------------------------------

C++/C程序中,指針和數組在不少地方可以相互替換著(zhù)用,讓人產(chǎn)生一種錯覺(jué),以為兩者是等價(jià)的。

    數組要么在靜態(tài)存儲區被創(chuàng )建(如全局數組),要么在棧上被創(chuàng )建。數組名對應著(zhù)(而不是指向)一塊內存,其地址與容量在生命期內保持不變,只有數組的內容可以改變。

指針可以隨時(shí)指向任意類(lèi)型的內存塊,它的特征是“可變”,所以我們常用指針來(lái)操作動(dòng)態(tài)內存。指針遠比數組靈活,但也更危險

示例7-3-1中,字符數組a的容量是6個(gè)字符,其內容為hello\0。a的內容可以改變,如a[0]= ‘X’。指針p指向常量字符串“world”(位于靜態(tài)存儲區,內容為world\0),常量字符串的內容是不可以被修改的。從語(yǔ)法上看,編譯器并不覺(jué)得語(yǔ)句p[0]= ‘X’有什么不妥,但是該語(yǔ)句企圖修改常量字符串的內容而導致運行錯誤。

7.3.2 內容復制與比較

  不能對數組名進(jìn)行直接復制與比較。示例7-3-2中,若想把數組a的內容復制給數組b,不能用語(yǔ)句 b = a ,否則將產(chǎn)生編譯錯誤。應該用標準庫函數strcpy進(jìn)行復制。同理,比較b和a的內容是否相同,不能用if(b==a) 來(lái)判斷,應該用標準庫函數strcmp進(jìn)行比較。

  語(yǔ)句p = a 并不能把a的內容復制指針p,而是把a的地址賦給了p。要想復制a的內容,可以先用庫函數malloc為p申請一塊容量為strlen(a)+1個(gè)字符的內存,再用strcpy進(jìn)行字符串復制。同理,語(yǔ)句if(p==a) 比較的不是內容而是地址,應該用庫函數strcmp來(lái)比較。

 

  // 數組…

  char a[] = "hello";

  char b[10];

  strcpy(b, a);       // 不能用   b = a;

  if(strcmp(b, a) == 0)   // 不能用 if (b == a)

  // 指針…

  int len = strlen(a);

  char *p = (char *)malloc(sizeof(char)*(len+1));

  strcpy(p,a);         // 不要用 p = a;

  if(strcmp(p, a) == 0)   // 不要用 if (p == a)

------------------------------------

針p指向a,但是sizeof(p)的值卻是4。這是因為sizeof(p)得到的是一個(gè)指針變量的字節數,相當于sizeof(char*),而不是p所指的內存容量

  void Func(char a[100])

  {

    cout<< sizeof(a) << endl;   // 4字節而不是100字節

}

-----------------------------------

毛病出在函數GetMemory中。編譯器總是要為函數的每個(gè)參數制作臨時(shí)副本,指針參數p的副本是 _p,編譯器使 _p = p。如果函數體內的程序修改了_p的內容,就導致參數p的內容作相應的修改。這就是指針可以用作輸出參數的原因。在本例中,_p申請了新的內存,只是把_p所指的內存地址改變了,但是p絲毫未變。所以函數GetMemory并不能輸出任何東西。事實(shí)上,每執行一次GetMemory就會(huì )泄露一塊內存,因為沒(méi)有用free釋放內存

-----------------------------------

用函數返回值來(lái)傳遞動(dòng)態(tài)內存這種方法雖然好用,但是常常有人把return語(yǔ)句用錯了。這里強調不要用return語(yǔ)句返回指向“棧內存”的指針,因為該內存在函數結束時(shí)自動(dòng)消亡,見(jiàn)示例7-4-4。

 

char *GetString(void)

{

  char p[] = "hello world";

  return p;   // 編譯器將提出警告

}

-------------------------------------

用調試器跟蹤示例7-5,發(fā)現指針p被free以后其地址仍然不變(非NULL),只是該地址對應的內存是垃圾,p成了“野指針”。如果此時(shí)不把p設置為NULL,會(huì )讓人誤以為p是個(gè)合法的指針。

-------------------------------

alloc與free是C++/C語(yǔ)言的標準庫函數,new/delete是C++的運算符。它們都可用于申請動(dòng)態(tài)內存和釋放內存。
對于非內部數據類(lèi)型的對象而言,光用maloc/free無(wú)法滿(mǎn)足動(dòng)態(tài)對象的要求。對象在創(chuàng )建的同時(shí)要自動(dòng)執行構造函數,對象在消亡之前要自動(dòng)執行析構函數。由于malloc/free是庫函數而不是運算符,不在編譯器控制權限之內,不能夠把執行構造函數和析構函數的任務(wù)強加于malloc/free。

 函數malloc的原型如下:
  void * malloc(size_t size);
 用malloc申請一塊長(cháng)度為length的整數類(lèi)型的內存,程序如下:
  int  *p = (int *) malloc(sizeof(int) * length);
我們應當把注意力集中在兩個(gè)要素上:“類(lèi)型轉換”和“sizeof”。

u malloc返回值的類(lèi)型是void *,所以在調用malloc時(shí)要顯式地進(jìn)行類(lèi)型轉換,將void * 轉換成所需要的指針類(lèi)型。
u malloc函數本身并不識別要申請的內存是什么類(lèi)型,它只關(guān)心內存的總字節數。我們通常記不住int, float等數據類(lèi)型的變量的確切字節數。例如int變量在16位系統下是2個(gè)字節,在32位下是4個(gè)字節;而float變量在16位系統下是4個(gè)字節,在32位下也是4個(gè)字節。

free(p)能正確地釋放內存。如果p是NULL指針,那么free對p無(wú)論操作多少次都不會(huì )出問(wèn)題。如果p不是NULL指針,那么free對p連續操作兩次就會(huì )導致程序運行錯誤。

-----------------------------------

 運算符new使用起來(lái)要比函數malloc簡(jiǎn)單得多,例如:
int  *p1 = (int *)malloc(sizeof(int) * length);
int  *p2 = new int[length];
這是因為new內置了sizeof、類(lèi)型轉換和類(lèi)型安全檢查功能。對于非內部數據類(lèi)型的對象而言,new在創(chuàng )建動(dòng)態(tài)對象的同時(shí)完成了初始化工作。如果對象有多個(gè)構造函數,那么new的語(yǔ)句也可以有多種形式。例如

在用delete釋放對象數組時(shí),留意不要丟了符號‘[]’。例如
 delete []objects; // 正確的用法
delete objects; // 錯誤的用法
后者相當于delete objects[0],漏掉了另外99個(gè)對象。

------------------------------------------

如果C++程序要調用已經(jīng)被編譯后的C函數,該怎么辦?
假設某個(gè)C函數的聲明如下:
void foo(int x, int y);
該函數被C編譯器編譯后在庫中的名字為_(kāi)foo,而C++編譯器則會(huì )產(chǎn)生像_foo_int_int之類(lèi)的名字用來(lái)支持函數重載和類(lèi)型安全連接。由于編譯后的名字不同,C++程序不能直接調用C函數。C++提供了一個(gè)C連接交換指定符號extern“C”來(lái)解決這個(gè)問(wèn)題。例如:
extern “C”
{
   void foo(int x, int y);
   … // 其它函數
}
或者寫(xiě)成
extern “C”
{
   #include “myheader.h”
   … // 其它C頭文件
}
這就告訴C++編譯譯器,函數foo是個(gè)C連接,應該到庫中找名字_foo而不是找_foo_int_int。C++編譯器開(kāi)發(fā)商已經(jīng)對C標準庫的頭文件作了extern“C”處理,所以我們可以用#include 直接引用這些頭文件。

----------------------------------------------

對于任意一個(gè)類(lèi)A,如果不想編寫(xiě)上述函數,C++編譯器將自動(dòng)為A產(chǎn)生四個(gè)缺省的函數,如
 A(void);     // 缺省的無(wú)參數構造函數
 A(const A &a);    // 缺省的拷貝構造函數
 ~A(void);     // 缺省的析構函數
 A & operate =(const A &a); // 缺省的賦值函數

-----------------------------------------------

構造從類(lèi)層次的最根處開(kāi)始,在每一層中,首先調用基類(lèi)的構造函數,然后調用成員對象的構造函數。析構則嚴格按照與構造相反的次序執行,該次序是唯一的,否則編譯器將無(wú)法自動(dòng)執行析構過(guò)程。
一個(gè)有趣的現象是,成員對象初始化的次序完全不受它們在初始化表中次序的影響,只由成員對象在類(lèi)中聲明的次序決定。這是因為類(lèi)的聲明是唯一的,而類(lèi)的構造函數可以有多個(gè),因此會(huì )有多個(gè)不同次序的初始化表。如果成員對象按照初始化表的次序進(jìn)行構造,這將導致析構函數無(wú)法得到唯一的逆序

------------------------------------------------

u 如果輸入參數采用“指針傳遞”,那么加const修飾可以防止意外地改動(dòng)該指針,起到保護作用。
例如StringCopy函數:
  void StringCopy(char *strDestination, const char *strSource);

對于非內部數據類(lèi)型的輸入參數,應該將“值傳遞”的方式改為“const引用傳遞”,目的是提高效率。例如將void Func(A a) 改為void Func(const A &a)。
對于內部數據類(lèi)型的輸入參數,不要將“值傳遞”的方式改為“const引用傳遞”。否則既達不到提高效率的目的,又降低了函數的可理解性。例如void Func(int x) 不應該改為void Func(const int &x)。

--------------------------------------------------

u 如果給以“指針傳遞”方式的函數返回值加const修飾,那么函數返回值(即指針)的內容不能被修改,該返回值只能被賦給加const修飾的同類(lèi)型指針。
例如函數
  const char * GetString(void);
如下語(yǔ)句將出現編譯錯誤:
  char *str = GetString();
正確的用法是
  const char *str = GetString();
u 如果函數返回值采用“值傳遞方式”,由于函數會(huì )把返回值復制到外部臨時(shí)的存儲單元中,加const修飾沒(méi)有任何價(jià)值。
 例如不要把函數int GetInt(void) 寫(xiě)成const int GetInt(void)。
 同理不要把函數A GetA(void) 寫(xiě)成const A GetA(void),其中A為用戶(hù)自定義的數據類(lèi)型

----------------------------------------------------

 任何不會(huì )修改數據成員的函數都應該聲明為const類(lèi)型。如果在編寫(xiě)const成員函數時(shí),不慎修改了數據成員,或者調用了其它非const成員函數,編譯器將指出錯誤,這無(wú)疑會(huì )提高程序的健壯性。
以下程序中,類(lèi)stack的成員函數GetCount僅用于計數,從邏輯上講GetCount應當為const函數。編譯器將指出GetCount函數中的錯誤。
 class Stack
{
   public:
  void  Push(int elem);
  int  Pop(void);
  int  GetCount(void)  const; // const成員函數
   private:
  int  m_num;
  int  m_data[100];
};

 int Stack::GetCount(void)  const
{
  ++ m_num; // 編譯錯誤,企圖修改數據成員m_num
 Pop();  // 編譯錯誤,企圖調用非const函數
 return m_num;
 }
 const成員函數的聲明看起來(lái)怪怪的:const關(guān)鍵字只能放在函數聲明的尾部,大概是因為其它地方都已經(jīng)被占用了。

----------------------------------------------

#ifndef GRAPHICS_H // 防止graphics.h被重復定義
#define GRAPHICS_H
#include <math.h>// 引用標準庫的頭文件…
#include “myheader.h” // 引用非標準庫的頭文件…
void Function1(…); // 全局函數聲明…
class Box    // 類(lèi)結構聲明{…};
#endif

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
C 知識點(diǎn)
c++知識 - 洋男的日志 - 網(wǎng)易博客
指針與引用
C中內存建立與釋放的函數
C語(yǔ)言經(jīng)典面試題
C/C 指針詳解之提高篇
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久