将数组写入控制台的更快方法?

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];
            }

        }
    }

}