使用 `curses.h` 库和随机数模拟矩阵数字雨的程序启动时间非常长

问题描述 投票:0回答:1

我正在尝试使用

curses.h
库和随机数编写一个模拟矩阵数字雨的程序。该程序似乎可以正常运行,但该程序的启动速度非常慢(在 MacOS 11.6.1、2.8GHz 四核英特尔酷睿 i7 上最多需要 10 秒)。这是为什么?它与随机数的使用方式有关吗?我怎样才能改进代码,使程序的启动变得活泼

这是我启动程序时的使用快照:

PID    COMMAND          %CPU TIME     #TH   #WQ #PORTS MEM    PURG  CMPRS  PGRP  PPID  STATE    BOOSTS      %CPU_ME  %CPU_OTHRS UID FAULTS   COW     MSGSENT   MSGRECV   SYSBSD    SYSMACH   CSW       PAGEINS IDLEW   POWER INSTRS      CYCLES     USER                   #MREGS RPRVT VPRVT VSIZE KPRVT KSHRD
55710  matrix_digital_r 99.7 00:06.77 1/1   0   10     768K   0B    0B     55709 55709 running  *0[1]       0.00000  0.00000    501 318      39      16        8         165       40        1333+     0       0       99.7  12800790099 3889519761 user01                  N/A    N/A   N/A   N/A   N/A   N/A  

10-20 秒后这里是相同的用法:

PID    COMMAND          %CPU TIME     #TH   #WQ #PORTS MEM    PURG  CMPRS  PGRP  PPID  STATE    BOOSTS      %CPU_ME  %CPU_OTHRS UID FAULTS   COW     MSGSENT   MSGRECV   SYSBSD    SYSMACH   CSW       PAGEINS IDLEW   POWER INSTRS      CYCLES     USER                   #MREGS RPRVT VPRVT VSIZE KPRVT KSHRD
65886  matrix_digital_r 0.4   00:36.54 1     0   10     632K   0B     0B     65846 65846 sleeping *0[1]        0.00000  0.00000    501 284      39      18        8         381+      39        14329+    0       19+      0.5   8935555     8242181    user01                  N/A    N/A   N/A   N/A   N/A   N/A  

(PID 不一样,因为它是 2 次不同的运行,但是,一次运行的结果是相同的)。人们可以注意到

%CPU
INSTRS
CYCLES
的数字在一段时间后急剧减少,并且
STATE
running
变为
sleeping

代码如下:

/*matrix_digital_rain.c*/

#include <curses.h>
#include <unistd.h>
#include <locale.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include "set_characters.h"
#include "hyperparameters.h"
#include "functions.h"

int main() {
  srand((unsigned) time(NULL));   // Initialization, should only be called once.
  setlocale(LC_ALL, "");
  int max_y = 0, max_x = 0;
  Drop_init_vals drop_init_vals01;
  //Drop_init_vals drop_init_vals02;
  //Drop_init_vals drop_init_vals03;
  //Drop_init_vals drop_init_vals04;
  //Drop_init_vals drop_init_vals05;
  //Drop_init_vals drop_init_vals06;
  //Drop_init_vals drop_init_vals07;
  //Drop_init_vals drop_init_vals08;
  //Drop_init_vals drop_init_vals09;

  int iter_start01 = rand() % ITER_START_RANGE; 
  //int iter_start02 = rand() % ITER_START_RANGE; 
  //int iter_start03 = rand() % ITER_START_RANGE; 
  //int iter_start04 = rand() % ITER_START_RANGE; 
  //int iter_start05 = rand() % ITER_START_RANGE; 
  //int iter_start06 = rand() % ITER_START_RANGE; 
  //int iter_start07 = rand() % ITER_START_RANGE; 
  //int iter_start08 = rand() % ITER_START_RANGE; 
  //int iter_start09 = rand() % ITER_START_RANGE; 

  int iter = 0;
 
  initscr();
  noecho();
  curs_set(FALSE);
  start_color();
  init_color(CUSTOM_GREEN1, 90, 280, 90);
  init_color(CUSTOM_GREEN2, 100, 500, 100);
  init_color(CUSTOM_GREEN3, 100, 900, 100);
  init_color(COLOR_BLACK, 0, 0, 0);

  char char_set[DIM_1_ARRAY_STRING][BYTES_PER_CHAR] = {SET_CHAR};
  char str_display[DIM_0_ARRAY_STRING][DIM_1_ARRAY_STRING][BYTES_PER_CHAR];
  for (int i = 0; i<DIM_0_ARRAY_STRING; i++){
    //for (int j = 0; j<LEN_STRING_DISPLAY; j++){
    for (int j = 0; j<DIM_1_ARRAY_STRING; j++){
      strcpy(str_display[i][j], char_set[rand() % N_COMMAS]);
    }
  }

  while(1) 
  {
    getmaxyx(stdscr, max_y, max_x);
 
    clear();

    if (iter % ITER_REFRESH == iter_start01){
      drop_init_vals01 = random_drop_init_vals(drop_init_vals01, iter);
      drop_init_vals01.n_dim_str = 0;
    }

    print_n_string_from_string_array_struct(
      drop_init_vals01,
      str_display,
      iter
    );

/*
    if (iter % ITER_REFRESH == iter_start02){
      drop_init_vals02 = random_drop_init_vals(drop_init_vals02, iter);
      drop_init_vals02.n_dim_str = 1;
    }
    print_n_string_from_string_array_struct(
      drop_init_vals02,
      str_display,
      iter
    );


    if (iter % ITER_REFRESH == iter_start03){
      drop_init_vals03 = random_drop_init_vals(drop_init_vals03, iter);
      drop_init_vals03.n_dim_str = 2;
    }
    print_n_string_from_string_array_struct(
      drop_init_vals03,
      str_display,
      iter
    );

    if (iter % ITER_REFRESH == iter_start04){
      drop_init_vals04 = random_drop_init_vals(drop_init_vals04, iter);
      drop_init_vals04.n_dim_str = 3;
    }
    print_n_string_from_string_array_struct(
      drop_init_vals04,
      str_display,
      iter
    );


    if (iter % ITER_REFRESH == iter_start05){
      drop_init_vals05 = random_drop_init_vals(drop_init_vals05, iter);
      drop_init_vals05.n_dim_str = 4;
    }
    print_n_string_from_string_array_struct(
      drop_init_vals05,
      str_display,
      iter
    );


    if (iter % ITER_REFRESH == iter_start06){
      drop_init_vals06 = random_drop_init_vals(drop_init_vals06, iter);
      drop_init_vals06.n_dim_str = 5;
    }
    print_n_string_from_string_array_struct(
      drop_init_vals06,
      str_display,
      iter
    );


    if (iter % ITER_REFRESH == iter_start07){
      drop_init_vals07 = random_drop_init_vals(drop_init_vals07, iter);
      drop_init_vals07.n_dim_str = 6;
    }
    print_n_string_from_string_array_struct(
      drop_init_vals07,
      str_display,
      iter
    );

    if (iter % ITER_REFRESH == iter_start08){
      drop_init_vals08 = random_drop_init_vals(drop_init_vals08, iter);
      drop_init_vals08.n_dim_str = 7;
    }
    print_n_string_from_string_array_struct(
      drop_init_vals08,
      str_display,
      iter
    );

    if (iter % ITER_REFRESH == iter_start09){
      drop_init_vals09 = random_drop_init_vals(drop_init_vals09, iter);
      drop_init_vals09.n_dim_str = 8;
    }
    print_n_string_from_string_array_struct(
      drop_init_vals09,
      str_display,
      iter
    );

*/

    iter++;

    refresh();
    usleep(DELAY);
 
  }
  attron(COLOR_PAIR(1));
  attron(COLOR_PAIR(2));
  attron(COLOR_PAIR(3));
 
  endwin();
  refresh();
  use_default_colors();
}
/*functions.c*/

#include "hyperparameters.h"
#include "functions.h"
#include <curses.h>
#include <time.h>
#include <stdlib.h>


void print_GREEN1(int y1, int x1, int i, int n_string, int n_dim_str, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR])
{
  init_pair(1, CUSTOM_GREEN1, COLOR_BLACK);
  attron(COLOR_PAIR(1));
  mvprintw(y1+i-n_string, x1, str_display[n_dim_str][i]);
}

void print_GREEN2(int y1, int x1, int i, int n_string, int n_dim_str, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR])
{
  init_pair(2, CUSTOM_GREEN2, COLOR_BLACK);
  attron(COLOR_PAIR(2));
  mvprintw(y1+i-n_string, x1, str_display[n_dim_str][i]);
}

void print_GREEN3(int y1, int x1, int i, int n_string, int n_dim_str, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR])
{
  init_pair(3, CUSTOM_GREEN3, COLOR_BLACK);
  attron(COLOR_PAIR(3));
  mvprintw(y1+i-n_string, x1, str_display[n_dim_str][i]);
}


Drop_init_vals random_drop_init_vals(Drop_init_vals drop_init_vals, int iter)
{
  

  struct timespec ts;
  clock_gettime(CLOCK_MONOTONIC, &ts);

  srand((unsigned int) (time_t)ts.tv_nsec);

  drop_init_vals.y1 = 0;
  drop_init_vals.x1 = rand() % X1_RANGE;
  drop_init_vals.n_string = 5 + rand() % N_STRING_RANGE;
  drop_init_vals.iter_init = iter;
  return drop_init_vals;
}

void print_n_string_from_string_array_struct(Drop_init_vals drop_init_vals, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR], int iter)
{
  int y1 = drop_init_vals.y1;
  int x1 = drop_init_vals.x1;
  int n_string = drop_init_vals.n_string;
  int n_dim_str = drop_init_vals.n_dim_str;
  int y_start = iter - drop_init_vals.iter_init;


  int count = 0;
  for (int i=y_start; i<y_start+n_string; i++)
  {
    if (count == 0 || count == 1){
      print_GREEN1(y1, x1, i, n_string, n_dim_str, &str_display[n_dim_str]);
    }
    else if (count == 2 || count == 3 || count == 4){
      print_GREEN2(y1, x1, i, n_string, n_dim_str, &str_display[n_dim_str]);
    }
    else{
      print_GREEN3(y1, x1, i, n_string, n_dim_str, &str_display[n_dim_str]);
    }
    count++;
  }
}

//int gen_rand_int(){
//  struct timespec ts;
//  clock_gettime(CLOCK_MONOTONIC, &ts);
//
//  srand((unsigned int) (time_t)ts.tv_nsec);
//
//  return rand();
//}
/*functions.h*/

#ifndef FUNCTIONS_H
#define FUNCTIONS_H

typedef struct {
  int x1, y1, n_string, n_dim_str, iter_init; 
} Drop_init_vals ;


int gen_rand_int(void);
void print_n_string_from_string_array_struct(Drop_init_vals drop_init_vals, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR], int iter);
Drop_init_vals random_drop_init_vals(Drop_init_vals drop_init_vals, int iter);

void print_GREEN1(int y1, int x1, int i, int n_string, int n_dim_str, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR]);
void print_GREEN2(int y1, int x1, int i, int n_string, int n_dim_str, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR]);
void print_GREEN3(int y1, int x1, int i, int n_string, int n_dim_str, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR]);



#endif
/*hyperparameters.h*/

#ifndef HYPERPARAMETERS_H
#define HYPERPARAMETERS_H

#define DELAY 60000 //480000
#define CUSTOM_GREEN1 8
#define CUSTOM_GREEN2 9
#define CUSTOM_GREEN3 10
#define COLOR_BLACK 0
#define DIM_0_ARRAY_STRING 20
#define DIM_1_ARRAY_STRING 100
#define BYTES_PER_CHAR 5

#define LEN_STRING_DISPLAY 100 
#define MAX_Y 100 
#define MAX_X 100 
#define N_STRING_MAX 20

#define Y1_RANGE 10
#define X1_RANGE 30
#define N_STRING_RANGE 5
#define Y_START_RANGE 15
#define ITER_REFRESH 60
#define ITER_START_RANGE 25


#endif
/*set_characters.h*/

#ifndef SET_CHARACTERS_H
#define SET_CHARACTERS_H

#define N_COMMAS 56

#define SET_CHAR "ㇰ", "ㇱ", "ㇲ","ㇳ","ㇴ","ㇵ","ㇶ","ㇷ","ㇸ","ㇹ","ㇺ","ㇻ","ㇼ","ㇽ","ㇾ", "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "<", "=", ">", "T", "H","E", "M", "A", "T", "R", "I", "X", "Z", ":", "・", ".", "=", "*", "+", "-", "<", ">", "¦", "|", "#", "_"


#endif
#makefile

CC = gcc 
CFLAGS = -Wextra -Wall -Wfloat-equal -Wundef -Wshadow -Wpointer-arith -Wcast-align -Wstrict-prototypes -Wstrict-overflow=5 -Wwrite-strings -Waggregate-return -Wcast-qual -Wswitch-default -Wswitch-enum -Wconversion -Wunreachable-code -pedantic -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition

BINC=matrix_digital_rain

allc: $(BINC) 

$(BINC): $(BINC).o functions.o
    $(CC) $(CFLAGS) $(BINC).o functions.o -o $@ -lncurses

$(BINC).o: $(BINC).c set_characters.h hyperparameters.h set_characters.h
    $(CC) $(CFLAGS) -c $(BINC).c

functions.o: functions.c functions.h
    $(CC) $(CFLAGS) -c functions.c 

clean:
    $(RM) -rf $(BINC) *.dSYM *.o

runc: allc
    ./$(BINC)

编辑

根据评论:我将代码更改如下:

  • 我在所有文件的
    DIM_2_ARRAY_STRING
    中重命名了
    BYTES_PER_CHAR
    ,并将其值从4更改为5
  • 我将
    DIM_1_ARRAY_STRING
    的值从200减少到100
  • matrix_digital_rain.c
    我在
    for (int j = 0; j<LEN_STRING_DISPLAY; j++){
    中更改了
    for (int j = 0; j<DIM_1_ARRAY_STRING; j++){
  • makefile
    中,我将
    $(BINC): $(BINC).c $(BINC).o functions.o
    行更改为
    $(BINC): $(BINC).o functions.o

编辑2

所以我听从了John Bollinger的建议,做了一个

drop_init_vals
的数组。这解决了启动缓慢的问题(非常感谢@JohnBollinger),并且在掉落次数少的情况下运行正常(
#define N_DROPS
hyperparameters.h
)但是当屏幕上要显示很多字符时,字符会闪烁,如果我将滴数增加到,比方说,15,我会出现段错误。

/*matrix_digital_rain.c*/

#include <curses.h>
#include <unistd.h>
#include <locale.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include "set_characters.h"
#include "hyperparameters.h"
#include "functions.h"

int main() {
  srand((unsigned) time(NULL));   // Initialization, should only be called once.
  setlocale(LC_ALL, "");
  int max_y = 0, max_x = 0;
  //Drop_init_vals drop_init_vals_array[N_DROPS] ;
  Drop_init_vals drop_init_vals_array[N_DROPS] ;

  //drop_init_vals_array[N_DROPS] = drop_init_vals_array_to_zero(&drop_init_vals_array[N_DROPS]);
  for (int drop_num = 0; drop_num < N_DROPS; drop_num++){

    drop_init_vals_array[drop_num] = drop_init_vals_array_to_zero(drop_init_vals_array[drop_num]);
    drop_init_vals_array[drop_num].rand_iter_start = rand() % ITER_START_RANGE;
  } 

  int iter = 0;
 
  initscr();
  noecho();
  curs_set(FALSE);
  start_color();
  init_color(CUSTOM_GREEN1, 90, 280, 90);
  init_color(CUSTOM_GREEN2, 100, 500, 100);
  init_color(CUSTOM_GREEN3, 100, 900, 100);
  init_color(COLOR_BLACK, 0, 0, 0);

  char char_set[DIM_1_ARRAY_STRING][BYTES_PER_CHAR] = {SET_CHAR};
  char str_display[DIM_0_ARRAY_STRING][DIM_1_ARRAY_STRING][BYTES_PER_CHAR];
  for (int i = 0; i<DIM_0_ARRAY_STRING; i++){
    for (int j = 0; j<DIM_1_ARRAY_STRING; j++){
      strcpy(str_display[i][j], char_set[rand() % N_COMMAS]);
    }
  }

  while(1) 
  {
    getmaxyx(stdscr, max_y, max_x);
 
    clear();

    for (int drop_num = 0; drop_num<N_DROPS; drop_num++){

      if (iter % ITER_REFRESH == drop_init_vals_array[drop_num].rand_iter_start){
        //drop_init_vals_array[drop_num] = random_drop_init_vals(drop_init_vals_array[drop_num], iter);
        drop_init_vals_array[drop_num].n_dim_str = drop_num;
        drop_init_vals_array[drop_num].x1 = rand() % X1_RANGE;
        drop_init_vals_array[drop_num].n_string = 20 + rand() % N_STRING_RANGE;
        drop_init_vals_array[drop_num].iter_init = iter;
        drop_init_vals_array[drop_num].rand_iter_start_bool = 1;
      }

      if(drop_init_vals_array[drop_num].rand_iter_start_bool == 1){
        print_n_string_from_string_array_struct(
          drop_init_vals_array[drop_num],
          str_display,
          iter
        );
        //if (drop_init_vals_array[drop_num].iter_init == ITER_REFRESH){
        if (iter == drop_init_vals_array[drop_num].iter_init + ITER_REFRESH){
          drop_init_vals_array[drop_num].rand_iter_start_bool = 0;
        }
      }
    }

    iter++;

    refresh();
    usleep(DELAY);
 
  }
  attron(COLOR_PAIR(1));
  attron(COLOR_PAIR(2));
  attron(COLOR_PAIR(3));
 
  endwin();
  refresh();
  use_default_colors();
}
/*functions.c*/

#include "hyperparameters.h"
#include "functions.h"
#include <curses.h>
#include <time.h>
#include <stdlib.h>


void print_GREEN1(int y1, int x1, int i, int n_string, int n_dim_str, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR])
{
  init_pair(1, CUSTOM_GREEN1, COLOR_BLACK);
  attron(COLOR_PAIR(1));
  mvprintw(y1+i-n_string, x1, str_display[n_dim_str][i]);
}

void print_GREEN2(int y1, int x1, int i, int n_string, int n_dim_str, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR])
{
  init_pair(2, CUSTOM_GREEN2, COLOR_BLACK);
  attron(COLOR_PAIR(2));
  mvprintw(y1+i-n_string, x1, str_display[n_dim_str][i]);
}

void print_GREEN3(int y1, int x1, int i, int n_string, int n_dim_str, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR])
{
  init_pair(3, CUSTOM_GREEN3, COLOR_BLACK);
  attron(COLOR_PAIR(3));
  mvprintw(y1+i-n_string, x1, str_display[n_dim_str][i]);
}

Drop_init_vals drop_init_vals_to_zero(void)
{
  Drop_init_vals drop_init_vals;
  drop_init_vals.y1 = 0;
  drop_init_vals.x1 = 0;
  drop_init_vals.n_string = 0;
  drop_init_vals.iter_init = 0;
  drop_init_vals.n_dim_str = 0;

  return drop_init_vals;
}

//Drop_init_vals random_drop_init_vals(Drop_init_vals drop_init_vals, int iter)
Drop_init_vals random_drop_init_vals(Drop_init_vals drop_init_vals)
{
  
  //drop_init_vals.y1 = 0;
  drop_init_vals.x1 = rand() % X1_RANGE;
  drop_init_vals.n_string = 20 + rand() % N_STRING_RANGE;
  //drop_init_vals.iter_init = iter;
  return drop_init_vals;
}

void print_n_string_from_string_array_struct(Drop_init_vals drop_init_vals, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR], int iter)
{
  int y1 = drop_init_vals.y1;
  int x1 = drop_init_vals.x1;
  int n_string = drop_init_vals.n_string;
  int n_dim_str = drop_init_vals.n_dim_str;
  int y_start = iter - drop_init_vals.iter_init;


  int count = 0;
  for (int i=y_start; i<y_start+n_string; i++)
  {
    if (count == 0 || count == 1){
      print_GREEN1(y1, x1, i, n_string, n_dim_str, &str_display[n_dim_str]);
    }
    else if (count == 2 || count == 3 || count == 4){
      print_GREEN2(y1, x1, i, n_string, n_dim_str, &str_display[n_dim_str]);
    }
    else{
      print_GREEN3(y1, x1, i, n_string, n_dim_str, &str_display[n_dim_str]);
    }
    count++;
  }
}

//int gen_rand_int(){
//  struct timespec ts;
//  clock_gettime(CLOCK_MONOTONIC, &ts);
//
//  srand((unsigned int) (time_t)ts.tv_nsec);
//
//  return rand();
//}

Drop_init_vals drop_init_vals_array_to_zero(Drop_init_vals drop_init_vals)
{

  for (int drop_num = 0; drop_num < N_DROPS; drop_num++){
  //Drop_init_vals drop_init_vals;
    drop_init_vals.y1 = 0;
    drop_init_vals.x1 = 0;
    drop_init_vals.n_string = 0;
    drop_init_vals.iter_init = 0;
    drop_init_vals.n_dim_str = 0;
  }

  return drop_init_vals;
}
/*functions.h*/

#ifndef FUNCTIONS_H
#define FUNCTIONS_H

typedef struct {
  int x1, y1, n_string, n_dim_str, iter_init, rand_iter_start, rand_iter_start_bool; 
} Drop_init_vals ;


int gen_rand_int(void);
void print_n_string_from_string_array_struct(Drop_init_vals drop_init_vals, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR], int iter);
//Drop_init_vals random_drop_init_vals(Drop_init_vals drop_init_vals, int iter);

Drop_init_vals random_drop_init_vals(Drop_init_vals drop_init_vals);
Drop_init_vals drop_init_vals_to_zero(void);

void print_GREEN1(int y1, int x1, int i, int n_string, int n_dim_str, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR]);
void print_GREEN2(int y1, int x1, int i, int n_string, int n_dim_str, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR]);
void print_GREEN3(int y1, int x1, int i, int n_string, int n_dim_str, char str_display[][DIM_1_ARRAY_STRING][BYTES_PER_CHAR]);


//Drop_init_vals drop_init_vals_array_to_zero(Drop_init_vals drop_init_vals_array[N_DROPS]);
Drop_init_vals drop_init_vals_array_to_zero(Drop_init_vals drop_init_vals);

#endif
/*set_characters.h*/

#ifndef SET_CHARACTERS_H
#define SET_CHARACTERS_H

#define N_COMMAS 56

#define SET_CHAR "ㇰ", "ㇱ", "ㇲ","ㇳ","ㇴ","ㇵ","ㇶ","ㇷ","ㇸ","ㇹ","ㇺ","ㇻ","ㇼ","ㇽ","ㇾ", "+", ",", "-", ".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "<", "=", ">", "T", "H","E", "M", "A", "T", "R", "I", "X", "Z", ":", "・", ".", "=", "*", "+", "-", "<", ">", "¦", "|", "#", "_"


#endif
/*hyperparameters.h*/

#ifndef HYPERPARAMETERS_H
#define HYPERPARAMETERS_H

#define DELAY 60000 //480000
#define CUSTOM_GREEN1 8
#define CUSTOM_GREEN2 9
#define CUSTOM_GREEN3 10
#define COLOR_BLACK 0
#define DIM_0_ARRAY_STRING 20
#define DIM_1_ARRAY_STRING 100
#define BYTES_PER_CHAR 5

#define LEN_STRING_DISPLAY 100 
#define MAX_Y 100 
#define MAX_X 100 
#define N_STRING_MAX 20
#define N_DROPS 16

#define Y1_RANGE 20
#define X1_RANGE 30
#define N_STRING_RANGE 5
#define Y_START_RANGE 15
#define ITER_REFRESH 80
#define ITER_START_RANGE 80


#endif
#makefile

CC = gcc 
CFLAGS = -O2 -Wextra -Wall -Wfloat-equal -Wundef -Wshadow -Wpointer-arith -Wcast-align -Wstrict-prototypes -Wstrict-overflow=5 -Wwrite-strings -Waggregate-return -Wcast-qual -Wswitch-default -Wswitch-enum -Wconversion -Wunreachable-code -pedantic -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition

BINC=matrix_digital_rain

allc: $(BINC) 

$(BINC): $(BINC).o functions.o
    $(CC) $(CFLAGS) -ggdb3 $(BINC).o functions.o -o $@ -lncurses

$(BINC).o: $(BINC).c set_characters.h hyperparameters.h set_characters.h
    $(CC) $(CFLAGS) -c $(BINC).c

functions.o: functions.c functions.h
    $(CC) $(CFLAGS) -c functions.c 

clean:
    $(RM) -rf $(BINC) *.dSYM *.o

runc: allc
    ./$(BINC)
c matrix random startup curses
1个回答
1
投票

主要问题似乎是您正在使用

drop_init_vals01
-
drop_init_vals09
未初始化。考虑这个......

  int iter = 0;

  // ...

  while (1)
  {

    // ...

    if (iter % ITER_REFRESH == iter_start09){
      drop_init_vals09 = random_drop_init_vals(drop_init_vals09, iter);
      drop_init_vals09.n_dim_str = 8;
    }
    print_n_string_from_string_array_struct(
      drop_init_vals09,
      str_display,
      iter
    );

    // ...

    iter++;

    // ...
}

记住在循环进入之前没有一个

drop_init_valsXX
被初始化,观察
drop_init_vals09
在循环的每次迭代中被传递给
print_n_string_from_string_array_struct()
,但只有当
iter
的值达到
iter_start09
drop_init_vals09 
已填写。这同样适用于所有其他
drop_init_valsXX
变量,包括
drop_init_vals01
。该程序因此表现出未定义的行为。

我不确定为什么当您使用九个变量时与仅使用一个变量时 UB 的表现如此不同,但“未定义”就是它所说的。

补充说明:

  • 在我通过在 Valgrind 下运行程序确定问题的性质后,我清楚了问题的原因

  • 程序请求(更多)使用数组。注意

    matrix_digital_rain.c
    中的所有代码重复。该源可以缩小到其当前大小的一半以下,同时通过使用
    Drop_init_vals
    对象数组而不是该类型的九个独立变量(结合使用
    int 数组)变得更加灵活和健壮
    而不是
    int
    的九个单独的
    iter_start_vals
    变量)。然后,您对
    while
    循环中的那些进行内部循环,而不是为每个循环单独编写代码。

© www.soinside.com 2019 - 2024. All rights reserved.