簡體   English   中英

為什么可以在嵌套循環中聲明STRUCT呢?

[英]Why is it okay to declare a STRUCT inside a nested loop?

這是一些提供的(CS50)代碼的片段,這些代碼在嵌套循環中一遍又一遍地聲明相同的STRUCT“三元組”。 為什么這樣可以呢? 在我看來,將STRUCT“三元組”聲明為嵌套循環的范圍上方並在每次迭代中更改值會更有效。

typedef struct
{
    BYTE rgbtBlue;
    BYTE rgbtGreen;
    BYTE rgbtRed;
} __attribute__((__packed__))
RGBTRIPLE;

 for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
{
    // iterate over pixels in scanline
    for (int j = 0; j < bi.biWidth; j++)
    {
        // temporary storage
        RGBTRIPLE triple;

        // read RGB triple from infile
        fread(&triple, sizeof(RGBTRIPLE), 1, inptr);

        // write RGB triple to outfile
        fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
    }

在大多數情況下,此級別的效率是編譯器關心的問題。 編譯器可以為每個RGBTRIPLE重新使用相同的堆棧空間! (盡管不是必須的。)

將RGBTRIPLE放在需要它的最小括號對(范圍)內,可以防止您在變量內容可能無效時意外,錯誤地訪問該范圍之外的變量。

還有,同一聲明的數千次迭代是否比第一個循環之前的單個聲明要好?

當然可以。 無論哪種方式,好的編譯器都不會發出具有任何性能差異的代碼。

進行適度的線性性能更改的原因可能是減少了fread()調用次數。

for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++) {
    RGBTRIPLE triple[bi.biWidth];
    fread(triple, sizeof triple, 1, inptr);
    fwrite(triple, sizeof triple, 1, outptr);
}

甚至

RGBTRIPLE triple[biHeight][bi.biWidth];
fread(triple, sizeof triple, 1, inptr);
fwrite(triple, sizeof triple, 1, outptr);

許多因素都需要考慮編碼。 避免專注於此類微優化。

這里要理解的重要一點是,語句RGBTRIPLE triple; 聲明變量,但不直接對應於“正在創建存儲”,或者根本不轉換為任何機器語言輸出。

您只是向編譯器聲明此變量的范圍和用法(並且在最局部的塊內進行聲明是一種僅表示您希望該變量在該區域內有效的良好做法)。 您可以將此行放在循環之外或函數的頂部,而無需更改可執行輸出。

編譯器的工作是在堆棧上有效地創建空間,以便在運行時使用局部變量。 實際上,它將簡單地重復使用相同的空間來進行每次循環迭代。 (這里的人會告訴你,正確的,這是沒有保證的 ,行為在技術上是真實的,但在實踐中,總是會重復使用相同的空間,如果你宣布它的循環以上。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM