2011-01-06 169 views
1

這似乎是一個簡單的問題,但它對我來說並不直觀。定義循環中的數據類型

說你有一個這樣的循環:

int i; 
for(i=0;i<10;i++){ 
float b = 25.2; 
float c; 
c=b+i; 
} 

是否有在每一個循環定義B中漂浮的任何負面後果呢?我認爲這將有,但我不敢肯定,因爲我已經看到了這個代碼工作...

謝謝...

回答

5

這是完全沒問題的,事實上我認爲它在任何像樣的編譯器中都不重要,如果你只在循環內部使用float

代碼的清晰度將其置於循環中確實有意義,但這主要是品味問題。

但要注意的情況下,像

int i,j; 
for (i=0;i<count;i++) 
{ 
    int j; 
    // stuff 
} 

我已經看到了類似的情況不會產生編譯器警告,這使得很難追查錯誤。

編輯只是測試,gcc並編譯不同,但與-O3所產生的組件是相同的。用gcc -S file.c進行測試。更新:-O1就夠了,它實際上取決於你聲明變量的順序。如果在您的示例中floatint i;之下聲明,編譯後的程序集仍然是相同的。

+0

這是-03和-01是什麼? – 2011-01-06 23:12:03

+0

@O_O:GCC中的優化級別,'-O1'到'-O3'(這是字母O,不是數字0)告訴編譯器將代碼從「一點點」優化到「相當多」。 `-Os`指示編譯器針對代碼大小進行優化。請參閱http://stackoverflow.com/questions/1778538/how-many-gcc-optimization-levels-are-there – nmichaels 2011-01-06 23:16:47

+0

這些是優化標誌。數字越高,技巧就越多。但是這些技巧也可能有缺點:優化程序集可能會更快,但也會更大,並且調試(高度)優化的代碼可能更難,因爲與C代碼的1:1關係更遠。 – mvds 2011-01-06 23:20:15

1

假設編譯器在這裏不優化,有一個小在分配每個循環的浮動時支付的罰款。在循環之外聲明float可能會更好。

它依賴於代碼。有時,像這樣聲明變量更清晰。你在演出中付出的代價可能很小。

0

你不初始化b,所以你使用它來調用未定義的行爲。

如果您擔心性能問題,編譯器可能會優化分配。

+0

oops,編輯代碼,將b的初始化固定爲一個值。 – 2011-01-06 23:15:10

-2

如果定義在一個塊(東西括在大括號),一個變量,它只是限制了它的範圍,你可以」在外面使用它。它只是使程序更清潔。

程序可能在開始的時候在堆棧上分配變量並在關閉時丟棄,但是一個好的編譯器應該在進入和離開子程序(方法)時執行它。另外,它是一個C++特性,對於結構良好的編程來說非常重要(它還使得C++編程有點像使用腳本語言,在這裏你不需要聲明變量,但是不需要聲明變量,但是不需要聲明變量,但是不需要聲明變量,但是不需要告訴認真的C或Java程序員)。

3

在編譯器之前,每次迭代通常會使用相同的堆棧空間,因此在循環中聲明變量實際上沒有性能影響,因爲在連續迭代期間不需要分配更多堆棧空間。我想像C99編譯器做類似的事情,但我不知道。

大多數編譯器只會優化它。最糟糕的情況是你正在堆棧上創建一個新的浮點數,這在大多數架構上都是非常便宜的操作。在使用之前立即聲明變量甚至可能會更快。但是,如果你的程序對性能敏感,那麼你應該首先使用匯編語言。

C99和更高版本指定變量的作用域爲它們在其中創建的循環,而早期版本的C不明確。不同的編譯器實現它的方式不同這一點很重要,因爲如果在包含循環的函數的作用域中存在一個相同名稱的變量(因爲它們會將該變量視爲該函數的作用域),那麼可能會碰到C99之前的編譯器的命名衝突。

就我個人而言,我一直聲明變量循環。它表現良好,清楚地表明變量存在於該循環中。這是以一種明確表示代碼意圖的方式來構建代碼的問題。