Очередь FIFO для 2D-массива в ANSI C, версия 2

Это модификация моей предыдущей версии.

Мне нужен совет по улучшению алгоритма FIFO для двумерного массива, который я разработал на ANSI C.

Я написал код, который использует этот алгоритм в тестовых целях. Случайные числа помещаются в массив, пока все элементы не заполнятся. Затем программа спрашивает пользователя, какие числа необходимо ввести в 2D-массив, чтобы обновить его. Затем код удаляет самый старый массив, сдвигает все оставшиеся массивы на единицу вверх, а затем добавляет новый массив (как введенный пользователем).

Я прошу проверить код FIFO, fifo_algorithm; окружающий код предназначен только для тестирования. Буду признателен за любые предложения, в которых используется только стандартный C.

код:

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

void random_num_input(void);
void print_random_num_input(void);
void print_new_array(void);
void fifo_algorithm(void);

int user_num[5] = { 0 };
uint16_t big_array[10][5] = { 0 };
uint16_t big_array_copy[10][5] = { 0 };
uint16_t array_print[1] = { 0 };
uint8_t count = 0;
int main()
{
    random_num_input();
    printf("These are the original numbers in the big array:n");
    print_random_num_input();
    while (count < 10)
    {
        printf("Please enter values to swap in:n");
        for (int i = 0; i < 5; i++)
        {
            scanf("%d", &user_num[i]);
        }
           printf("nn");
           fifo_algorithm();
        count++;
    }
}
//stores random numbers between 0-255 into big_array and big_array_copy
void random_num_input(void)
{
    for (int j = 0; j < 10; j++)
    {
        for (int i = 0; i < 5; i++)
        {
            big_array[j][i] = rand() % 255;
        }
    }
    
}
//prints the random values within the big_array 
void print_random_num_input(void)
{
    for (int j = 0; j < 10; j++)
    {
        for (int i = 0; i < 5; i++)
        {
            array_print[0] = big_array[j][i];
            printf("%d,", array_print[0]);
        }
        printf("n");
    }
}
//This algorithm removes the oldest array in big_array_copy (element 9), shifts every
//element up by 1 and stores the user inputted array into element 0. Thus a fifo that updates
//the 2d array with the user input values every time 
void fifo_algorithm(void)
{
    for (int j = 0; j < 10; j++)
    {
        for (int i = 0; i < 5; i++)
        {
            big_array_copy[j][i] = big_array[j][i];
        }
    }
    for (int k = 0; k < 5; k++)
    {
        big_array_copy[10 - 1][k] = 0;
    }
    for (int j = 9; j > 0; j--)
    {
        for (int i = 0; i < 5; i++)
        {
            big_array_copy[j][i] = big_array[j - 1][i];
        }
    }
    for (int i = 0; i < 5; i++)
    {
        big_array_copy[0][i] = user_num[i];
    }
    print_new_array();
    for (int j = 0; j < 10; j++)
    {
        for (int i = 0; i < 5; i++)
        {
            big_array[j][i] = big_array_copy[j][i];
        }
    }
}
//simply prints the new, updated values in big_array_copy
void print_new_array(void)
{
    printf("These array values have been swapped:n ");
    for (int j = 0; j < 10; j++)
    {
        for (int i = 0; i < 5; i++)
        {
            array_print[0] = big_array_copy[j][i];
            printf("%d,", array_print[0]);
        }
        printf("n");
    }
}

Спасибо

1 ответ
1

Хорошее форматирование

Хорошее использование (u)intN_t типы

При печати используйте соответствующий описатель формата: printf("%" PRI16u , array_print[0]);

Избегайте голых магических чисел

Определите константы для гибкости и ясности

// int user_num[5] = { 0] };
//uint16_t big_array[10][5] = { 0 };

#define BIG_ARRAY_MAXJ 10
#define BIG_ARRAY_MAXI 5
int user_num[BIG_ARRAY_MAXI] = { 0 };
uint16_t big_array[BIG_ARRAY_MAXJ][BIG_ARRAY_MAXI] = { 0 };

Вместо 9, использовать BIG_ARRAY_MAXJ - 1, так далее.

Чтобы ответить на вопрос «Я мог бы записать макросы для имен 5 и 10, но я не видел, как это может быть выгодно», комментарий: использование именованных констант передает другим, в том числе и вам позже, взаимосвязь между множеством констант. и их индивидуальное значение.

Глобальные объекты

Как правило, гораздо лучше кодировать использование локальных объектов, чем глобальных.

Вместо

random_num_input(void)

Передайте указатель на массив и его размеры. Если VLA поддерживается:

random_num_input(int jn, int in, uint16_t a[j][i]) {
  for (int j = 0; j < jn; j++) {
    for (int i = 0; i < in; i++) {
        a[j][i] = rand() % 256;
    }
}

Индексирование массива

За большой массивы, рассмотрим size_t вместо int чтобы хорошо обрабатывать большие массивы. size_t это Златовласка размер для определения размера и индексации массива: не слишком маленький, не слишком большой.

За большой массивы, вероятно, также необходимо переместить в выделенную память, а не в фиксированные размеры.

Комментарий / код отключен на 1.

rand() % 255 формирует ценности [0…254], нет [0…255].

// stores random numbers between 0-255 into big_array ...
        big_array[j][i] = rand() % 255;

Учитывать

big_array[j][i] = rand() % 256;
// or 
big_array[j][i] = (uint8_t) rand();

Копирование массивов

С массивами того же размера и типа, что и здесь, можно использовать memcpy().

// for (int j = 0; j < 10; j++) //
//    for (int i = 0; i < 5; i++) {
//        big_array_copy[j][i] = big_array[j][i];
//    }
//}

// if known to be non-overlapping 
memcpy(big_array_copy, big_array, sizeof big_array_copy); 
// else 
memmove(big_array_copy, big_array, sizeof big_array_copy);

Незначительный: более аккуратный принт

Подумайте о том, чтобы не печатать конечный ','. Маленькая причина для глобального array_print[]. Используйте правильный переносимый спецификатор

    char *sep = "";
    for (int i = 0; i < BIG_ARRAY_MAXI; i++) {
        printf("%s%" PRI16u , sep, big_array_copy[j][i]);
        sep = ",";
    }
    printf("n");

  • Спасибо за обзор. Хотя программисту проще писать memcpy, насколько он переносим или более эффективен, чем базовая реализация цикла for?

    — ChrisD91

  • @ ChrisD91 Это портативный и более линейно эффективен для больших массивов. При рассмотрении эффективности лучше всего сосредоточить внимание на большой O и ясность кода, чем тратить слишком много усилий на линейные проблемы.

    — chux — Восстановить Монику


Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *