c - 为什么我的小 C 循环不能正确打印到帧缓冲区,但它的展开版本却可以?
问题描述
我正在尝试编写一个简单的 C 程序,该程序在位置 (x, y) = (50, 50) 处绘制一个 4x4 像素的白色实心正方形。
这个想法是直接写入 Linux 帧缓冲区,它从映射内存 fb->fp 开始。
现在,问题在于以下代码运行良好:
uint16_t color = 0xffff;
memcpy(fb->fp + (50+0) * fb->line_length + (50+0) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+0) * fb->line_length + (50+1) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+0) * fb->line_length + (50+2) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+0) * fb->line_length + (50+3) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+1) * fb->line_length + (50+0) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+1) * fb->line_length + (50+1) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+1) * fb->line_length + (50+2) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+1) * fb->line_length + (50+3) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+2) * fb->line_length + (50+0) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+2) * fb->line_length + (50+1) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+2) * fb->line_length + (50+2) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+2) * fb->line_length + (50+3) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+3) * fb->line_length + (50+0) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+3) * fb->line_length + (50+1) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+3) * fb->line_length + (50+2) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
memcpy(fb->fp + (50+3) * fb->line_length + (50+3) * fb->bytes_per_pixel, &color, fb->bytes_per_pixel);
但是,以下没有。它产生一条 1x4 的线而不是 4x4 的正方形。
uint16_t color = 0xffff;
int i = 0;
int j = 0;
for (; j < 4; j++) {
for (; i < 4; i++) {
int y_offset = 50 + j;
int x_offset = 50 + i;
memcpy(fb->fp + y_offset * fb->line_length + x_offset * fb->bytes_per_pixel,
&color, fb->bytes_per_pixel);
}
}
据我所知,它们应该是等价的。我从编译器得到的汇编版本看起来不太容易理解。
这在 ARM 嵌入式 Linux 设备中运行。此时没有 X 服务器或任何其他内容写入帧缓冲区。
fb->bytes_per_pixel等于2。
我找不到任何关于帧缓冲区如何映射到内存的文档。我得到的偏移量来自我在谷歌上找到的随机代码。
这些偏移量可能有问题。但至少这两个代码应该是等价的,不是吗?我要疯了吗?
解决方案
这是问题所在:
for (; j < 4; j++) {
for (; i < 4; i++) {
//some code
}
}
外for
循环预计执行4次,一定是因为break;
body中没有条件语句。然而,内for
循环需要改变。对于外for
循环的第一次迭代,内for
循环按预期执行了 4 次。
在外for
循环的第二次迭代中,值为i
is ,内循环4
的条件为假,所以它不执行。外循环的所有下一次迭代都会发生同样的情况。i>4
for
for
您可以通过初始化i
外for
循环的每次迭代来克服这个问题。
选项1:
for( ; j < 4; j++)
{
for (i = 0; i < 4; i++)
{
// Some code
}
}
选项 2:
for( ; j < 4; j++)
{
for (; i < 4; i++)
{
// Some code
}
i = 0;
}
选项 3:
for( ; j < 4; j++)
{
i = 0;
for ( ; i < 4; i++)
{
// Some code
}
}
选项 4:正如David C. Rankin所建议的那样:
int j = 0;
// int i = 0;
for( ; j < 4; j++)
{
int i = 0;
for ( ; i < 4; i++)
{
// Some code
}
}
推荐阅读
- unit-testing - 连接字段的 Apex 触发器的单元测试
- python - tkinter - 如何在框架中调整屏幕大小?
- javascript - 为什么 (true && 'string') 在 JS 中等于 'string' 而不是 true?
- apache-spark - Spark 中的 Apache 光束 StateSpec
- asp.net - 回发后如何留在同一个标签上
- c - 如何更改字符串中的每个字符但不更改 C 中的标点符号?
- ansible - ansible 模块 os_keypair 从不返回 private_key 的值
- python - AttributeError:“NoneType”对象没有属性“fileno”诅咒模块错误
- java - Java Spring Boot 作为 Windows 服务的替代品
- r - 为 data.frame 和 tbl_df 设置行和列