【问题标题】:Why can't I create copies of these 2D arrays in C?为什么我不能在 C 中创建这些二维数组的副本?
【发布时间】:2021-05-12 17:53:51
【问题描述】:

您好,我正在为哈佛 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;
}

我的第一个问题是为什么当我将 grayscale 函数中的 image[i][j].rgbtBlue = newgray; 替换为 pixel.rgbtBlue = newgray; 时它不起作用。像素变量不就是image[i][j]的副本吗?

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

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

输出:image

【问题讨论】:

  • “像素变量不就是图像[i][j]的副本”。不,它是 image[i][j] 值的副本。修改像素不会修改图像[i][j]
  • 这能回答你的问题吗? What's the difference between passing by reference vs. passing by value?(特别是那里的第二个答案)
  • 如果像素变黑,那是因为它们被设置为 0(至少,这是标准)
  • 临时数组不需要整个数组。只需使用一个变量。
  • 你确定 C 有二维数组吗?上次我阅读n1570 时没有它们(只是数组的数组)

标签: c computer-science cs50


【解决方案1】:

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;
        }
    }
}

【讨论】:

    【解决方案2】:

    至于你的第一个问题,这是因为像素只是 image[i][j] 的值副本。它有一个独立的内存位置,所以修改它不会改变图像[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]
    

    【讨论】:

      猜你喜欢
      • 2018-02-07
      • 1970-01-01
      • 1970-01-01
      • 2021-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多