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