CS50灰度滤镜代码不生效原因及无指针修改数组问题咨询
问题1:while循环版本代码异常原因
你的代码问题出在内层循环计数器j没有重置:
- 你在函数开头一次性初始化了
j=0,当第一轮外层循环(i=0)执行完成后,j已经自增到等于width的值 - 后续i从1到height-1的所有外层循环执行时,j一直保持为width,永远不会进入
j < width的内层循环,最终只有图片的第一行被处理成灰度,其余行无变化,导致整体运行异常。
修正方案只需要在每次进入外层循环时,将j重置为0即可,修正后代码如下:
void grayscale(int height, int width, RGBTRIPLE image[height][width]) { int i = 0; float rgbGray; while (i < height) { int j = 0; // 每次处理新行时重置j为0 while (j < width) { rgbGray = (image[i][j].rgbtBlue + image[i][j].rgbtGreen + image[i][j].rgbtRed) / 3.00; rgbGray = round(rgbGray); image[i][j].rgbtBlue = rgbGray; image[i][j].rgbtGreen = rgbGray; image[i][j].rgbtRed = rgbGray; j++; } i++; } return; }
你参考的for循环版本不会有这个问题,是因为内层for循环的int j = 0会在每次内层循环启动前自动完成j的初始化。
问题2:无指针、无返回值可修改原图的原理
这是C语言的数组传参特性导致的:
- 当你把数组作为参数传入函数时,C语言不会对整个数组做值拷贝,而是会将数组隐式退化为指向数组首元素的指针
- 你代码中函数参数写的
RGBTRIPLE image[height][width]只是语法糖,编译器实际处理时会将其识别为RGBTRIPLE (*image)[width](指向长度为width的RGBTRIPLE一维数组的指针) - 所以你在函数内对
image[i][j]的修改,本质上是通过指针直接操作原数组所在的内存地址,不需要额外返回值也不需要显式声明指针,就可以直接修改原图数据。
内容的提问来源于stack exchange,提问作者Rounded Hedgehog
相关产品推荐
相关产品推荐

