Salut,
fort de ma lecture rapide du tutoriel C pour me remettre dans le bain de ce merveilleux langage, j’ai décidé de me pencher sur la quesion de la généricité (notamment avec les pointeurs génériques) pour voir ce que ça vaut, en implémentant des tableaux génériques redimensionnables.
Voilà ce que ça donne :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define GET_INT(t, i) *((int *)t.get(&t, i))
typedef struct vector Vector;
struct vector {
size_t data_size;
void *data;
size_t size;
size_t capacity;
void* (*get)(Vector*, int);
void (*push)(Vector*, void*);
void (*set)(Vector*, int, void*);
};
void* vector_get(Vector* this, int index) {
// arithmetic operator is invalid on void pointer
return (void *)((size_t)this->data + this->data_size * index);
}
void vector_set(Vector* this, int index, void* val) {
void *to = (void *)((size_t)this->data + this->data_size * index);
memcpy(to, val, this->data_size);
}
void vector_push(Vector* this, void* val) {
if (this->size == this->capacity) {
this->capacity = this->capacity * 2 + 1;
this->data = realloc((char *)this->data, this->capacity * this->data_size);
}
this->size++;
vector_set(this, this->size-1, val);
}
Vector vector_new(size_t data_size) {
Vector tmp = {
.data_size = data_size,
.data = NULL,
.size = 0,
.capacity = 0,
.get = vector_get,
.set = vector_set,
.push = vector_push
};
return tmp;
}
void vector_free(Vector *t) {
free(t->data);
t->size = 0;
t->capacity = 0;
}
int main() {
Vector t = vector_new(sizeof(int));
for (int i=0; i<10; ++i) t.push(&t, &i);
for (int i=0; i<t.size; ++i) printf("%d ", GET_INT(t, i));
printf("\n");
for (int i=0; i<t.size; ++i) {
int sqr = i * i;
t.set(&t, i, &sqr);
}
for (int i=0; i<t.size; ++i) printf("%d ", GET_INT(t, i));
printf("\n");
vector_free(&t);
return 0;
}
Si quelqu’un a déjà fait ce genre de choses en C, ça m’intéresserait de savoir dans quel contexte :). Plus généralement n’importe quelle critique ou remarque par rapport au code est la bienvenue !
EDIT: à la lecture de code je vois souvent les pointeurs écrits type *ptr
mais malgré tout je trouve que l’écrire type* ptr
(qui indique mieux que la variable ptr
a le type type*
à mon gout). Des avis ?
+0
-0