繁体   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