c++基礎3:關於前置++和後置++的那麼點糾結

STL基礎6:list容器的使用總結曾經討論過前置++和後置++最本質的區別:

前置++返回的就是操作數自增後的結果

int a=5;
int b=++a;//該表達式執行後b=6,a=6

後置++返回的是操作數的一個副本(未自增操作數的值),然而操作數本身已經調用前置++的方法自增

int a=5;
int b=a++;//該表達式執行後b=5,a=6

兩者比較總結:

前置++的效率更高,後置++效率低(內部實現不僅拷貝了一份原始操作數的副本而且還調用了前置++進行操作數自增,然後返回元素操作數的副本)。所以如果不是特別需求的話就一律用前置++,保持這個習慣,當然,後置++也是有用武之地的,如下。

後置++的應用:

後置++操作符返回的是未加1的值,所以我們需要在單個複合表達式使用操作數自增前的原始值,然後在自增,那麼就必須使用後置++。

例如1:依次刪除lisDeleted1裏的所有元素

for(List_Iter iter=lisDeleted1.begin();iter!=lisDeleted1.end();)  
{  
    lisDeleted1.erase(iter++);        
}


如果在for中使用lisDeleted1.erase(iter);iter++;這樣的代碼,那麼迭代器iter在第一次使用erase刪除後就會失效,然後使用失效的迭代器++就會造成程序報錯,如果使用上面的一條複合表達式lisDeleted1.erase(iter++);這句話的解釋是:erase刪除的是iter++,也就是iter的副本,這句話執行完後然後iter本身其實已經在iter++的時候自增了,然後進行比較iter!=lisDeleted1.end(),所以這時候使用後置++

例如2:使用後置++將10個元素0--9添加到向量vector中

vector<int> ivec;
int cnt=0;
while(cnt<10)
{
	ivec.push_back(cnt++);
	/*ivec.push_back(cnt);
	cnt++;*/ //可以,麻煩
	//ivec.push_back(++cnt);//錯,不行
}

如果這個時候使用前置++,ivec.push_back(++cnt);那麼第一個元素0就不能添加到vector中,添加進去的是元素10,所以不能達到想要的效果

多個前置++相加和多個後置++相加又或者多個前置++和多個後置++混合相加的糾結:

如:

int a=5;
int b=(a++)+(a++)+(a++)+(a++)+(a++);
a=5;
b=(a++)+(++a)+(a++)+(++a)+(a++)+(++a);
a=1;
b=(++a)+(++a)+(++a)+(++a)+(++a)+(++a);

這些混合或者單個類型的相加,每個編譯器相加的規則不一樣,所以得到的值有可能出乎程序員能掌握的範疇。
克服這類副作用的方法是,儘量把程序寫得易懂一些,即將費解處分解成若干個語句。如:k=i+++j:可寫成k=i+j:i++:而類似(i++)+(i++)+(i++)這類連續自增、自減的運算最好不要使用,以避免疑團的出現,同時也可減少程序出錯的可性能。在程序設計中,效率和易讀性是一對主要矛盾。爲了提高程序的效率,需要用技巧把程序寫得儘可能簡潔一些,但這樣有可能降低程序的可讀性和可理解性。可讀性差的程序容易隱藏錯誤且難於糾正,不易維護,降低了程序的可靠性。鑑於“軟件危機”的教訓,人們在程序設計時遵守的基本規範是:可靠性第一,效率第二。爲了保證可靠性,程序必須清晰易讀,而表達式的清晰易讀是十分重要的方面。因此,在C程序設計中,要慎重使用自增、自減運算符,特別是在一個表達式中不要多處出現變量的自增、自減等運算。

 

延伸,趣味話題:

你認爲爲什麼c++不叫做++c???

"++"是c語言的自增操作符。c++是c語言的超集,是在c語言的基礎上進行的擴展,所以是先有c語言,然後進行++的。根據自增操作符的前++和後++的區別,c++表示對c語言進行擴展之後,還是c的一個副本,還可以使用c語言的內容;而寫成++c表示無法在使用c的原始值了,也就是說c++不能使用c了,這與實際情況不符合。

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章