在代码中没有明显划分的情况下除以零故障
Divide by zero fault where there is no apparent division in code
以下代码来源于一个问题here。 (我知道代码有几个逻辑问题,但我不明白它们是如何导致这个问题的。)
编辑: 我在 Windows 上使用 CLANG,显示编译时的常见警告。
它在指示的行(for 循环中的第一个语句。)生成一个被零除的错误,但没有明显的 除。任何人都可以提供一些关于为什么会发生此错误的见解吗?
编辑 2: 根据评论:将 sepia
函数中的第三个参数从
更改为
void sepia(int height, int width, RGBTRIPLE image[height][width])
到
void sepia(int height, int width, RGBTRIPLE image[3][4])
消除除以零的错误。为什么?
typedef struct {
double rgbtRed;
double rgbtGreen;
double rgbtBlue;
}RGBTRIPLE;
RGBTRIPLE image[3][4];
void sepia(int height, int width, RGBTRIPLE image[height][width])
{
double sepiaRed = 0.0;
double sepiaGreen = 0.0;
double sepiaBlue = 0.0;
// over height
for (int h = 0; h < height; h++)
{
// over width
for ( int w = 0; w < width; w++)
{
sepiaRed = .393 * image[h][w].rgbtRed + .769 * image[h][w].rgbtGreen + .189 * image[h][w].rgbtBlue;
// ^ Divide by zero occurs on this line.
sepiaGreen = .349 * image[h][w].rgbtRed + .686 * image[h][w].rgbtGreen + .168 * image[h][w].rgbtBlue;
sepiaBlue = .272 * image[h][w].rgbtRed + .534 * image[h][w].rgbtGreen + .131 * image[h][w].rgbtBlue;
// space
if (sepiaRed > 255 || sepiaGreen > 255 || sepiaBlue > 255)
{
sepiaRed = 255;
sepiaGreen = 255;
sepiaBlue = 255;
}
image[h][w].rgbtRed = (sepiaRed);
image[h][w].rgbtBlue = (sepiaBlue);
image[h][w].rgbtGreen = (sepiaGreen);
}
}
return;
}
int main()
{
sepia(3, 4, image);
return 0;
}
由于数组索引,除以 0。
VLA 支持有问题或不存在。
// VLA prototype v-------------v
void sepia(int height, int width, RGBTRIPLE image[height][width]) {
// v----v
sepiaRed = .393 * image[h][w].rgbtRed + .769 * ...
代码可以使用非 VLA 方法,如下所示,
void sepia(int height, int width, RGBTRIPLE image[3][4]) {
VLA 支持从 C99 开始。
使用 C11 或更高版本,检查 __STDC_NO_VLA__
是否不支持。
以下代码来源于一个问题here。 (我知道代码有几个逻辑问题,但我不明白它们是如何导致这个问题的。)
编辑: 我在 Windows 上使用 CLANG,显示编译时的常见警告。
它在指示的行(for 循环中的第一个语句。)生成一个被零除的错误,但没有明显的 除。任何人都可以提供一些关于为什么会发生此错误的见解吗?
编辑 2: 根据评论:将 sepia
函数中的第三个参数从
void sepia(int height, int width, RGBTRIPLE image[height][width])
到
void sepia(int height, int width, RGBTRIPLE image[3][4])
消除除以零的错误。为什么?
typedef struct {
double rgbtRed;
double rgbtGreen;
double rgbtBlue;
}RGBTRIPLE;
RGBTRIPLE image[3][4];
void sepia(int height, int width, RGBTRIPLE image[height][width])
{
double sepiaRed = 0.0;
double sepiaGreen = 0.0;
double sepiaBlue = 0.0;
// over height
for (int h = 0; h < height; h++)
{
// over width
for ( int w = 0; w < width; w++)
{
sepiaRed = .393 * image[h][w].rgbtRed + .769 * image[h][w].rgbtGreen + .189 * image[h][w].rgbtBlue;
// ^ Divide by zero occurs on this line.
sepiaGreen = .349 * image[h][w].rgbtRed + .686 * image[h][w].rgbtGreen + .168 * image[h][w].rgbtBlue;
sepiaBlue = .272 * image[h][w].rgbtRed + .534 * image[h][w].rgbtGreen + .131 * image[h][w].rgbtBlue;
// space
if (sepiaRed > 255 || sepiaGreen > 255 || sepiaBlue > 255)
{
sepiaRed = 255;
sepiaGreen = 255;
sepiaBlue = 255;
}
image[h][w].rgbtRed = (sepiaRed);
image[h][w].rgbtBlue = (sepiaBlue);
image[h][w].rgbtGreen = (sepiaGreen);
}
}
return;
}
int main()
{
sepia(3, 4, image);
return 0;
}
由于数组索引,除以 0。
VLA 支持有问题或不存在。
// VLA prototype v-------------v
void sepia(int height, int width, RGBTRIPLE image[height][width]) {
// v----v
sepiaRed = .393 * image[h][w].rgbtRed + .769 * ...
代码可以使用非 VLA 方法,如下所示,
void sepia(int height, int width, RGBTRIPLE image[3][4]) {
VLA 支持从 C99 开始。
使用 C11 或更高版本,检查 __STDC_NO_VLA__
是否不支持。