这不是制作意大利国旗 .ppm 文件的方法吗?
Is this not that way to make an Italian flag .ppm file?
这是我创建意大利国旗 .ppm 文件的代码:
#include <stdio.h>
int main() {
int width = 800, height = 600, i, j;
printf("P6\n");
printf("%d %d\n", width, height);
printf("255\n");
for (i = 0; i < height; i++) {
for (j = 0; j < width/3; j++) {
printf("%c%c%c", 0,146,70);
}
for (j = 0; j < width/3; j++) {
printf("%c%c%c", 255, 255, 255);
}
for (j = 0; j < width/3; j++) {
printf("%c%c%c", 206,43,55);
}
}
return 0;
}
我已经制作了一面波兰和荷兰国旗,效果很好。不知道对不对?
你的问题是你的 width = 800
不能被 3 整除。所以你不会用外循环的一次迭代填充整行。
for (j = 0; j < width/3; j++)
一旦 j
大于宽度的三分之一,该行就会停止。让我们考虑一个简单的例子 width=4
。 width/3
介于 1 和 2 之间。因此,您可以将一个像素涂成绿色,将一个像素涂成白色,将一个像素涂成红色。第四个呢?必须由下一次迭代填充。
例如设置您的width = 900
,您应该得到预期的输出。
@lucidbrot 给出的答案是正确的,但我想详细说明一下。
800/3
是266
(假设整除),而266*3
是798
,不是你想要的800
的宽度。自然地,您可以 select 可以被 3
整除的宽度来解决 @lucidbrot 建议的问题。
有时您无法自由更改宽度,但幸运的是还有另一种解决方案。不要将颜色分成相等的部分。最简单的方法是计算每个色带相对于扫描线开始的位置,然后在下一个开始的地方停止用一种颜色着色:
#include <stdio.h>
int main() {
int width = 800, height = 600;
printf("P6\n");
printf("%d %d\n", width, height);
printf("255\n");
int start_green = 0;
int start_white = (1*width)/3;
int start_red = (2*width)/3
for (int i = 0; i < height; i++) {
/* Green Band */
for (int j = start_green; j < start_white; j++) {
printf("%c%c%c", 0,146,70);
}
/* White Band */
for (int j = start_white; j < start_red; j++) {
printf("%c%c%c", 255, 255, 255);
}
/* Red Band */
for (int j = start_red; j < width; j++) {
printf("%c%c%c", 206,43,55);
}
}
return 0;
}
对 start_white
和 start_red
的一些补充评论。进行整数乘法和除法时,运算符应用程序的正确顺序很重要。 (2 * 800)/3
等于 533
。这与等于 532
的 2 * (800/3)
不同。所以第一个表达式更接近 533.3333....
.
的真实值
从技术上讲,由于运算符的优先级,我们不需要括号,但它
为 reader.
添加清晰度始终是个好主意
这种将事物分成大致相同大小的组的方法还有其他用途。然后我们通常不能改变我们拥有的“东西”的数量。
作为 reader 的额外奖励问题:假设整数除法,[=24= 的值是多少。提示:它不是 533.3333....
.
这是我创建意大利国旗 .ppm 文件的代码:
#include <stdio.h>
int main() {
int width = 800, height = 600, i, j;
printf("P6\n");
printf("%d %d\n", width, height);
printf("255\n");
for (i = 0; i < height; i++) {
for (j = 0; j < width/3; j++) {
printf("%c%c%c", 0,146,70);
}
for (j = 0; j < width/3; j++) {
printf("%c%c%c", 255, 255, 255);
}
for (j = 0; j < width/3; j++) {
printf("%c%c%c", 206,43,55);
}
}
return 0;
}
我已经制作了一面波兰和荷兰国旗,效果很好。不知道对不对?
你的问题是你的 width = 800
不能被 3 整除。所以你不会用外循环的一次迭代填充整行。
for (j = 0; j < width/3; j++)
一旦 j
大于宽度的三分之一,该行就会停止。让我们考虑一个简单的例子 width=4
。 width/3
介于 1 和 2 之间。因此,您可以将一个像素涂成绿色,将一个像素涂成白色,将一个像素涂成红色。第四个呢?必须由下一次迭代填充。
例如设置您的width = 900
,您应该得到预期的输出。
@lucidbrot 给出的答案是正确的,但我想详细说明一下。
800/3
是266
(假设整除),而266*3
是798
,不是你想要的800
的宽度。自然地,您可以 select 可以被 3
整除的宽度来解决 @lucidbrot 建议的问题。
有时您无法自由更改宽度,但幸运的是还有另一种解决方案。不要将颜色分成相等的部分。最简单的方法是计算每个色带相对于扫描线开始的位置,然后在下一个开始的地方停止用一种颜色着色:
#include <stdio.h>
int main() {
int width = 800, height = 600;
printf("P6\n");
printf("%d %d\n", width, height);
printf("255\n");
int start_green = 0;
int start_white = (1*width)/3;
int start_red = (2*width)/3
for (int i = 0; i < height; i++) {
/* Green Band */
for (int j = start_green; j < start_white; j++) {
printf("%c%c%c", 0,146,70);
}
/* White Band */
for (int j = start_white; j < start_red; j++) {
printf("%c%c%c", 255, 255, 255);
}
/* Red Band */
for (int j = start_red; j < width; j++) {
printf("%c%c%c", 206,43,55);
}
}
return 0;
}
对 start_white
和 start_red
的一些补充评论。进行整数乘法和除法时,运算符应用程序的正确顺序很重要。 (2 * 800)/3
等于 533
。这与等于 532
的 2 * (800/3)
不同。所以第一个表达式更接近 533.3333....
.
从技术上讲,由于运算符的优先级,我们不需要括号,但它 为 reader.
添加清晰度始终是个好主意这种将事物分成大致相同大小的组的方法还有其他用途。然后我们通常不能改变我们拥有的“东西”的数量。
作为 reader 的额外奖励问题:假设整数除法,[=24= 的值是多少。提示:它不是 533.3333....
.