进行棕褐色过滤时,会弹出错误消息,这意味着什么? C

时间:2020-08-18 13:27:13

标签: c cs50

我尝试下一个请求的过滤器,再次遇到问题。该代码只编译一次,但是在棕褐色中运行该程序时会出现错误消息。其如下:

helpers.c:31:29:运行时错误:259.821超出了'unsigned char'类型的可表示值的范围

现在我知道这意味着已超出255的限制(并且不起作用),所以我写了一条if else语句,因为指令是:

“公式的结果也有可能是大于255的数字,这是8位颜色值的最大值。在这种情况下,红色,绿色和蓝色值的上限应为255。结果,我们可以保证所得的红色,绿色和蓝色值将是0到255之间的整数(包括0和255)。“

但是这会导致另一个错误提示:

通过“未声明的标识符”,lang意味着您在helpers.c的第57行中使用了未定义的名称sepiaBlue。如果您打算将sepiaBlue用作变量,请确保通过指定其类型来声明它,并检查变量名是否拼写正确。

但是我将sepiaBlue设为了float变量。这是我的代码:

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 rgbt = image[i][j];
        if(rgbt.rgbtRed > 255)
        {
            rgbt.rgbtRed = 255;
        }
        else
        {
            float sepiaRed = .393 * rgbt.rgbtRed + .769 * rgbt.rgbtGreen + .189 * rgbt.rgbtBlue;
        }
        
        if(rgbt.rgbtGreen > 255)
        {
            rgbt.rgbtGreen = 255;
        }
        else
        {
            float sepiaGreen = .349 * rgbt.rgbtRed + .686 * rgbt.rgbtGreen + .168 * rgbt.rgbtBlue;
        }
        if(rgbt.rgbtBlue > 255)
        {
            rgbt.rgbtBlue = 255;
        }
        else
        {
            float sepiaBlue = .272 * rgbt.rgbtRed + .534 * rgbt.rgbtGreen + .131 * rgbt.rgbtBlue;
        }
        
        rgbt.rgbtBlue = sepiaBlue;
        rgbt.rgbtGreen = sepiaGreen;
        rgbt.rgbtRed =  sepiaRed;
        image[i][j] = rgbt;
    }
  }
  return;
}

再次感谢(我认为我的大脑今天不能正常工作!)

4 个答案:

答案 0 :(得分:1)

首先,如前所述,您已经在一个块的本地范围内定义了sepiaRedsepiaGreensepiaBlue,当您尝试在该块之外访问该块时,将无法访问该块

所有范围检查均无效。看看这种情况:

if(rgbt.rgbtRed > 255)
{
   rgbt.rgbtRed = 255;
}
else
{
   sepiaRed = .393 * rgbt.rgbtRed + .769 * rgbt.rgbtGreen + .189 * rgbt.rgbtBlue;
}

该条件永远不会为真,因为rgbt.rgbtRedBYTE,它是8位unsigned char值。因此,它的值不能大于255。您需要在计算后 进行范围检查。

真的,您可以像这样重写内部循环中的所有内容:

RGBTRIPLE rgbt = image[i][j];
float red   = .393 * rgbt.rgbtRed + .769 * rgbt.rgbtGreen + .189 * rgbt.rgbtBlue;
float green = .349 * rgbt.rgbtRed + .686 * rgbt.rgbtGreen + .168 * rgbt.rgbtBlue
float blue  = .272 * rgbt.rgbtRed + .534 * rgbt.rgbtGreen + .131 * rgbt.rgbtBlue;

image[i][j].rgbtRed   = min(red, 255);
image[i][j].rgbtGreen = min(green, 255);
image[i][j].rgbtBlue  = min(blue, 255);

这要简单得多,而且应该可以工作。

答案 1 :(得分:0)

sepiaBlue 的范围是您定义它的else块。

在块外,变量未定义。

在函数开头声明局部变量。

答案 2 :(得分:0)

在不了解所有结构变量的情况下,这是“未声明的标识符”的解决方案。

观察到我刚刚在与使用sepiaRedsepiaGreensepiaBlue设置rgbt值的范围内声明了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 rgbt = image[i][j]; float sepiaRed, sepiaGreen, sepiaBlue; if(rgbt.rgbtRed > 255) { rgbt.rgbtRed = 255; } else { sepiaRed = .393 * rgbt.rgbtRed + .769 * rgbt.rgbtGreen + .189 * rgbt.rgbtBlue; } if(rgbt.rgbtGreen > 255) { rgbt.rgbtGreen = 255; } else { sepiaGreen = .349 * rgbt.rgbtRed + .686 * rgbt.rgbtGreen + .168 * rgbt.rgbtBlue; } if(rgbt.rgbtBlue > 255) { rgbt.rgbtBlue = 255; } else { sepiaBlue = .272 * rgbt.rgbtRed + .534 * rgbt.rgbtGreen + .131 * rgbt.rgbtBlue; } rgbt.rgbtBlue = sepiaBlue; rgbt.rgbtGreen = sepiaGreen; rgbt.rgbtRed = sepiaRed; image[i][j] = rgbt; } } return; } ,{{1}},{{1}}。您已经在if else语句中声明了它们,因此在保留if else语句时它们将不存在。

{{1}}

答案 3 :(得分:0)

通过编译器运行发布的代码会导致:

gcc -ggdb3 -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c "untitled1.c" -o "untitled1.o" 

untitled1.c: In function ‘sepia’:

untitled1.c:20:25: warning: comparison is always false due to limited range of data type [-Wtype-limits]
   20 |         if(rgbt.rgbtRed > 255)
      |                         ^

untitled1.c:26:30: warning: conversion from ‘double’ to ‘float’ may change value [-Wfloat-conversion]
   26 |             float sepiaRed = .393 * rgbt.rgbtRed + .769 * rgbt.rgbtGreen + .189 * rgbt.rgbtBlue;
      |                              ^~~~

untitled1.c:26:19: warning: unused variable ‘sepiaRed’ [-Wunused-variable]
   26 |             float sepiaRed = .393 * rgbt.rgbtRed + .769 * rgbt.rgbtGreen + .189 * rgbt.rgbtBlue;
      |                   ^~~~~~~~

untitled1.c:29:27: warning: comparison is always false due to limited range of data type [-Wtype-limits]
   29 |         if(rgbt.rgbtGreen > 255)
      |                           ^

untitled1.c:35:32: warning: conversion from ‘double’ to ‘float’ may change value [-Wfloat-conversion]
   35 |             float sepiaGreen = .349 * rgbt.rgbtRed + .686 * rgbt.rgbtGreen + .168 * rgbt.rgbtBlue;
      |                                ^~~~

untitled1.c:35:19: warning: unused variable ‘sepiaGreen’ [-Wunused-variable]
   35 |             float sepiaGreen = .349 * rgbt.rgbtRed + .686 * rgbt.rgbtGreen + .168 * rgbt.rgbtBlue;
      |                   ^~~~~~~~~~

untitled1.c:37:26: warning: comparison is always false due to limited range of data type [-Wtype-limits]
   37 |         if(rgbt.rgbtBlue > 255)
      |                          ^

untitled1.c:43:31: warning: conversion from ‘double’ to ‘float’ may change value [-Wfloat-conversion]
   43 |             float sepiaBlue = .272 * rgbt.rgbtRed + .534 * rgbt.rgbtGreen + .131 * rgbt.rgbtBlue;
      |                               ^~~~

untitled1.c:43:19: warning: unused variable ‘sepiaBlue’ [-Wunused-variable]
   43 |             float sepiaBlue = .272 * rgbt.rgbtRed + .534 * rgbt.rgbtGreen + .131 * rgbt.rgbtBlue;
      |                   ^~~~~~~~~

untitled1.c:46:25: error: ‘sepiaBlue’ undeclared (first use in this function)
   46 |         rgbt.rgbtBlue = sepiaBlue;
      |                         ^~~~~~~~~

untitled1.c:46:25: note: each undeclared identifier is reported only once for each function it appears in
untitled1.c:47:26: error: ‘sepiaGreen’ undeclared (first use in this function)
   47 |         rgbt.rgbtGreen = sepiaGreen;
      |                          ^~~~~~~~~~

untitled1.c:48:25: error: ‘sepiaRed’ undeclared (first use in this function); did you mean ‘sepia’?
   48 |         rgbt.rgbtRed =  sepiaRed;
      |                         ^~~~~~~~
      |                         sepia

Compilation failed.

要解决这些问题:

float文字以f结尾,没有f的结果是double文字。

这些变量的范围受最近的括号{}限制。建议在sepia()函数顶部声明变量。

陈述,例如:

if(rgbt.rgbtRed > 255)

由于未签名的char的范围为0 ... 255,因此始终为false,因此永远不能大于255。

以下建议的代码:

  1. 干净地编译
  2. 执行所需的功能

现在,建议的代码:

typedef unsigned char BYTE;

typedef struct tagRGBTRIPLE 
{
  BYTE rgbtBlue;
  BYTE rgbtGreen;
  BYTE rgbtRed;
} RGBTRIPLE;
    


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 rgbt = image[i][j];
        //if(rgbt.rgbtRed > 255)
        ///{
        //    rgbt.rgbtRed = 255;
        //}
        //else
        //{
        float sepiaRed = .393f * rgbt.rgbtRed + .769f * rgbt.rgbtGreen + .189f * rgbt.rgbtBlue;
        //}
        
        //if(rgbt.rgbtGreen > 255)
        //{
        //   rgbt.rgbtGreen = 255;
        //}
        //else
        //{
        float sepiaGreen = .349f * rgbt.rgbtRed + .686f * rgbt.rgbtGreen + .168f * rgbt.rgbtBlue;
        //}
        //if(rgbt.rgbtBlue > 255)
        //{
        //    rgbt.rgbtBlue = 255;
        //}
        //else
        //{
        float    sepiaBlue = .272f * rgbt.rgbtRed + .534f * rgbt.rgbtGreen + .131f * rgbt.rgbtBlue;
        //}
        
        rgbt.rgbtBlue  = ( (BYTE)sepiaBlue  > 255 )? 255 : (BYTE)sepiaBlue;
        rgbt.rgbtGreen = ( (BYTE)sepiaGreen > 255 )? 255 : (BYTE)sepiaGreen;
        rgbt.rgbtRed   = ( (BYTE)sepiaRed   > 255 )? 255 : (BYTE)sepiaRed;
        image[i][j] = rgbt;
    }
  }
  return;
}