PSET4:过滤器(少)
PSET4: Filter(less)
我正在尝试 Pset4 的过滤器问题(不太舒服)。我在下面写了这段代码来反映图像。但它根本不起作用。但是编译没问题。
// Reflect image horizontally
void reflect(int height, int width, RGBTRIPLE image[height][width])
{
for (int i = 0; i < height; i++) //for rows
{
int start = 0;
for (int end = width; end > 0; end--)
{
BYTE tempR, tempB, tempG;
if(start < end)
{
tempR = image[i][start].rgbtRed;
tempB = image[i][start].rgbtBlue;
tempG = image[i][start].rgbtGreen;
image[i][start].rgbtRed = image[i][end].rgbtRed;
image[i][start].rgbtBlue = image[i][end].rgbtBlue;
image[i][start].rgbtGreen = image[i][end].rgbtGreen;
image[i][end].rgbtRed = tempR;
image[i][end].rgbtBlue = tempB;
image[i][end].rgbtGreen = tempG;
start += 1;
}
}
}
return;
}
在我看到评论之前,根据代码,这看起来像是“反转[光栅]线上所有像素的顺序”。
几个问题...
end
应该从 width - 1
开始 [并且 而不是 width
]。它从行中最后一个像素 过去 处开始(即 下一个 行的第一个像素)。对于最后一行,这是 UB [未定义的行为]。
因此,效果是移动了一个像素,我敢打赌该行的第一个和最后一个像素看起来“很有趣”...
内部循环条件应该是start < end
而不是end > 0
,我们应该完全消除if (start < end)
。
除了正确性之外,这还将消除最后 50% 的内部循环。那些 不是 传输数据 [因为 if
会变成假,并且在该行的其余部分仍然如此]。因此,循环进行了两倍的循环迭代(即)只有第一次迭代做了有用的工作。
换句话说,内部 for
循环进行了 width
次迭代而不是 width / 2
次迭代。
这是清理和更正后的代码:
// Reflect image horizontally
void
reflect(int height, int width, RGBTRIPLE image[height][width])
{
// for rows
for (int i = 0; i < height; i++) {
int start = 0;
for (int end = width - 1; start < end; --end, ++start) {
BYTE tempR, tempB, tempG;
tempR = image[i][start].rgbtRed;
tempB = image[i][start].rgbtBlue;
tempG = image[i][start].rgbtGreen;
image[i][start].rgbtRed = image[i][end].rgbtRed;
image[i][start].rgbtBlue = image[i][end].rgbtBlue;
image[i][start].rgbtGreen = image[i][end].rgbtGreen;
image[i][end].rgbtRed = tempR;
image[i][end].rgbtBlue = tempB;
image[i][end].rgbtGreen = tempG;
}
}
}
虽然优化器可能从上面生成高效的代码,这里有一个版本,其中start
和end
是指针。这样编译器更容易看出意图,也更简单易读:
// Reflect image horizontally
void
reflect(int height, int width, RGBTRIPLE image[height][width])
{
// for rows
for (int i = 0; i < height; i++) {
RGBTRIPLE *start = &image[i][0];
RGBTRIPLE *end = &image[i][width - 1];
for (; start < end; --end, ++start) {
BYTE tempR, tempB, tempG;
tempR = start->rgbtRed;
tempB = start->rgbtBlue;
tempG = start->rgbtGreen;
start->rgbtRed = end->rgbtRed;
start->rgbtBlue = end->rgbtBlue;
start->rgbtGreen = end->rgbtGreen;
end->rgbtRed = tempR;
end->rgbtBlue = tempB;
end->rgbtGreen = tempG;
}
}
}
我正在尝试 Pset4 的过滤器问题(不太舒服)。我在下面写了这段代码来反映图像。但它根本不起作用。但是编译没问题。
// Reflect image horizontally
void reflect(int height, int width, RGBTRIPLE image[height][width])
{
for (int i = 0; i < height; i++) //for rows
{
int start = 0;
for (int end = width; end > 0; end--)
{
BYTE tempR, tempB, tempG;
if(start < end)
{
tempR = image[i][start].rgbtRed;
tempB = image[i][start].rgbtBlue;
tempG = image[i][start].rgbtGreen;
image[i][start].rgbtRed = image[i][end].rgbtRed;
image[i][start].rgbtBlue = image[i][end].rgbtBlue;
image[i][start].rgbtGreen = image[i][end].rgbtGreen;
image[i][end].rgbtRed = tempR;
image[i][end].rgbtBlue = tempB;
image[i][end].rgbtGreen = tempG;
start += 1;
}
}
}
return;
}
在我看到评论之前,根据代码,这看起来像是“反转[光栅]线上所有像素的顺序”。
几个问题...
end
应该从 width - 1
开始 [并且 而不是 width
]。它从行中最后一个像素 过去 处开始(即 下一个 行的第一个像素)。对于最后一行,这是 UB [未定义的行为]。
因此,效果是移动了一个像素,我敢打赌该行的第一个和最后一个像素看起来“很有趣”...
内部循环条件应该是start < end
而不是end > 0
,我们应该完全消除if (start < end)
。
除了正确性之外,这还将消除最后 50% 的内部循环。那些 不是 传输数据 [因为 if
会变成假,并且在该行的其余部分仍然如此]。因此,循环进行了两倍的循环迭代(即)只有第一次迭代做了有用的工作。
换句话说,内部 for
循环进行了 width
次迭代而不是 width / 2
次迭代。
这是清理和更正后的代码:
// Reflect image horizontally
void
reflect(int height, int width, RGBTRIPLE image[height][width])
{
// for rows
for (int i = 0; i < height; i++) {
int start = 0;
for (int end = width - 1; start < end; --end, ++start) {
BYTE tempR, tempB, tempG;
tempR = image[i][start].rgbtRed;
tempB = image[i][start].rgbtBlue;
tempG = image[i][start].rgbtGreen;
image[i][start].rgbtRed = image[i][end].rgbtRed;
image[i][start].rgbtBlue = image[i][end].rgbtBlue;
image[i][start].rgbtGreen = image[i][end].rgbtGreen;
image[i][end].rgbtRed = tempR;
image[i][end].rgbtBlue = tempB;
image[i][end].rgbtGreen = tempG;
}
}
}
虽然优化器可能从上面生成高效的代码,这里有一个版本,其中start
和end
是指针。这样编译器更容易看出意图,也更简单易读:
// Reflect image horizontally
void
reflect(int height, int width, RGBTRIPLE image[height][width])
{
// for rows
for (int i = 0; i < height; i++) {
RGBTRIPLE *start = &image[i][0];
RGBTRIPLE *end = &image[i][width - 1];
for (; start < end; --end, ++start) {
BYTE tempR, tempB, tempG;
tempR = start->rgbtRed;
tempB = start->rgbtBlue;
tempG = start->rgbtGreen;
start->rgbtRed = end->rgbtRed;
start->rgbtBlue = end->rgbtBlue;
start->rgbtGreen = end->rgbtGreen;
end->rgbtRed = tempR;
end->rgbtBlue = tempB;
end->rgbtGreen = tempG;
}
}
}