Reviews de code - TP 2

/// Addition de deux entier de gauss /// Premier entier de gauss z_1 /// Deuxième entier de gauss z_2 /// return : z_1 + z_2 gi addition(gi z_1, gi z_2) { gi z; z.re = z_1.re + z_2.re; z.im = z_1.im + z_2.im; return z; }
// Première version de somme moyenne // utilise la classe en_fl qui permet de renvoyé un entier et un flottant. struct en_fl somme_moyenne_bad (int t[], int n) { int somme ; for (int i= 0; i < n; i++){somme += t[i]; } struct en_fl rep ; rep.en = somme ; rep.fl = (float) somme / n ; return rep ; } void somme_moyenne(int t[] , int taille, int* ptr_somme, float* ptr_moyenne) { int somme ; for (int i= 0; i < taille; i++){somme += t[i]; } *ptr_somme = somme ; *ptr_moyenne = (float) somme / taille ; }

Game of life

// a few helper functions int liveliness(CellState s) { if (s == ALIVE) { return 1; } else { return 0; } } void swap_live(CellState* s) { if (*s == ALIVE) { *s = DEAD; } else { *s = ALIVE; } } // in C, the "%" infix operator is the remainder operation, not the mathematical // modulus. The latter is what we need and is implemented by this function. int mod(int x) { return ((x % N) + N) % N; }
// timer to update the simulation every 0.1 seconds typedef struct { double start; double length; } Timer; void Timer_start(Timer* timer, double length) { timer->start = GetTime(); timer->length = length; } bool Timer_finished(Timer* timer) { return GetTime() - timer->start >= timer->length; }
... // rendering BeginDrawing(); ClearBackground(BLACK); for (int x = 0; x < N; x++) { for (int y = 0; y < N; y++) { if ((*current)[AT(x, y)] == ALIVE) { DrawRectangle(x * 10, y * 10, 10, 10, WHITE); } } } EndDrawing(); ...

Brainfuck interpreter

/** * @file main.c * @brief A simple Brainfuck interpreter. * ----- * @created Tu Sep 2024 * @author Alexandre DOUARD * ----- * @last modified Sun Sep 22 2024 * @modified by Alexandre DOUARD * ----- * @copyright (c) 2024 Ecole Normal Superieur Lyon */ #include "brainfuck.h" /** * @brief Prints the usage instructions for the Brainfuck interpreter. * * This function displays the correct usage of the program when incorrect * arguments are passed by the user. * * @param av[] The array of arguments passed to the program. The first element * is the program's name. */ void print_usage(char *av[]) { printf("USAGE %s <filename.bf>\n", av[0]); } /** * @brief Main entry point for the Brainfuck interpreter. * * This function checks if the correct number of arguments is passed, and * either proceeds to interpret the Brainfuck file or prints the usage * instructions. If the number of arguments is incorrect, it returns a failure * code. * * @param ac The number of arguments passed to the program. * @param av[] The array of arguments passed to the program. * @return EXIT_FAILURE if the incorrect number of arguments is passed; * otherwise, it returns the result of the brainfuck function. */ int main(int ac, char *av[]) { if (ac != 2) { print_usage(av); return EXIT_FAILURE; } return brainfuck(av) ? FAILURE_EXIT : SUCCESS_EXIT; }
/** * @struct Ptr * @brief Represents a cell in the Brainfuck memory tape. * * This structure is used to represent each memory cell in the Brainfuck interpreter. * Each cell has a value and pointers to the previous and next cells. */ typedef struct Ptr { struct Ptr *next; struct Ptr *prec; char val; } Ptr; // ptr_handling.c Ptr *create_ptr(void); Ptr *add_to_next(Ptr *ptr, Ptr *nxt); Ptr *add_to_prec(Ptr *ptr, Ptr *prec); void destroy_ptr(Ptr **ptr); // operations.c Ptr *incr_ptr(Ptr *ptr); Ptr *decr_ptr(Ptr *ptr); Ptr *incr_ptr_v(Ptr *ptr); Ptr *decr_ptr_v(Ptr *ptr); Ptr *read_ptr(Ptr *ptr); Ptr *write_ptr(Ptr *ptr);
/** * @brief Creates a new memory cell for the Brainfuck pointer. * * This function allocates memory for a new pointer and initializes its value to 0, * with no previous or next cells linked. * * @return A pointer to the newly created memory cell, or NULL if memory allocation fails. */ Ptr *create_ptr(void) { Ptr *tmp = malloc(sizeof(Ptr)); if (tmp == NULL) return NULL; tmp->next = NULL; tmp->prec = NULL; tmp->val = 0; return tmp; } /** * @brief Recursively destroys the next linked memory cells. * * This function recursively frees all memory cells linked to the given pointer via the `next` pointer. * * @param ptr The pointer to the current memory cell. */ static void destroy_ptr_next(Ptr *ptr) { if (ptr->next != NULL) { destroy_ptr_next(ptr->next); free(ptr); } } /** * @brief Recursively destroys the previous linked memory cells. * * This function recursively frees all memory cells linked to the given pointer via the `prec` pointer. * * @param pt The pointer to the current memory cell. */ static void destroy_ptr_prec(Ptr *ptr) { if (ptr->prec != NULL) { destroy_ptr_prec(ptr->prec); free(ptr); } if (ptr != NULL) free(ptr); }
/** * @brief Moves the pointer to the next memory cell. * * This function moves the Brainfuck pointer to the next memory cell to the right. * If the next cell does not exist, it creates a new cell and links it to the current one. * * @param ptr The current memory pointer. * @return The pointer to the next memory cell, or NULL if an error occurs. */ Ptr *incr_ptr(Ptr *ptr) { Ptr *tmp = NULL; if (ptr == NULL) return NULL; if (ptr->next != NULL) return ptr->next; tmp = create_ptr(); if (tmp == NULL || add_to_next(ptr, tmp) == NULL || ptr->next == NULL) return NULL; return ptr->next; } /** * @brief Increments the value at the current memory cell. * * This function increases the value stored at the current memory cell by 1. * * @param ptr The current memory pointer. * @return The updated memory pointer, or NULL if the pointer is NULL. */ Ptr *incr_ptr_v(Ptr *ptr) { if (ptr == NULL) return NULL; ptr->val++; return ptr; }
/** * @def CLEANUP(X) * @brief Automatically calls the specified cleanup function when the variable goes out of scope. * * This attribute is used for automatic resource cleanup by specifying a function `X` to call when the variable goes out of scope. * * @param X The function to be called for cleanup. */ #define CLEANUP(X) __attribute__((cleanup(X)))
/** * @brief Reads the content of a file into a dynamically allocated string. * * This function opens the file at the specified path, reads its content into * memory, and returns it as a null-terminated string. If the file cannot be * opened or read, the function returns NULL. * * @param path The path to the file to read. * @return A pointer to the dynamically allocated string containing the file content, * or NULL if the file could not be opened or read. */ char *contentFile(char *path) { struct stat s = {0}; int fd = 0; char *content = NULL; int tmp = 0; if (stat(path, &s)) return NULL; fd = open(path, O_RDONLY); if (fd < 0) return NULL; content = malloc(sizeof(char) * (s.st_size + 1)); tmp = read(fd, content, s.st_size); content[s.st_size] = 0; if (tmp <= 0) free(content); close(fd); return content; }
/** * @brief Executes Brainfuck code by processing each instruction. * * This function iterates through the Brainfuck code and executes each instruction, * handling loops and performing the necessary pointer manipulations. It ensures * correct memory management and error handling during execution. * * @param str The Brainfuck code as a string. * @param pc A pointer to the program counter. * @param ptr The memory pointer. * @return SUCCESS_RETURN on successful execution; FAILURE_RETURN on error. */ int exec(char *str, int *pc, Ptr *ptr) { int tmp = 0; while (str[*pc]) { if (str[*pc] == '[') { tmp = (*pc); (*pc)++; if (exec_on_loop(str, pc, &ptr) == FAILURE_RETURN) return FAILURE_RETURN; if (ptr->val) *pc = tmp; continue; } if (exec_ope(str[*pc], &ptr) == FAILURE_RETURN) return FAILURE_RETURN; (*pc)++; } return SUCCESS_RETURN; }
/** * @brief Executes Brainfuck code by processing each instruction. * * This function iterates through the Brainfuck code and executes each instruction, * handling loops and performing the necessary pointer manipulations. It ensures * correct memory management and error handling during execution. * * @param str The Brainfuck code as a string. * @param pc A pointer to the program counter. * @param ptr The memory pointer. * @return SUCCESS_RETURN on successful execution; FAILURE_RETURN on error. */ int exec(char *str, int *pc, Ptr *ptr) { int tmp = 0; while (str[*pc]) { if (str[*pc] == '[') { tmp = (*pc); (*pc)++; if (exec_on_loop(str, pc, &ptr) == FAILURE_RETURN) return FAILURE_RETURN; if (ptr->val) *pc = tmp; continue; } if (exec_ope(str[*pc], &ptr) == FAILURE_RETURN) return FAILURE_RETURN; (*pc)++; } return SUCCESS_RETURN; }

https://gitlab.aliens-lyon.fr/adouard/brainfuck_interpreter

Commentaires

struct en_fl rep = {.en = somme, .fl = (float) somme / n}; typedef struct en_fl enfl; return (struct en_fl) {.en = somme, .fl = (float) somme / n}; if (s == ALIVE) { return 1; } else { return 0; } return (s == ALIVE) ? 1 : 0; inline bool Timer_finished(Timer timer) { return GetTime() - timer.start >= timer.length; } Ptr *incr_ptr(Ptr *ptr); Cell *get_cell_right(Cell* cell); Cell *incr(Cell *cell); int *p = malloc(sizeof(int); if(!p) { printf("Out of memory!\n"); exit(EXIT_FAILURE); }