为什么我不能在 C 中创建这些二维数组的副本?

Why can't I create copies of these 2D arrays in C?

你好,我正在做哈佛 CS50 的作业,如果你想回答这个问题,请阅读 directions

这是我的 helpers.c

代码
#include "helpers.h"
#include <math.h>

// Convert image to grayscale
void grayscale(int height, int width, RGBTRIPLE image[height][width])
{
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            RGBTRIPLE pixel = image[i][j];

            int newgray = round((pixel.rgbtBlue + pixel.rgbtGreen + pixel.rgbtRed)/ 3.00);
            image[i][j].rgbtBlue = newgray;
            image[i][j].rgbtGreen = newgray;
            image[i][j].rgbtRed = newgray;
        }
    }
    return;
}
// Convert image to sepia
void sepia(int height, int width, RGBTRIPLE image[height][width])
{
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            RGBTRIPLE pixel = image[i][j];

            //Reassign pixel colors based on formula
            image[i][j].rgbtRed = .393 * pixel.rgbtRed + .769 * pixel.rgbtGreen + .189 * pixel.rgbtBlue;
            image[i][j].rgbtGreen = .349 * pixel.rgbtRed + .686 * pixel.rgbtGreen + .168 * pixel.rgbtBlue;
            image[i][j].rgbtBlue = .272 * pixel.rgbtRed + .534 * pixel.rgbtGreen + .131 * pixel.rgbtBlue;
        }
    }
    return;
}

// Reflect image horizontally
void reflect(int height, int width, RGBTRIPLE image[height][width])
{
    RGBTRIPLE temp[height][width];
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width/2; j++)
        {
            temp[i][j] = image[i][j];
            int reflected_j = width - j;
            image[i][reflected_j] = image[i][j];
            image[i][j] = temp[i][j];
        }
    }
    return;
}

// Blur image
void blur(int height, int width, RGBTRIPLE image[height][width])
{
    return;
}

我的第一个问题是为什么当我将灰度函数中的image[i][j].rgbtBlue = newgray;替换为pixel.rgbtBlue = newgray; 没用。像素变量不是 image[i][j].

的副本吗

我的第二个问题在于反射函数,我在其中制作RGBTRIPLE temp[height][width];(RGBTRIPLE是一个使用1字节的数据结构对于图像图片中的每种 RGB 颜色)并将其指定为复制原始图像的像素。我这样做是为了复制图片的前半部分并将其从原始图像反射到另一侧,然后从副本(temp)复制后半部分并将其粘贴到前半部分原始图像。为什么前半部分(左半部分)显示为黑色?

输入:image,终端命令./filter -r tower.bmp outfile.bmp (tower.bmp为输入图像,outfile为输出图像)

输出:image

关于你的第一个问题,是因为pixel只是image[i][j]的值拷贝。它有自己独立的内存位置,所以修改它不会改变 image[i][j].
至于你的第二个问题,是因为这一行

image[i][reflected_j] = image[i][j];

应该是

image[i][j]=image[i][reflected_j]

和这一行

image[i][j] = temp[i][j];

应该是

image[i][reflected_j]=temp[i][j]

reflect() 存在一些问题。

  1. 一次只使用 temp 的一个元素,并且永远不会重复使用。因此不需要在堆栈上创建一个潜在的巨大实例。
  2. j 的索引 reflected_j = width - j 等于 0 将等于 width 长度数组 width 的超出范围。这会调用 UB。应该是reflected_j = width - j - 1
  3. 反射图像时交换像素会更好,不要玩半拷贝。

更新代码:

void reflect(int height, int width, RGBTRIPLE image[height][width]) {
    for (int y = 0; y < height; y++) {
        for (int i = 0, j = width - 1; i < j; i++, j--) {
            RGBTRIPLE temp = image[y][i];
            image[y][i] = image[y][j];
            image[y][j] = temp;
        }
    }
}