我尝试制作的程序几乎是一个点,因为它围绕屏幕中心移动,好像受重力影响。方法I用作"显示"只是打印一个" "没有任何意义的地方和" X"哪里有一点。在完成我的程序编写并注意到它没有按照我想要的方式工作之后,我开始调试它。完整的计划如下:
#include <stdio.h>
#include <math.h>
double dist (double xpos, double ypos, double xm, double ym);
double acc (double xpos, double ypos, double xm, double ym, double grav, int xory);
int main () {
double xpos, ypos, xvel, yvel, xm, ym, grav, step;
double xtpos, ytpos, xtvel, ytvel;
int refresh, width, height;
int xposr, yposr, xmr, ymr;
xpos = 3;
ypos = 4;
xvel = 0;
yvel = 0;
grav = 4;
step = 1;
xm = 0;
ym = 0;
width = 128;
height = 64;
refresh = 1;
int screen[width][height];
printf ("done2\n");
printf ("test\n");
printf ("done3");
while (refresh == 1) {
printf ("entered loop");
usleep (100000);
for (int a = 0; a <= height; ++a) {
for (int b = 0; b <= width; ++b) {
screen[b][a] = 0;
}
}
xposr = rint (xpos);
yposr = rint (ypos);
xmr = rint (xm);
ymr = rint (ym);
screen[xmr][ymr] = 1;
screen[xposr][yposr] = 1;
for (int y = 0; y <= height; ++y) {
for (int x = 0; x <= width; ++x) {
if (screen [x][y] == 0) {
printf (" ");
}
else {
printf ("X");
}
}
printf ("\n");
}
xtpos = xpos + (xvel * step);
ytpos = ypos + (yvel * step);
xtvel = xvel + (acc (xpos, ypos, xm, ym, grav, 0) * step * step);
ytvel = yvel + (acc (xpos, ypos, xm, ym, grav, 1) * step * step);
xpos = xtpos;
ypos = ytpos;
xvel = ytvel;
yvel = xtvel;
refresh = 0;
}
}
double dist (double xpos, double ypos, double xm, double ym) {
double deltax, deltay, result;
deltax = xpos - xm;
deltay = ypos - ym;
result = sqrt ((deltax * deltax) + (deltay * deltay));
return result;
}
double acc (double xpos, double ypos, double xm, double ym, double grav, int xory) {
double result;
if (xory == 0) {
result = ((xpos - xm) * grav * grav) / (dist (xpos, ypos, xm, ym) * dist (xpos, ypos, xm, ym) * dist (xpos, ypos, xm, ym));
}
else if (xory == 1) {
result = ((ypos - ym) * grav * grav) / (dist (xpos, ypos, xm, ym) * dist (xpos, ypos, xm, ym) * dist (xpos, ypos, xm, ym));
}
return result;
}
该程序似乎挂起并且从未进入可以看到的while循环,因为没有&#34;进入循环&#34;文字印在屏幕上。这很奇怪,因为while循环应该无限循环,因为refresh == 1.然后我会在while之前放一些printf语句来查看程序停止的位置。此时,运行程序后我唯一得到的是
done2
test
|
出于某种原因,该程序甚至不必费心去做下一个printf语句。
答案 0 :(得分:3)
printf
写入名为FILE *
的特殊stdout
。 printf(/*...*/)
与fprintf(stdout, /*.../*)
同义。出于性能原因,stdout是行缓冲,这意味着在您向其写入换行符或手动刷新之前,写入其中的任何内容都可能无法向外显示。输出字符是昂贵的,通过缓冲输出我们可以输出更少的次数,我们的程序运行得更快,更快。
如果您没有输出到文件,可以通过说
让它在每个打印件上刷新printf("entered loop\n"); // note the extra '\n'
如果你只是写文本(不是格式字符串,不打印任何变量),你也可以使用puts(const char *)
打印你给它的字符串,然后换行。
puts("entered loop");
输出到文件(而不是屏幕)时,stdout完全缓冲。以下将始终使其刷新。如果您希望输出完全按照您的编写方式保留,则可以采用以下方法:
printf("entered loop");
fflush(stdout);
如果你想生活危险,你可以做到
setbuf(stdout, NULL);
一旦进入你的主人或其他地方,这将阻止stdout上的所有缓冲(危险地,我的意思是非常慢,你可能实际上不应该这样做)。
答案 1 :(得分:2)
您应该在printf中包含换行符:
printf("entered loop\n");
这将导致缓冲区刷新。没有它,角色将无法实际打印在控制台上。顺便说一句,这也是你没有看到“done3”打印的原因,它也缺少“\ n”。
或者,您可以手动冲洗它:
printf("entered loop");
fflush(stdout);
有必要的原因是stdout是一个缓冲设备(嗯,它适用于某些* nix系统)。这意味着它不会在屏幕上打印,除非填充缓冲区,手动刷新或在打印文本中包含新行字符。
答案 2 :(得分:0)
除了kamituel和Ryan Haining发现的问题之外,您的计划还存在以下问题:
当索引达到给定维度的大小时,迭代遍历screen
矩阵维度的循环应该停止。您必须使用a < height
代替<=
。必须至少在4个不同的实例中纠正这个错误。
将矩阵screen
定义为int screen[height][width];
更为常见,因为它允许嵌套循环中更好的局部性,y
在外部循环中进行迭代x
在内在的。发布的代码不正确,但有点令人惊讶。
acc()
既不是result
也不是xory
,则函数0
会返回未初始化的变量1
。如果配置正确,编译器应该针对此问题和其他潜在问题生成警告。如果xory
只是一个布尔值,那么单个测试就足够了。
循环while (refresh == 1)
似乎只迭代一次。为什么要把它变成循环?