C++與C的一個最大的不同的是C要求所有變量要在最開始的就聲明,而C++的變量是信手拈來,想用才聲明。這個簡單的細節其實隱含了C與C++的設計邏輯有所區別。
C設計的時候其實更多是為編譯器考慮問題,當所有變量在使用之前就聲明的話,編譯器更容易處理這些變量。在開始的時候就把他們都寫入符號表中,在程序執行的時候直接查看符號表即可。然而C++設計的時候對安全性特別關注,對於類,它是有構造與析構處理的。而構造函數有時是需要參數,我們在程序的最開始其實我們不一定很清楚參數的值。這就要求變量的聲明不能只放在函數的最開始,而是能夠做到使用時再聲明,C++也的確做到這一點。
這個使用時才聲明是極其方便,我們最常用的一個例子是在循環裡面使用。像for(int i=0; i<10; i++) ...
這種臨時性的工作在for裡面定義是再好不過的。對於一個循環裡面定義的變量,其生命周期是for循環,這是標准C++的定義。然而編譯器對for循環裡面變量的處理卻是不一致的。
對於VC6.0,下面的代碼是錯誤的。
for(int i=0; i<10; i++) sum += i;
for(int i=0; i<10; i++) sum += i;
編譯器會給出如下提示:error C2374: 'i' : redefinition; multiple initialization
錯誤時變量i重復生命力額,原因很簡單,VC在實現變量i的聲明周期是遇到右大括號“}”才結束其定義的。所以上面的程序要改成:
{
for(int i=0; i<10; i++) sum += i;
}
for(int i=0; i<10; i++) sum += i;
才能過編譯器那一關。
這一點也讓很多程序員犯暈,在鼓勵要用才聲明的C++裡面,竟然會存在for循環的重復定義。如果使用,
for(int i=0; i<10; i++) sum += i;
for(i=0; i<10; i++) sum += i;
的話,這跟我們的邏輯又混亂了,在循環裡面聲明,卻在循環外面使用。如果加上大括號又讓程序顯得特別奇怪。只能說,這是編譯器的錯,不是人的錯,因為這兩種選擇都不是很合理。
其實這跟早期編譯器實現方式相關,筆者試了最新版本的G++編譯器,上面的兩段代碼都沒有問題。即for循環裡面的變量的生存周期只在for裡面有效。VC6.0的這種錯誤只能說它並不是一個標准的C++編譯器。