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