亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

C++編程易范的錯誤

2019-11-17 05:06:15
字體:
來源:轉載
供稿:網友
C/C++語言中有許多對初學者(甚至是有經驗的編程人員)來說很輕易范的錯誤。通曉這樣的錯誤可使你免于陷入其中。
忘記初始化指針
這種錯誤只是一般"忘記初始化變量"錯誤的一個非凡形式(C/C++中變量不會自動初始化,而Basic可以)。使這種錯誤更糟糕的原因是它的后果往往更加糟糕:
void SomeFunction()
{
int *pnVar
int nVal;
nVal = *pnVar; // Bad enough.
*pnVar = nVal; // MUCh worse.
}
在這個例子中,指針變量pnVar從未被賦值。因此你必須假設它含有的是雜亂的數據,從一個混亂信息指針中讀數糟糕的很,因為結果肯定是雜亂數據,向一個混亂信息指針寫數據更糟,因為它將導致一些不知道什么地方的數據被重寫。
假如被重寫的區域無用,這到沒什么危害。假如被重寫的區域有用,數據就會丟失。這種類型的錯誤那么難找,是因為直到程序企圖使用已丟失的數據時問題才會呈現出來。這種問題可能是在數據丟失后好久才發生的。
由于這一問題手工判定很困難,Visual C++編譯器就通過一些努力來避免它的發生。例如,當你編譯上述函數時就會產生一個警告。在這種情況下,編譯器會告訴你變量在使用前未被賦值。在很多情況下,它不可能告訴你。
Windows 95操作系統試圖用保護存儲器在一定程度上幫助解決難題:假如應用程序企圖從不屬于它的存儲器讀或寫,Windows通常能截獲該請求,并立即終止該程序??上В琖indows 95不能截獲對應用程序擁有的存儲器的無效訪問,它也不能截獲所有非法訪問,因為必須保留某些缺口,以與Windows 3.1的兼容性名義開放。
忘記釋放堆內存
請記住從堆獲得分配的任何內存都必須要釋放。假如你用完內存以后,忘記釋放它,系統內存就會變得愈來愈小,直到最后你的程序不能運行而崩潰。
這個問題會出現在諸如下列的一些情況中:
Car* GetAnewCar(int nOccupants)
{
Car* pCar;
if(nOccupants < 4)
{
pCar = new Car(2); // get a two-door.
}
else
{
pCar = new Car(4); // otherwise, a four-door.
}
return pCar;
}
void GoToTheStore(int nOccupants)
{
// get a car。
Car* pCar = GetAnewCar(nOccupants);
// Now drive to the store。
if(pCar)
{
pCar->Drive(Store);
}
} 更多文章 更多內容請看C/C++技術專題  java編程開發手冊專題,或
在此例中,函數GoToTheStore()首先分配一輛新車來開——這有點浪費,但你肯定會同意這種算法可以正常工作。只要分配了新車,它就會開到有調用pCar->Drive(Store)所指向的商店。
問題是在它安全到達目的地之后,函數不破壞Car對象。它只是簡單地退出,從而使內存丟失。
通常,當對象pCar出了程序中的作用域時,程序員應該依靠析構函數~Car釋放內存。但這里辦不到,因為pCar的類型不是Car而是Car*,當pCar出了作用域時不會調用析構函數。
修正的函數如下:
void GoToTheStore(int nOccupants)
{
// get a car。
Car* pCar = GetAnewCar(nOccupants);

// Now drive to the store。
if(pCar)
{
pCar->Drive(Store);
}
// Now delete the object,returning the memory.
delete pCar;
}
使用new操作符構造的對象都應該用delete運算符刪除,這一點必須牢記。
返回對局部內存的引用
另一個常見的與內存有關的問題是從函數返回局部內存對象的地址。當函數返回時,對象不再有效。下一次調用某函數時,這個內存地址可能會被這個新函數使用。繼續使用這個內存指針就有可能會寫入新函數的局部內存。
這個常見問題以這種方式出現:
Car* GetAnewCar(int nOccupants)
{
Car* pCar;
if(nOccupants < 4)
{
pCar = &Car(2); // get a two-door.
}
else
{
pCar = &Car(4); // otherwise, a four-door.
}
return pCar;
}
請注重指針pCar怎樣被賦予由構造函數Car()建立的未命名對象的局部地址的。到目前為止,沒有問題。然而一旦函數返回這個地址,問題就產生了,因為在封閉的大括號處臨時對象會被析構。
使運算符混亂
C++從它的前輩C那里繼續了一套含義相當混亂模糊的運算符。再加上語法規則的靈活性,就使它很輕易對程序員造成混亂,使程序員去使用錯誤的運算符。
這個情況的最出名的例子如下:
if(nVal = 0)
{
// do something if nVal is nonzero.
} 更多文章 更多內容請看C/C++技術專題  Java編程開發手冊專題,或 程序員顯然想要寫if(nVal == 0)。不幸的是,上述語句是完全合法的,雖然沒有什么意義,C++語句將nVal賦值為0,然后檢查結果看看是否為非零(這是不可能發生的)。結果是大括號內的代碼永遠不會被執行。
其它幾對輕易弄錯的運算符是&和&&,以及/和//。
0的四種面孔
根據使用它的方式,常數0有四種可能的含義:
☆ 整數0
☆ 不能是對象地址的地址
☆ 邏輯FALSE
☆ 字符串的終結符
我可以向你證實這些含義的差別是很實際的。例如,下列賦值是合法的:
int *pInt;
pInt = 0;// this is leagal.
而下列賦值是不合法的:
int *pInt;
pInt = 1;// this is not.
第一個賦值是合法的,因為表中的第二定義:常數0可以是地址,然而常數1則不行。
這個含義的多重性能導致一些難以發現的錯誤:
// copy a string from pSource to pTarget -- incorrect version.
while(pSource)
{
*pTarget++ = *pSource++;
}
此例中的while循環試圖把由pSource指向的源字符串復制到由pTarget指向的內存塊。但不幸的是,條件寫錯了,它應這樣寫出:
// copy a string from pSource to pTarget -- incorrect version.
while(*pSource)
{
*pTarget++ = *pSource++;
}
你可以看到,當由pSource指向的字符為NULL時,終止條件出現。這是0的第四定義。然而,這里寫出的代碼卻是去查看地址pSource是否為零,這是第二定義。
最終結果是while()循環繼續寫入內存直到程序崩潰。
0的其他定義之間也可能產生混亂。唯一的解決辦法就是當你使用常數0的時候小心一點。
聲明的混亂處
復合聲明是非?;靵y的,但C++——以它的熱忱保持了與C的反向兼容性——但也產生了一些聲明間的矛盾,你必須避免這種矛盾。
class Myclass
{
public:
Myclass(int nArg1 = 0,int nArg2 = 0);
};
Myclass mcA(1,2);
Myclass mcB(1);
Myclass mcC();
mcA是參數1和2構成的對象,而mcB是參數1和0構成的對象。因此你可能認為mcC是參數0和0構成的對象,然而情況不是這樣。而mcC()是一個不帶參數的函數,它用數值返回類Myclass的對象。
另一個混亂產生于初始化運算符=的使用:
Myclass mcB = nA; // same as Myclass mcB(nA)

為了增強與C的兼容性,答應這樣使用=;然而你應該避免這種結構,因為它不是一貫適用的。例如下列程序就不會有預期的效果:
Myclass mcA = nA,nB;
這說明一個對象mcA(nA),它后面有一個獨立的使用缺省構造符的對象nB,而不是說明一個對象mcA(nA,nB)。
堅持使用C++格式——這是最安全的。 更多文章 更多內容請看C/C++技術專題  Java編程開發手冊專題,或 計算順序混亂
C和C++運算符的先后順序,使你能夠知道怎樣計算諸如下列表達式:
a = b * c + d;
然而先后次序不會影響子表達式的計算順序。讓我們以看上去不重要的方式改變示例的表達式:
a = b() * c() + d();
現在的問題是,在這個表達式中以什么樣的順序調用函數b(),c()和d()?答案是,順序是完全不確定的。更糟的是,順序不能借助圓括號的使用而確定。所以下列表達式沒有作用:
a = (b() * c()) + d();
函數計算順序通常不值得去關心。然而,假如這些函數有副作用,以某種方式彼此影響(稱為相互副作用),那么順序就是重要的了。例如,假如這些函數改變相同的全局變量,則結果就是不同的,這取決于其中函數被調用的順序。
甚至當不涉及函數調用時,相互副作用也會產生影響:
int nI = 0;
cout<<"nA[0]="<這個表達式的問題是單個表達式包含有相互副作用的兩個子表達式——變量nI是增量。哪個nA[nI++]首先被執行,左邊的nA[nI++]還是右邊的nA[nI++]?沒法說,上述代碼可能會以預期的方式工作,但也可能不會。
說明虛擬成員函數
為了在子類中重載虛擬成員函數,必須用和基本類中函數一樣的形式說明子類中函數的參數和返回類型。這并不總是清楚的。例如,下列代碼似乎講得通:
class Base
{
public:
virtual void AFunc(Base *pB);
};
class Subclass:public Base
{
public:
virtual void AFunc(Subclass *pS);
};
這個代碼會編譯通過,但不會有遲后聯編。函數Base::AFunc()的參數是Base*類型的,而函數Subclass::AFunc()的參數是Subclass*,它們是不同的。
這個規則的唯一例外是下面的例子,它符合ANSI C++標準:
class Base
{
public:
virtual void Base* AFunc();
};
class Subclass:public Base
{
public:
virtual void Subclass* AFunc();
};
在此例中,每個函數返回其固有類型對象的地址。這種技術很通用,所以標準委員會決定承認它。
從構造函數內調用虛擬成員函數
從構造符內調用虛擬函數是前期聯編的,這樣,它就短路掉了那些原本可能的簡潔的能力:
class Base
{
public:
Base();
virtual void BuildSection();
};
class Subclass:public Base
{
public:
Subclass();
virtual void BuildSection();
};
Base::Base()
{
BuildSection();
}; 更多文章 更多內容請看C/C++技術專題  Java編程開發手冊專題,或 在此例中,程序員希望構造函數能夠多態地調用BuildSection(),當正在構造的對象是Base對象時調用Base::BuildSection(),當對象是類Subclass對象時調用Subclass::BuildSection()。

由于下列簡單的原因這個例子不起作用:當調用BuildSection()完成時,正在構造的對象僅僅是一個Base對象。即使對象最終成為Subclass對象,也要等到Subclass的構造函數把它過一遍以后。在這些情況下調用Subclass::BuildSection()可能是致命的。即使對象將最終成為Subclass對象,但在調用BuildSection()的時候,對象只不過是Base對象,而且,這個調用必須要前期聯編到函數Base::BuildSection()。
指針對準
當你在80x86處理器(例如,你的PC機的芯片)上執行你的程序時,這個問題不是致命的,但對其他的絕大多數芯片來說,這就是致命的了。它還會對你的應用程序移植到某個其他環境的能力產生影響。此外,甚至對于Intel 處理器來說,這個問題也將導致低于標準的性能。
當你的指針從一種類型轉換到另一種類型的時候,就有可能產生一個非對準指針(misaligned pointer)。處理器一般要求內存塊的地址要與一個和這個內存塊的尺寸匹配的邊界對齊。例如,字只能在字邊界上被訪問(地址是二的倍數),雙字只能在雙字邊界上被訪問(地址是四的倍數),依次類推。
編譯器通常確保監視這個規則。但是當你的指針類型從一種類型轉換成較大類型時,你就可以很輕易地違反這個規則:
char cA;
char* pC = &cA;
int* pI;
pI = (int*)pC;
*pI = 0; // this may be fatal.
因為字符僅僅是一個字節長,所以地址&cA可能有任意值,包括奇數值??墒牵琾I應只包含四的倍數的地址。通過轉換,答應把pC賦給pI,但是假如地址不是四的倍數,則接著發生的賦值可能使程序崩潰。
對于Intel處理器來說,甚至當pC值為奇數時,該賦值也不是致命的;雖然占用的時間要長得多,但是賦值還是能夠正常執行。請你謹防非對準指針。
這種情況只在你正在把你的指針從指向一種類型轉換成指向較大類型時才會出現。[完] 更多文章 更多內容請看C/C++技術專題  Java編程開發手冊專題,或

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
乱亲女秽乱长久久久| 国产91成人video| 欧洲精品久久久| 久久成人亚洲精品| 国产中文字幕亚洲| 午夜欧美大片免费观看| 一区二区三区亚洲| 久久精品色欧美aⅴ一区二区| 狠狠干狠狠久久| 亚洲成av人片在线观看香蕉| 国产精品69久久| 久久亚洲欧美日韩精品专区| 日韩欧美视频一区二区三区| 日韩精品视频免费在线观看| 精品偷拍一区二区三区在线看| 精品久久久久久亚洲精品| 亚洲精品国偷自产在线99热| 久久福利视频网| 国产精品丝袜视频| 国产精品一区二区三区免费视频| 97欧美精品一区二区三区| 欧美日韩加勒比精品一区| 91香蕉电影院| 欧美性感美女h网站在线观看免费| 在线观看欧美www| 久久99视频免费| 97涩涩爰在线观看亚洲| 日韩av电影院| 欧美激情精品久久久久久免费印度| 最好看的2019的中文字幕视频| 日韩hd视频在线观看| 91国内揄拍国内精品对白| 亚洲国产欧美日韩精品| 欧美电影在线观看网站| 91手机视频在线观看| 欧美国产激情18| 5566日本婷婷色中文字幕97| 成人黄色生活片| 国产精品成人v| 久久久久久成人| 亚洲国产免费av| 亚洲精品不卡在线| 国产日产欧美a一级在线| 性欧美xxxx视频在线观看| 久久频这里精品99香蕉| 激情成人在线视频| 在线电影av不卡网址| 91中文精品字幕在线视频| 色综合色综合网色综合| 久久在线精品视频| 欧美夫妻性视频| 日韩av免费在线看| 欧美日韩美女视频| 国产精品第10页| 不卡毛片在线看| 不卡av电影院| 国产视频精品va久久久久久| 亚洲国产精品久久久久久| 中文字幕欧美精品在线| 亚洲精品欧美一区二区三区| 国产精品久久久久久中文字| 久久久久久国产三级电影| 日本午夜精品理论片a级appf发布| 成人激情av在线| 91精品国产高清自在线看超| 97精品国产97久久久久久免费| 91精品国产99| 91丨九色丨国产在线| 日韩中文在线视频| 日韩精品在线播放| 亚洲专区国产精品| 91po在线观看91精品国产性色| 国产丝袜精品第一页| 欧美大片免费观看| 一个人www欧美| 国产亚洲美女精品久久久| 97视频在线观看网址| 中国人与牲禽动交精品| 久99九色视频在线观看| 欧美黑人xxxⅹ高潮交| 国产欧美一区二区三区久久| 欧美日韩亚洲视频一区| 国产欧美日韩免费| 国产午夜精品美女视频明星a级| 午夜精品一区二区三区视频免费看| 91亚洲精华国产精华| 欧美一级视频在线观看| 国产日韩在线看| 综合激情国产一区| 国产日韩欧美电影在线观看| 91av免费观看91av精品在线| 欧美日韩第一视频| 亚洲一区二区三| 欧美精品一区二区免费| 国产日韩欧美在线播放| 97视频在线观看成人| 久久精品色欧美aⅴ一区二区| 日韩经典中文字幕在线观看| 国产日韩av在线播放| 欧美另类在线播放| 国产精品一区专区欧美日韩| www日韩欧美| 成人xvideos免费视频| 91中文字幕在线观看| 国产深夜精品福利| 欧美高清在线观看| 亚洲精品中文字幕有码专区| 欧美一级淫片播放口| 久久久www成人免费精品| 午夜精品美女自拍福到在线| 久久在线精品视频| 国产精品国语对白| 日韩午夜在线视频| 人人爽久久涩噜噜噜网站| 91久久久久久| 亚洲国产精品yw在线观看| 亚洲美女喷白浆| 综合av色偷偷网| 欧美黄色www| 国产亚洲视频在线观看| 欧美视频国产精品| 久久综合久久88| 在线看片第一页欧美| 日韩午夜在线视频| 欧美亚洲激情视频| 成人自拍性视频| 亚洲精品久久久久国产| 91在线视频精品| 国产精品扒开腿爽爽爽视频| 69国产精品成人在线播放| 久久人人爽亚洲精品天堂| 国产精品一久久香蕉国产线看观看| 欧美伊久线香蕉线新在线| 久久精品国产亚洲一区二区| 夜夜嗨av一区二区三区四区| 亚洲日本成人网| 亚洲性视频网址| 亚洲色图欧美制服丝袜另类第一页| 久久久久久久久久久国产| 亚洲欧美日韩区| 欧美体内谢she精2性欧美| 亚洲三级 欧美三级| 亚洲精选一区二区| 精品无人国产偷自产在线| 欧美日韩一区二区三区在线免费观看| 国产一区二区在线播放| 国产精品爱啪在线线免费观看| 欧美成人在线免费| 亚洲欧美日韩国产中文专区| 欧美成人h版在线观看| 精品国偷自产在线| 亚洲片国产一区一级在线观看| 热99久久精品| 午夜精品国产精品大乳美女| 日日骚av一区| 欧美小视频在线观看| 成人网页在线免费观看| 2019中文字幕在线观看| 韩国三级日本三级少妇99| 欧美人在线视频| 美女撒尿一区二区三区| 亚洲欧美在线磁力| 亚洲天堂男人天堂女人天堂| 亚洲精品小视频在线观看|