我尝试下一个请求的过滤器,再次遇到问题。该代码只编译一次,但是在棕褐色中运行该程序时会出现错误消息。其如下:
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;
}
再次感谢(我认为我的大脑今天不能正常工作!)
答案 0 :(得分:1)
首先,如前所述,您已经在一个块的本地范围内定义了sepiaRed
,sepiaGreen
和sepiaBlue
,当您尝试在该块之外访问该块时,将无法访问该块
所有范围检查均无效。看看这种情况:
if(rgbt.rgbtRed > 255)
{
rgbt.rgbtRed = 255;
}
else
{
sepiaRed = .393 * rgbt.rgbtRed + .769 * rgbt.rgbtGreen + .189 * rgbt.rgbtBlue;
}
该条件永远不会为真,因为rgbt.rgbtRed
是BYTE
,它是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)
在不了解所有结构变量的情况下,这是“未声明的标识符”的解决方案。
观察到我刚刚在与使用sepiaRed
,sepiaGreen
,sepiaBlue
设置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。
以下建议的代码:
现在,建议的代码:
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;
}