将数组写入控制台的更快方法?
Faster Way to write an Array to the Console?
我最近尝试制作自己的生命游戏版本,并且成功了,唯一的问题是打印到控制台,如果你执行它,你可以清楚地看到它从左到右写入,并且大约需要 0.3 秒,我希望它能快一点
如果要编译它,只需在第一个屏幕上输入 0。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include "console.h"
//#include <conio.h>
#define XSIZE 80 // max 240
#define YSIZE 25 // max 67
int clone(int array1[XSIZE][YSIZE], int array2[XSIZE][YSIZE]);
int print(int array[XSIZE][YSIZE]);
int getrandarray(int array[XSIZE][YSIZE]);
int countNachbar(int x, int y, int array[XSIZE][YSIZE]);
int calccells(int thisarray[XSIZE][YSIZE], int nextarray[XSIZE][YSIZE]);
int choice;
int main()
{
setCursorType(0);
srand(time(0));
initConsole();
//mode con: cols=XSIZE lines=YSIZE;
int cells[XSIZE][YSIZE], nextcells[XSIZE][YSIZE] = {};
int cellgen = 0;
char c;
printf("Nachbarmodus?\n1 = Rechteck(Randzellen bleiben immer gleich, stirbt nicht oft aus)\n0 = Torus(Die seiten des rechteckes werden verbunden, um einen Donut\ndarzustellen, der keine raender hat, stirbt oefter aus, ist der Originale Modus)\n");
scanf("%d", &choice);
clrscr();
gotoxy(0, 0);
getrandarray(cells);
print(cells);
while(c != 27)
{
calccells(cells, nextcells); //memcpy (cells, nextcells, YSIZE*XSIZE*sizeof(int));
print(nextcells);
cellgen++;
gotoxy(0, YSIZE+1);
printf("Generation %d", cellgen);
clone(nextcells, cells);
if(kbhit())
c = getch();
}
return 0;
}
int print(int array[XSIZE][YSIZE])
{
int x, y;
for(x=0; x<XSIZE; x++)
{
for(y=0; y<YSIZE; y++)
{
gotoxy(x, y);
if(array[x][y] == 1)
printf("%c", 254);
else if(array[x][y] == 0)
printf(" ");
}
}
}
int getrandarray(int array[XSIZE][YSIZE])
{
int x, y;
for(x=0; x<XSIZE; x++)
{
for(y=0; y<YSIZE; y++)
{
array[x][y] = rand()%2;
//array[x][y] = 1;
}
}
}
int countNachbar(int x, int y, int array[XSIZE][YSIZE])
{
int sum=0, i, j, spalte, reihe;
for(i=-1; i<2; i++)
{
for(j=-1; j<2; j++)
{
spalte = (x + i + XSIZE) % XSIZE;
reihe = (y + j + YSIZE) % YSIZE;
sum += array[spalte][reihe];
}
}
sum-=array[x][y];
return sum;
}
int clone(int array1[XSIZE][YSIZE], int array2[XSIZE][YSIZE])
{
int x, y;
for(x=0; x<XSIZE; x++)
{
for(y=0; y<YSIZE; y++)
{
array2[x][y] = array1[x][y];
}
}
}
int calccells(int thisarray[XSIZE][YSIZE], int nextarray[XSIZE][YSIZE])
{
int x, y, state, nachbarn;
for(x=0; x<XSIZE; x++)
{
for(y=0; y<YSIZE; y++)
{
state = thisarray[x][y];
nachbarn = countNachbar(x, y, thisarray);
if(state == 0 && nachbarn == 3)
{
nextarray[x][y] = 1;
}
if(state == 1 && (nachbarn < 2 || nachbarn > 3))
nextarray[x][y] = 0;
if(choice)
{
if(x == 0 || x == (XSIZE-1) || y == 0 || y == (YSIZE-1) )
nextarray[x][y] = thisarray[x][y];
}
}
}
}
//console.h:
//https://www.mediafire.com/file/124e42w8mzy0o4z/console.h/file
//https://www.mediafire.com/file/89j8f9kf7ndyqp6/console.c/file
快速分析您的代码后,我发现占用时间最多的函数是 gotoxy()
和 printf()
。
因此,我建议您尽量少调用它们。
下面是您可以使用的改进列表:
- 由于网格从位置 (0, 0) 开始,您可以简单地在
print()
的开头调用 gotoxy(0, 0);
。
- 要减少对
printf()
的调用次数,您可以使用数组构建单个字符串。然后通过单个函数调用显示该字符串。
- 对于未格式化的字符串,可以使用
puts()
而不是printf()
。
- 或者,要打印单个字符,您可以使用
putc()
。
希望对您有所帮助! :)
在我使用了@Pimich 的建议后,这是现在的代码,打印命令之前大约需要 0.8 秒,现在需要 0.03 秒。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include <windows.h>
#define XSIZE 236 // max 236
#define YSIZE 61 // max (61)67
#define SLEEP 50
void print(int array[XSIZE][YSIZE]); // unused
void getrandarray(int array[XSIZE][YSIZE]);
void qprint(int array[XSIZE][YSIZE]);
int countNachbar(int x, int y, int array[XSIZE][YSIZE]);
void clone(int array1[XSIZE][YSIZE], int array2[XSIZE][YSIZE]); // unused
void calccells(int thisarray[XSIZE][YSIZE], int nextarray[XSIZE][YSIZE]);
int choice;
int main()
{
setCursorType(0);
srand(time(0));
SMALL_RECT windowSize = {0 , 0 , XSIZE , YSIZE+5};
SetConsoleWindowInfo(GetStdHandle(STD_OUTPUT_HANDLE), TRUE, &windowSize);
int cells[XSIZE][YSIZE] = {}, nextcells[XSIZE][YSIZE] = {};
int cycles = 0;
char c;
double timetaken, cpuTime, biggestCpuTime = 0;
printf("Nachbarmodus?\n1 = Rechteck(Randzellen bleiben immer gleich, stirbt nicht oft aus)\n0 = Torus(Die seiten des rechteckes werden verbunden, um einen Donut\ndarzustellen, der keine raender hat, stirbt oefter aus, ist der Originale Modus)\n");
scanf("%d", &choice);
clrscr();
gotoxy(0, 0);
getrandarray(cells);
qprint(cells);
while(c != 27)
{
clock_t tic = clock();
//measure time for 1 cycle
calccells(cells, nextcells);
qprint(nextcells);
cycles++;
memcpy (cells, nextcells, YSIZE*XSIZE*sizeof(int));
if(kbhit())
c = getch();
delay(SLEEP);
//Calculate Stats
clock_t toc = clock();
timetaken = (double)(toc - tic) / CLOCKS_PER_SEC;
cpuTime = timetaken-(SLEEP/1000.0);
if(cpuTime > biggestCpuTime)
biggestCpuTime = cpuTime;
gotoxy(0, YSIZE+1);
printf("Time per Cycle: %f s\nDelay: %f s\nCPU Time: %f s\nworst CPU Time: %f s\nCycle: %d", timetaken, SLEEP/1000.0, cpuTime, biggestCpuTime, cycles);
}
return 0;
}
void qprint(int array[XSIZE][YSIZE])
{
char text[XSIZE*YSIZE+(YSIZE)];
char at[2];
*at = 254;
char space[2] = " ";
char newline[2] = "\n";
text[0] = '[=10=]';
for(int j=0; j<YSIZE; j++)
{
for(int i=0; i<XSIZE; i++)
{
if(array[i][j] == 1)
strcat(text, at);
else
strcat(text, space);
}
strcat(text, newline);
}
gotoxy(0, 0);
printf("%s", text);
}
void print(int array[XSIZE][YSIZE])
{
gotoxy(0, 0);
int x, y;
for(y=0; y<YSIZE; y++)
{
for(x=0; x<XSIZE; x++)
{
if(array[x][y] == 1)
printf("%c", 254);
else
printf(" ");
}
printf("\n");
}
}
void getrandarray(int array[XSIZE][YSIZE])
{
int x, y;
for(x=0; x<XSIZE; x++)
{
for(y=0; y<YSIZE; y++)
{
array[x][y] = rand()%2;
//array[x][y] = 1;
}
}
}
int countNachbar(int x, int y, int array[XSIZE][YSIZE])
{
int sum=0, i, j, spalte, reihe;
for(i=-1; i<2; i++)
{
for(j=-1; j<2; j++)
{
spalte = (x + i + XSIZE) % XSIZE;
reihe = (y + j + YSIZE) % YSIZE;
sum += array[spalte][reihe];
}
}
sum-=array[x][y];
return sum;
}
void clone(int array1[XSIZE][YSIZE], int array2[XSIZE][YSIZE])
{
int x, y;
for(x=0; x<XSIZE; x++)
{
for(y=0; y<YSIZE; y++)
{
array2[x][y] = array1[x][y];
}
}
}
void calccells(int thisarray[XSIZE][YSIZE], int nextarray[XSIZE][YSIZE])
{
int x, y, state, nachbarn;
for(x=0; x<XSIZE; x++)
{
for(y=0; y<YSIZE; y++)
{
state = thisarray[x][y];
nachbarn = countNachbar(x, y, thisarray);
if(state == 0 && nachbarn == 3)
{
nextarray[x][y] = 1;
}
if(state == 1 && (nachbarn < 2 || nachbarn > 3))
nextarray[x][y] = 0;
if(choice)
{
if(x == 0 || x == (XSIZE-1) || y == 0 || y == (YSIZE-1) )
nextarray[x][y] = thisarray[x][y];
}
}
}
}
我最近尝试制作自己的生命游戏版本,并且成功了,唯一的问题是打印到控制台,如果你执行它,你可以清楚地看到它从左到右写入,并且大约需要 0.3 秒,我希望它能快一点 如果要编译它,只需在第一个屏幕上输入 0。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include "console.h"
//#include <conio.h>
#define XSIZE 80 // max 240
#define YSIZE 25 // max 67
int clone(int array1[XSIZE][YSIZE], int array2[XSIZE][YSIZE]);
int print(int array[XSIZE][YSIZE]);
int getrandarray(int array[XSIZE][YSIZE]);
int countNachbar(int x, int y, int array[XSIZE][YSIZE]);
int calccells(int thisarray[XSIZE][YSIZE], int nextarray[XSIZE][YSIZE]);
int choice;
int main()
{
setCursorType(0);
srand(time(0));
initConsole();
//mode con: cols=XSIZE lines=YSIZE;
int cells[XSIZE][YSIZE], nextcells[XSIZE][YSIZE] = {};
int cellgen = 0;
char c;
printf("Nachbarmodus?\n1 = Rechteck(Randzellen bleiben immer gleich, stirbt nicht oft aus)\n0 = Torus(Die seiten des rechteckes werden verbunden, um einen Donut\ndarzustellen, der keine raender hat, stirbt oefter aus, ist der Originale Modus)\n");
scanf("%d", &choice);
clrscr();
gotoxy(0, 0);
getrandarray(cells);
print(cells);
while(c != 27)
{
calccells(cells, nextcells); //memcpy (cells, nextcells, YSIZE*XSIZE*sizeof(int));
print(nextcells);
cellgen++;
gotoxy(0, YSIZE+1);
printf("Generation %d", cellgen);
clone(nextcells, cells);
if(kbhit())
c = getch();
}
return 0;
}
int print(int array[XSIZE][YSIZE])
{
int x, y;
for(x=0; x<XSIZE; x++)
{
for(y=0; y<YSIZE; y++)
{
gotoxy(x, y);
if(array[x][y] == 1)
printf("%c", 254);
else if(array[x][y] == 0)
printf(" ");
}
}
}
int getrandarray(int array[XSIZE][YSIZE])
{
int x, y;
for(x=0; x<XSIZE; x++)
{
for(y=0; y<YSIZE; y++)
{
array[x][y] = rand()%2;
//array[x][y] = 1;
}
}
}
int countNachbar(int x, int y, int array[XSIZE][YSIZE])
{
int sum=0, i, j, spalte, reihe;
for(i=-1; i<2; i++)
{
for(j=-1; j<2; j++)
{
spalte = (x + i + XSIZE) % XSIZE;
reihe = (y + j + YSIZE) % YSIZE;
sum += array[spalte][reihe];
}
}
sum-=array[x][y];
return sum;
}
int clone(int array1[XSIZE][YSIZE], int array2[XSIZE][YSIZE])
{
int x, y;
for(x=0; x<XSIZE; x++)
{
for(y=0; y<YSIZE; y++)
{
array2[x][y] = array1[x][y];
}
}
}
int calccells(int thisarray[XSIZE][YSIZE], int nextarray[XSIZE][YSIZE])
{
int x, y, state, nachbarn;
for(x=0; x<XSIZE; x++)
{
for(y=0; y<YSIZE; y++)
{
state = thisarray[x][y];
nachbarn = countNachbar(x, y, thisarray);
if(state == 0 && nachbarn == 3)
{
nextarray[x][y] = 1;
}
if(state == 1 && (nachbarn < 2 || nachbarn > 3))
nextarray[x][y] = 0;
if(choice)
{
if(x == 0 || x == (XSIZE-1) || y == 0 || y == (YSIZE-1) )
nextarray[x][y] = thisarray[x][y];
}
}
}
}
//console.h:
//https://www.mediafire.com/file/124e42w8mzy0o4z/console.h/file
//https://www.mediafire.com/file/89j8f9kf7ndyqp6/console.c/file
快速分析您的代码后,我发现占用时间最多的函数是 gotoxy()
和 printf()
。
因此,我建议您尽量少调用它们。 下面是您可以使用的改进列表:
- 由于网格从位置 (0, 0) 开始,您可以简单地在
print()
的开头调用gotoxy(0, 0);
。 - 要减少对
printf()
的调用次数,您可以使用数组构建单个字符串。然后通过单个函数调用显示该字符串。 - 对于未格式化的字符串,可以使用
puts()
而不是printf()
。 - 或者,要打印单个字符,您可以使用
putc()
。
希望对您有所帮助! :)
在我使用了@Pimich 的建议后,这是现在的代码,打印命令之前大约需要 0.8 秒,现在需要 0.03 秒。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include <windows.h>
#define XSIZE 236 // max 236
#define YSIZE 61 // max (61)67
#define SLEEP 50
void print(int array[XSIZE][YSIZE]); // unused
void getrandarray(int array[XSIZE][YSIZE]);
void qprint(int array[XSIZE][YSIZE]);
int countNachbar(int x, int y, int array[XSIZE][YSIZE]);
void clone(int array1[XSIZE][YSIZE], int array2[XSIZE][YSIZE]); // unused
void calccells(int thisarray[XSIZE][YSIZE], int nextarray[XSIZE][YSIZE]);
int choice;
int main()
{
setCursorType(0);
srand(time(0));
SMALL_RECT windowSize = {0 , 0 , XSIZE , YSIZE+5};
SetConsoleWindowInfo(GetStdHandle(STD_OUTPUT_HANDLE), TRUE, &windowSize);
int cells[XSIZE][YSIZE] = {}, nextcells[XSIZE][YSIZE] = {};
int cycles = 0;
char c;
double timetaken, cpuTime, biggestCpuTime = 0;
printf("Nachbarmodus?\n1 = Rechteck(Randzellen bleiben immer gleich, stirbt nicht oft aus)\n0 = Torus(Die seiten des rechteckes werden verbunden, um einen Donut\ndarzustellen, der keine raender hat, stirbt oefter aus, ist der Originale Modus)\n");
scanf("%d", &choice);
clrscr();
gotoxy(0, 0);
getrandarray(cells);
qprint(cells);
while(c != 27)
{
clock_t tic = clock();
//measure time for 1 cycle
calccells(cells, nextcells);
qprint(nextcells);
cycles++;
memcpy (cells, nextcells, YSIZE*XSIZE*sizeof(int));
if(kbhit())
c = getch();
delay(SLEEP);
//Calculate Stats
clock_t toc = clock();
timetaken = (double)(toc - tic) / CLOCKS_PER_SEC;
cpuTime = timetaken-(SLEEP/1000.0);
if(cpuTime > biggestCpuTime)
biggestCpuTime = cpuTime;
gotoxy(0, YSIZE+1);
printf("Time per Cycle: %f s\nDelay: %f s\nCPU Time: %f s\nworst CPU Time: %f s\nCycle: %d", timetaken, SLEEP/1000.0, cpuTime, biggestCpuTime, cycles);
}
return 0;
}
void qprint(int array[XSIZE][YSIZE])
{
char text[XSIZE*YSIZE+(YSIZE)];
char at[2];
*at = 254;
char space[2] = " ";
char newline[2] = "\n";
text[0] = '[=10=]';
for(int j=0; j<YSIZE; j++)
{
for(int i=0; i<XSIZE; i++)
{
if(array[i][j] == 1)
strcat(text, at);
else
strcat(text, space);
}
strcat(text, newline);
}
gotoxy(0, 0);
printf("%s", text);
}
void print(int array[XSIZE][YSIZE])
{
gotoxy(0, 0);
int x, y;
for(y=0; y<YSIZE; y++)
{
for(x=0; x<XSIZE; x++)
{
if(array[x][y] == 1)
printf("%c", 254);
else
printf(" ");
}
printf("\n");
}
}
void getrandarray(int array[XSIZE][YSIZE])
{
int x, y;
for(x=0; x<XSIZE; x++)
{
for(y=0; y<YSIZE; y++)
{
array[x][y] = rand()%2;
//array[x][y] = 1;
}
}
}
int countNachbar(int x, int y, int array[XSIZE][YSIZE])
{
int sum=0, i, j, spalte, reihe;
for(i=-1; i<2; i++)
{
for(j=-1; j<2; j++)
{
spalte = (x + i + XSIZE) % XSIZE;
reihe = (y + j + YSIZE) % YSIZE;
sum += array[spalte][reihe];
}
}
sum-=array[x][y];
return sum;
}
void clone(int array1[XSIZE][YSIZE], int array2[XSIZE][YSIZE])
{
int x, y;
for(x=0; x<XSIZE; x++)
{
for(y=0; y<YSIZE; y++)
{
array2[x][y] = array1[x][y];
}
}
}
void calccells(int thisarray[XSIZE][YSIZE], int nextarray[XSIZE][YSIZE])
{
int x, y, state, nachbarn;
for(x=0; x<XSIZE; x++)
{
for(y=0; y<YSIZE; y++)
{
state = thisarray[x][y];
nachbarn = countNachbar(x, y, thisarray);
if(state == 0 && nachbarn == 3)
{
nextarray[x][y] = 1;
}
if(state == 1 && (nachbarn < 2 || nachbarn > 3))
nextarray[x][y] = 0;
if(choice)
{
if(x == 0 || x == (XSIZE-1) || y == 0 || y == (YSIZE-1) )
nextarray[x][y] = thisarray[x][y];
}
}
}
}