diff --git a/c/Guia de ejercicios.docx b/c/Guia de ejercicios.docx new file mode 100644 index 0000000..350958f Binary files /dev/null and b/c/Guia de ejercicios.docx differ diff --git a/c/arena-lib/arena.c b/c/arena-lib/arena.c new file mode 100644 index 0000000..50442f2 --- /dev/null +++ b/c/arena-lib/arena.c @@ -0,0 +1,143 @@ +#include "arena.h" +#include + + +char* arena_strdup(Arena* ref_arena, const char* s){ + char* str = (char*) arena_alloc(ref_arena, strlen(s) + 1); + if(str == NULL){ + return NULL; + } + strcpy(str, s); + return str; +} + +void* arena_chunk_alloc(Arena* ref_arena, Chunk* chunk, size_t s){ + size_t aligned = (chunk->offset + (ARENA_MEMORY_ALIGN - 1)) & ~(ARENA_MEMORY_ALIGN -1); + if ((aligned + s <= chunk->size)){ + chunk->offset = aligned; + void* start = (void *)(chunk->buffer + chunk->offset); + chunk->offset = aligned + s; + return start; + } + return NULL; +} + +Chunk* arena_chunk_create(size_t s){ + printf("Creating a new chunk of %zu bytes\n", s); + Chunk* chunk1 = (Chunk*)malloc(sizeof(Chunk)); + + if(chunk1 == NULL){ + return NULL; + } + + chunk1->size = s; + chunk1->offset = 0; + chunk1->next = NULL; + + chunk1->buffer = (unsigned char *)malloc(s); + + if(chunk1->buffer == NULL){ + perror("Error creando chunk...\n"); + free(chunk1); + chunk1 = NULL; + return NULL; + } + + printf("Chunk creado correctamente\n"); + + return chunk1; + +} + +void arena_chunk_free(Chunk* chunk){ + printf("Liberando %zu bytes de memoria\n", chunk->size); + if(chunk->buffer != NULL){ + free(chunk->buffer); + chunk->buffer = NULL; + } + free(chunk); +} + +void* arena_alloc(Arena* ref_arena, size_t s){ + if(ref_arena == NULL){ + return NULL; + } + + if(ref_arena->current == NULL){ + return NULL; + } + + Chunk* current_chunk = ref_arena->current; + + void* ptr = arena_chunk_alloc(ref_arena, current_chunk, s); + + if(ptr == NULL){ + + size_t new_size = current_chunk->size * 2; + + if(new_size < s){ + new_size = s; + } + + Chunk *new_chunk = arena_chunk_create(new_size); + if(new_chunk == NULL){ + return NULL; + } + + current_chunk->next = new_chunk; + new_chunk->next = NULL; + ref_arena->current = new_chunk; + + return arena_alloc(ref_arena, s); + } + + return ptr; + + +} + +Arena arena_create(size_t s){ + Arena new_arena = { + .current = NULL, + .first = NULL + }; + + Chunk* chunk1 = arena_chunk_create(s); + + if(chunk1 == NULL){ + perror("Error creando arena\n"); + exit(1); + } + + new_arena.current = chunk1; + new_arena.first = chunk1; + + printf("Arena creada correctamente\n"); + + return new_arena; + +} + +void arena_free(Arena* ref_arena){ + Chunk* item = ref_arena->first; + while (item != NULL) { + Chunk *next = item->next; + arena_chunk_free(item); + item = next; + } + + ref_arena->first = NULL; + ref_arena->current = NULL; + + printf("Arena liberada\n"); +} + +void arena_print(Arena* ref_arena){ + printf("ARENA INFO\n"); + printf("==========\n"); + + printf("first: %p\n", ref_arena->first); + printf("next: %p\n", ref_arena->current); + + printf("==========\n"); +} diff --git a/c/arena-lib/arena.h b/c/arena-lib/arena.h new file mode 100644 index 0000000..7f28977 --- /dev/null +++ b/c/arena-lib/arena.h @@ -0,0 +1,29 @@ +#include +#include +#include +#include + +#define ARENA_MEMORY_ALIGN 8 + +typedef struct Chunk{ + size_t size; + size_t offset; + unsigned char *buffer; + struct Chunk *next; +}Chunk; + +typedef struct{ + Chunk *current; + Chunk *first; +}Arena; + +Arena arena_create(size_t); +void* arena_alloc(Arena*, size_t); +void arena_free(Arena*); +void arena_print(Arena*); + +Chunk* arena_chunk_create(size_t); +void arena_chunk_free(Chunk*); +void* arena_chunk_alloc(Arena*, Chunk*, size_t); + +char* arena_strdup(Arena*, const char*); diff --git a/c/arena/main.c b/c/arena/main.c new file mode 100644 index 0000000..b03fe0a --- /dev/null +++ b/c/arena/main.c @@ -0,0 +1,90 @@ +#include +#include +#include + +typedef struct{ + unsigned char *buffer; + size_t size; + size_t offset; +}Arena; + +Arena arena_create(size_t); +void* arena_alloc(Arena *, size_t); +void arena_destroy(Arena *); + +int main(void){ + Arena arena = arena_create(13); + int *ptrInt1 = (int*)arena_alloc(&arena, sizeof(int)); + int *ptrInt2 = (int*)arena_alloc(&arena, sizeof(int)); + float *ptrFloat1 = (float*)arena_alloc(&arena, sizeof(float)); + char *ptrChar1 = (char*)arena_alloc(&arena, sizeof(char)); + + int need = sizeof(int)*2 + sizeof(float) + sizeof(char); + + printf("sizeof int: %d\n", (int)sizeof(int)); + printf("sizeof float: %d\n", (int)sizeof(float)); + printf("sizeof char: %d\n", (int)sizeof(char)); + + printf("Necesitamos: %d\n", need); + + if(ptrInt1 != NULL){ + *ptrInt1 = 18; + printf("Primer entero: %d\n", *ptrInt1); + } + if(ptrInt2 != NULL){ + *ptrInt2 = 27; + printf("Segundo entero: %d\n", *ptrInt2); + } + if(ptrFloat1 != NULL){ + *ptrFloat1 = 3.1415f; + printf("Primer flotante: %f\n", *ptrFloat1); + } + if(ptrChar1 != NULL){ + *ptrChar1 = 'L'; + printf("Primer char: %c\n", *ptrChar1); + } + + arena_destroy(&arena); + + return 0; +} + +Arena arena_create( size_t bytes){ + Arena new_arena = { + .buffer = NULL, + .size = bytes, + .offset = 0 + }; + + new_arena.buffer = (unsigned char *)malloc(bytes); + + if(new_arena.buffer == NULL){ + perror("Error asignando memoria"); + exit(1); + } + + return new_arena; + +} +void* arena_alloc(Arena *ref_arena, size_t bytes){ + + if(ref_arena->buffer == NULL){ + return NULL; + } + + if(ref_arena->offset + bytes > ref_arena->size){ + perror("Memoria llena\n"); + return NULL; + } + void* ptr_ref = ref_arena->buffer + ref_arena->offset; + ref_arena->offset += bytes; + return ptr_ref; +} + +void arena_destroy(Arena *ref_arena){ + if(ref_arena->buffer != NULL){ + free(ref_arena->buffer); + ref_arena->buffer = NULL; + } +} + diff --git a/c/arena/programa b/c/arena/programa new file mode 100755 index 0000000..080b0a1 Binary files /dev/null and b/c/arena/programa differ diff --git a/c/arena2/main.c b/c/arena2/main.c new file mode 100644 index 0000000..bf3e925 --- /dev/null +++ b/c/arena2/main.c @@ -0,0 +1,82 @@ +#include +#include +#include +#include + +#define FPS 10 + +typedef struct{ + unsigned char *buffer; + size_t size; + size_t offset; +}Arena; + +Arena arena_create(size_t); +void* arena_alloc(Arena *, size_t); +void arena_reset(Arena *); +void arena_destroy(Arena *); + +int main(void){ + srand(time(NULL)); + Arena arena = arena_create(100); + + for(int i=0; i < FPS; i++){ + + int* ptrLeft = arena_alloc(&arena, sizeof(int)); + + if(ptrLeft != NULL){ + *ptrLeft = rand()%FPS; + printf("El datos del frame es: %d\n", *ptrLeft); + } + + arena_reset(&arena); + } + + arena_destroy(&arena); + + return 0; +} + +Arena arena_create( size_t bytes){ + Arena new_arena = { + .buffer = NULL, + .size = bytes, + .offset = 0 + }; + + new_arena.buffer = (unsigned char *)malloc(bytes); + + if(new_arena.buffer == NULL){ + perror("Error asignando memoria"); + exit(1); + } + + return new_arena; + +} +void* arena_alloc(Arena *ref_arena, size_t bytes){ + + if(ref_arena->buffer == NULL){ + return NULL; + } + + if(ref_arena->offset + bytes > ref_arena->size){ + perror("Memoria llena\n"); + return NULL; + } + void* ptr_ref = ref_arena->buffer + ref_arena->offset; + ref_arena->offset += bytes; + return ptr_ref; +} + +void arena_reset(Arena *ref_arena){ + ref_arena->offset = 0; +} + +void arena_destroy(Arena *ref_arena){ + if(ref_arena->buffer != NULL){ + free(ref_arena->buffer); + ref_arena->buffer = NULL; + } +} + diff --git a/c/arena2/programa b/c/arena2/programa new file mode 100755 index 0000000..0d74a54 Binary files /dev/null and b/c/arena2/programa differ diff --git a/c/arena3/main.c b/c/arena3/main.c new file mode 100644 index 0000000..31a34b7 --- /dev/null +++ b/c/arena3/main.c @@ -0,0 +1,106 @@ +#include +#include +#include +#include + +#define FPS 10 + +#define ARENA_ALIGN 8 + +#define ALLOC_TYPE(REF, TYPE) (TYPE*)arena_alloc(&REF, sizeof(TYPE)) + +typedef struct{ + unsigned char *buffer; + size_t size; + size_t offset; +}Arena; + +Arena arena_create(size_t); +void* arena_alloc(Arena *, size_t); +void arena_reset(Arena *); +void arena_destroy(Arena *); +bool arena_is_aligned(size_t); + +int main(void){ + Arena arena = arena_create(32); + + int *test = ALLOC_TYPE(arena, int); + + *test = 5; + + arena_alloc(&arena, 3); + + arena_alloc(&arena, 1); + arena_alloc(&arena, 5); + arena_alloc(&arena, 9); + arena_alloc(&arena, 8); + arena_alloc(&arena, 1); + + arena_destroy(&arena); + + return 0; +} + +bool arena_is_aligned(size_t pos){ + size_t mask = 7; + return (pos & mask) == 0; +} + +Arena arena_create( size_t bytes){ + Arena new_arena = { + .buffer = NULL, + .size = bytes, + .offset = 0 + }; + + new_arena.buffer = (unsigned char *)malloc(bytes); + + if(new_arena.buffer == NULL){ + perror("Error asignando memoria"); + exit(1); + } + + return new_arena; + +} +void* arena_alloc(Arena *ref_arena, size_t bytes){ + + if(ref_arena->buffer == NULL){ + return NULL; + } + + size_t aligned = ((ref_arena->offset + (size_t)((ARENA_ALIGN - 1))) & ~(ARENA_ALIGN - 1)); + + if(aligned + bytes > ref_arena->size){ + printf("arena_alloc(%d): NULL \n", (int) bytes); + return NULL; + } + void* ptr_ref = ref_arena->buffer + aligned; + + printf("arena_alloc(%d) ", (int) bytes); + + if(arena_is_aligned((size_t)ptr_ref)){ + printf("aligned: true "); + }else{ + printf("aligned: false "); + } + + printf(" base + %d", (int)aligned); + printf(" offset: %d -> %d \n", (int)ref_arena->offset, (int)aligned); + + ref_arena->offset = aligned + bytes; + + return ptr_ref; +} + +void arena_reset(Arena *ref_arena){ + ref_arena->offset = 0; +} + +void arena_destroy(Arena *ref_arena){ + if(ref_arena->buffer != NULL){ + free(ref_arena->buffer); + ref_arena->buffer = NULL; + } +} + diff --git a/c/arena3/programa b/c/arena3/programa new file mode 100755 index 0000000..e104368 Binary files /dev/null and b/c/arena3/programa differ diff --git a/c/arena4/main.c b/c/arena4/main.c new file mode 100644 index 0000000..084ffbd --- /dev/null +++ b/c/arena4/main.c @@ -0,0 +1,107 @@ +#include +#include +#include +#include +#include + +#define ARENA_ALIGN 8 + +typedef struct{ + unsigned char *buffer; + size_t size; + size_t offset; +}Arena; + +Arena arena_create(size_t); +void* arena_alloc(Arena *, size_t); +void arena_reset(Arena *); +void arena_destroy(Arena *); +bool arena_is_aligned(size_t); +char* arena_strdup(Arena*, const char *); + +int main(void){ + Arena arena = arena_create(16); + + char* s1 = arena_strdup(&arena, "arena"); + char* s2 = arena_strdup(&arena, "hola"); + char* s3 = arena_strdup(&arena, "x"); + + arena_destroy(&arena); + + return 0; +} + + +char* arena_strdup(Arena* ref_arena, const char *src){ + char* ref_str = (char*) arena_alloc(ref_arena, strlen(src) + 1); + if(ref_str == NULL){ + perror("No se ha podido reservar memoria para la cadena."); + return NULL; + } + strcpy(ref_str, src); + return ref_str; +} + +bool arena_is_aligned(size_t pos){ + size_t mask = 7; + return (pos & mask) == 0; +} + +Arena arena_create( size_t bytes){ + Arena new_arena = { + .buffer = NULL, + .size = bytes, + .offset = 0 + }; + + new_arena.buffer = (unsigned char *)malloc(bytes); + + if(new_arena.buffer == NULL){ + perror("Error asignando memoria"); + exit(1); + } + + return new_arena; + +} +void* arena_alloc(Arena *ref_arena, size_t bytes){ + + if(ref_arena->buffer == NULL){ + return NULL; + } + + size_t aligned = ((ref_arena->offset + (size_t)((ARENA_ALIGN - 1))) & ~(ARENA_ALIGN - 1)); + + if(aligned + bytes > ref_arena->size){ + printf("arena_alloc(%d): NULL \n", (int) bytes); + return NULL; + } + void* ptr_ref = ref_arena->buffer + aligned; + + printf("arena_alloc(%d) ", (int) bytes); + + if(arena_is_aligned((size_t)ptr_ref)){ + printf("aligned: true "); + }else{ + printf("aligned: false "); + } + + printf(" base + %d", (int)aligned); + printf(" offset: %d -> %d \n", (int)ref_arena->offset, (int)aligned); + + ref_arena->offset = aligned + bytes; + + return ptr_ref; +} + +void arena_reset(Arena *ref_arena){ + ref_arena->offset = 0; +} + +void arena_destroy(Arena *ref_arena){ + if(ref_arena->buffer != NULL){ + free(ref_arena->buffer); + ref_arena->buffer = NULL; + } +} + diff --git a/c/arena4/programa b/c/arena4/programa new file mode 100755 index 0000000..f858181 Binary files /dev/null and b/c/arena4/programa differ diff --git a/c/arena5/main.c b/c/arena5/main.c new file mode 100644 index 0000000..f5a84ba --- /dev/null +++ b/c/arena5/main.c @@ -0,0 +1,120 @@ +#include +#include +#include +#include +#include + +#define ARENA_ALIGN 8 + +typedef struct{ + unsigned char *buffer; + size_t size; + size_t offset; +}Arena; + +Arena arena_create(size_t); +void* arena_alloc(Arena *, size_t); +void arena_reset(Arena *); +void arena_destroy(Arena *); +bool arena_is_aligned(size_t); +size_t arena_checkpoint(Arena*); +void arena_restore(Arena*, size_t); + +int main(void){ + Arena arena = arena_create(32); + + size_t cp0 = arena_checkpoint(&arena); + int* x = (int*)arena_alloc(&arena, 8); + +*x = 21; + + arena_alloc(&arena, 8); + size_t cp1 = arena_checkpoint(&arena); + int* tmp = (int*)arena_alloc(&arena, 8); + + arena_restore(&arena, cp1); + + printf("x:%d\n", *x); + + arena_alloc(&arena, 16); + + arena_restore(&arena, cp0); + + arena_alloc(&arena, 32); + + arena_destroy(&arena); + + return 0; +} + +void arena_restore(Arena* ref_arena, size_t chk){ + ref_arena->offset = chk; +} + +size_t arena_checkpoint(Arena* ref_arena){ + return ref_arena->offset; +} + +bool arena_is_aligned(size_t pos){ + size_t mask = 7; + return (pos & mask) == 0; +} + +Arena arena_create( size_t bytes){ + Arena new_arena = { + .buffer = NULL, + .size = bytes, + .offset = 0 + }; + + new_arena.buffer = (unsigned char *)malloc(bytes); + + if(new_arena.buffer == NULL){ + perror("Error asignando memoria"); + exit(1); + } + + return new_arena; + +} +void* arena_alloc(Arena *ref_arena, size_t bytes){ + + if(ref_arena->buffer == NULL){ + return NULL; + } + + size_t aligned = ((ref_arena->offset + (size_t)((ARENA_ALIGN - 1))) & ~(ARENA_ALIGN - 1)); + + if(aligned + bytes > ref_arena->size){ + printf("arena_alloc(%d): NULL \n", (int) bytes); + return NULL; + } + void* ptr_ref = ref_arena->buffer + aligned; + + printf("arena_alloc(%d) ", (int) bytes); + + if(arena_is_aligned((size_t)ptr_ref)){ + printf("aligned: true "); + }else{ + printf("aligned: false "); + } + + printf(" base + %d", (int)aligned); + printf(" offset: %d -> %d \n", (int)ref_arena->offset, (int)aligned); + + ref_arena->offset = aligned + bytes; + + return ptr_ref; +} + +void arena_reset(Arena *ref_arena){ + ref_arena->offset = 0; +} + +void arena_destroy(Arena *ref_arena){ + if(ref_arena->buffer != NULL){ + free(ref_arena->buffer); + ref_arena->buffer = NULL; + } +} + diff --git a/c/arena5/programa b/c/arena5/programa new file mode 100755 index 0000000..88b4f11 Binary files /dev/null and b/c/arena5/programa differ diff --git a/c/arena6/main.c b/c/arena6/main.c new file mode 100644 index 0000000..b998d84 --- /dev/null +++ b/c/arena6/main.c @@ -0,0 +1,178 @@ +#include +#include +#include +#include + +#define ARENA_MEMORY_ALIGN 8 + +typedef struct Chunk{ + size_t size; + size_t offset; + unsigned char *buffer; + struct Chunk *next; +}Chunk; + +typedef struct{ + Chunk *current; + Chunk *first; +}Arena; + +Arena arena_create(size_t); +void* arena_alloc(Arena*, size_t); +void arena_free(Arena*); +void arena_print(Arena*); + +Chunk* arena_chunk_create(size_t); +void arena_chunk_free(Chunk*); +void* arena_chunk_alloc(Arena*, Chunk*, size_t); + +int main(void){ + + Arena arena = arena_create(32); + + arena_print(&arena); + + arena_alloc(&arena, 100); + + arena_print(&arena); + + arena_alloc(&arena, 40); + + arena_print(&arena); + + arena_free(&arena); + + arena_print(&arena); + return 0; +} + +void* arena_chunk_alloc(Arena* ref_arena, Chunk* chunk, size_t s){ + size_t aligned = (chunk->offset + (ARENA_MEMORY_ALIGN - 1)) & ~(ARENA_MEMORY_ALIGN -1); + if ((aligned + s <= chunk->size)){ + chunk->offset = aligned; + void* start = (void *)(chunk->buffer + chunk->offset); + chunk->offset = aligned + s; + return start; + } + return NULL; +} + +Chunk* arena_chunk_create(size_t s){ + printf("Creating a new chunk of %zu bytes\n", s); + Chunk* chunk1 = (Chunk*)malloc(sizeof(Chunk)); + + if(chunk1 == NULL){ + return NULL; + } + + chunk1->size = s; + chunk1->offset = 0; + chunk1->next = NULL; + + chunk1->buffer = (unsigned char *)malloc(s); + + if(chunk1->buffer == NULL){ + perror("Error creando chunk...\n"); + free(chunk1); + chunk1 = NULL; + return NULL; + } + + printf("Chunk creado correctamente\n"); + + return chunk1; + +} + +void arena_chunk_free(Chunk* chunk){ + printf("Liberando %zu bytes de memoria\n", chunk->size); + if(chunk->buffer != NULL){ + free(chunk->buffer); + chunk->buffer = NULL; + } + free(chunk); +} + +void* arena_alloc(Arena* ref_arena, size_t s){ + if(ref_arena == NULL){ + return NULL; + } + + if(ref_arena->current == NULL){ + return NULL; + } + + Chunk* current_chunk = ref_arena->current; + + void* ptr = arena_chunk_alloc(ref_arena, current_chunk, s); + + if(ptr == NULL){ + + size_t new_size = current_chunk->size * 2; + + if(new_size < s){ + new_size = s; + } + + Chunk *new_chunk = arena_chunk_create(new_size); + if(new_chunk == NULL){ + return NULL; + } + + current_chunk->next = new_chunk; + new_chunk->next = NULL; + ref_arena->current = new_chunk; + + return arena_alloc(ref_arena, s); + } + + return ptr; + + +} + +Arena arena_create(size_t s){ + Arena new_arena = { + .current = NULL, + .first = NULL + }; + + Chunk* chunk1 = arena_chunk_create(s); + + if(chunk1 == NULL){ + perror("Error creando arena\n"); + exit(1); + } + + new_arena.current = chunk1; + new_arena.first = chunk1; + + printf("Arena creada correctamente\n"); + + return new_arena; + +} + +void arena_free(Arena* ref_arena){ + Chunk* item = ref_arena->first; + while (item != NULL) { + Chunk *next = item->next; + arena_chunk_free(item); + item = next; + } + + ref_arena->first = NULL; + ref_arena->current = NULL; + + printf("Arena liberada\n"); +} + +void arena_print(Arena* ref_arena){ + printf("ARENA INFO\n"); + printf("==========\n"); + + printf("first: %p\n", ref_arena->first); + printf("next: %p\n", ref_arena->current); + + printf("==========\n"); +} diff --git a/c/arena6/programa b/c/arena6/programa new file mode 100755 index 0000000..774be34 Binary files /dev/null and b/c/arena6/programa differ diff --git a/c/arena7/main.c b/c/arena7/main.c new file mode 100644 index 0000000..36382da --- /dev/null +++ b/c/arena7/main.c @@ -0,0 +1,86 @@ +#include +#include "../arena-lib/arena.h" +#include + +typedef struct Persona{ + char* nombre; + int edad; + struct Persona* next; +}Persona; + +void print_persona(Persona*); + + +int main(void){ + + printf("Alinacion struct Persona: %d\n", (int)_Alignof(Persona)); + printf("sizeof struct Persona: %d\n", (int)sizeof(Persona)); + + Arena arena = arena_create(32); + + char continuar = 'S'; + + Persona* first = NULL; + Persona* last = NULL; + + do{ + char input_name[50]; + printf("Nombre:"); + if (fgets(input_name, sizeof(input_name), stdin) != NULL) { + input_name[strcspn(input_name, "\n")] = '\0'; + } + + int input_edad = 0; + + printf("Edad:"); + scanf("%d", &input_edad); + printf("\n"); + + int c; + while ((c = getchar()) != '\n' && c != EOF); + + Persona* p = (Persona*)arena_alloc(&arena, sizeof(Persona)); + + if(p == NULL){ + perror("Ha ocurrido un error\n"); + exit(1); + } + + p->nombre = arena_strdup(&arena, input_name); + p->edad = input_edad; + p->next = NULL; + + if(first == NULL){ + first = p; + } + + if(last != NULL){ + last->next = p; + } + + last = p; + + printf("Cargar mas personas? (S) Continuar, (N): Terminar :"); + scanf(" %c", &continuar); + + while ((c = getchar()) != '\n' && c != EOF); + + }while((continuar == 'S') || (continuar == 's')); + + printf("Listado de personas cargadas:\n"); + printf("=============================\n"); + + Persona* current = first; + while(current != NULL){ + print_persona(current); + current = current->next; + } + + arena_free(&arena); + + return 0; +} + +void print_persona(Persona* ref_persona) { + printf("%s: tiene %d years\n", ref_persona->nombre, ref_persona->edad); +} diff --git a/c/arena7/programa b/c/arena7/programa new file mode 100755 index 0000000..beace48 Binary files /dev/null and b/c/arena7/programa differ diff --git a/c/arena8/main.c b/c/arena8/main.c new file mode 100644 index 0000000..e557f1d --- /dev/null +++ b/c/arena8/main.c @@ -0,0 +1,102 @@ +#include "../arena-lib/arena.h" +#include + +typedef enum { + BIN_OP_SUMA, + BIN_OP_RESTA, + BIN_OP_MULTIPLY, + BIN_OP_DIVISION +} BinaryOps; + +typedef enum { + NODE_NUMBER, + NODE_OPERATION +} NodeKind; + +typedef struct Node{ + union { + BinaryOps operation; + int number; + }value; + NodeKind type; + struct Node* left; + struct Node* right; +} Node; + +Node* create_number(Arena* arena_ref, int n){ + Node* node = (Node*)arena_alloc(arena_ref, sizeof(Node)); + if(node == NULL){ + return NULL; + } + node->type = NODE_NUMBER; + node->value.number = n; + node->left = NULL; + node->right = NULL; + return node; +} + +Node* create_operation(Arena* ref_arena, BinaryOps op, Node* l, Node* r){ + Node* node = (Node*)arena_alloc(ref_arena, sizeof(Node)); + if(node == NULL){ + return NULL; + } + node->type = NODE_OPERATION; + node->value.operation = op; + node->left = l; + node->right = r; + return node; +} + +int node_compute(Node* node){ + if(node->type == NODE_OPERATION){ + int r1 = node_compute(node->left); + int r2 = node_compute(node->right); + int result = 0; + switch (node->value.operation) { + case BIN_OP_SUMA: + result = r1 + r2; + break; + case BIN_OP_RESTA: + result = r1 - r2; + break; + case BIN_OP_MULTIPLY: + result = r1 * r2; + break; + case BIN_OP_DIVISION: + result = (r2 != 0) ? r1 / r2 : 0; + break; + default: + result = 0; + break; + } + return result; + } + + return node->value.number; +} + +int main(void){ + + Arena arena = arena_create(32); + + printf("Memory struct information\n"); + printf("=========================\n"); + printf("sizeof(Node):%zu\n", sizeof(Node)); + printf("align(Node): %zu\n", _Alignof(Node)); + + //Creamos el arbol para 3 + (4 - 1) + Node* t1 = create_number(&arena, 3); + Node* t21 = create_number(&arena, 4); + Node* t22 = create_number(&arena, 1); + Node* t2 = create_operation(&arena, BIN_OP_RESTA, t21, t22); + Node* root = create_operation(&arena, BIN_OP_SUMA, t1, t2); + + printf("Node compute\n"); + printf("============\n"); + + printf("result: %d\n", node_compute(root)); + + arena_free(&arena); + + return 0; +} diff --git a/c/arena8/programa b/c/arena8/programa new file mode 100755 index 0000000..10b91c4 Binary files /dev/null and b/c/arena8/programa differ diff --git a/c/args/main.c b/c/args/main.c new file mode 100644 index 0000000..c9b3ead --- /dev/null +++ b/c/args/main.c @@ -0,0 +1,73 @@ +#include +#include +#include +#include +#include +#include + + +static struct option option_args[] = { + {"help", no_argument, 0, 'h' }, + {"verbose", no_argument, 0, 'v' }, + {"output", required_argument, 0, 'o' }, + {"max", required_argument, 0, 'm' }, + {0,0,0,0} +}; + +void print_usage(char* arg){ + fprintf(stdout, "Uso: %s\n", arg); + fprintf(stdout, "[--help]\n"); + fprintf(stdout, "[--verbose]\n"); + fprintf(stdout, "[--output ]\n"); + fprintf(stdout, "[--max ]\n"); + fprintf(stdout, "[posicionales...]\n"); +} + +int main(int argc, char* argv[]){ + + printf("argv[0]: %s\n", argv[0]); + + int opt; + int opt_index = 0; + + while((opt = getopt_long(argc, argv, "hvo:m:", option_args, &opt_index)) != -1){ + switch (opt){ + case 'h': + print_usage(argv[0]); + exit(0); + break; + case 'v': + fprintf(stdout, "Modo verbose: ON\n"); + break; + case 'o': + fprintf(stdout, "Output: %s\n", optarg); + break; + case 'm': + errno = 0; + char* errorptr = NULL; + long maximo = strtol(optarg, &errorptr, 10); + if( (errno == EINVAL) + || (errno == ERANGE) + || (*errorptr != 0) + || (maximo < INT_MIN) + || (maximo > INT_MAX) + ){ + fprintf(stderr, "--max debe ser un numero entero valido.\n"); + exit(1); + } + printf("Maximo:%ld\n", maximo); + break; + case '?': + print_usage(argv[0]); + exit(1); + break; + } + } + + fprintf(stdout, "Posicionales:\n"); + for(int i = optind; i < argc; i++){ + fprintf(stdout, "%s\n", argv[i]); + } + + return 0; +} diff --git a/c/args/programa b/c/args/programa new file mode 100755 index 0000000..fe3fcb6 Binary files /dev/null and b/c/args/programa differ diff --git a/c/args/util b/c/args/util new file mode 100755 index 0000000..d182f40 Binary files /dev/null and b/c/args/util differ diff --git a/c/aritmeticaptr/main.c b/c/aritmeticaptr/main.c new file mode 100644 index 0000000..47ee18c --- /dev/null +++ b/c/aritmeticaptr/main.c @@ -0,0 +1,60 @@ +/* +* Enunciado del Ejercicio: Modificación de Arreglos mediante Aritmética de Punteros +* +* Objetivo: +* Practicar el manejo de punteros y su relación con los arreglos estáticos en el lenguaje C, +* aplicando aritmética de punteros para recorrer y modificar los elementos almacenados en memoria. +* +* Descripción: +* +* Escribe un programa completo en C que realice las siguientes tareas: +* +* Declaración e Inicialización: +* +* Declara un arreglo estático de 5 enteros (int) e inicialízalo +* con valores arbitrarios de tu elección (por ejemplo: 5, 10, 15, 20, 25). +* +* Declara un puntero a entero (int *ptr) que apunte al inicio del arreglo. +* +* Procesamiento con Aritmética de Punteros: +* +* Utiliza un bucle (for o el de tu preferencia) para recorrer el arreglo únicamente mediante +* aritmética de punteros y el operador de indirección en la forma *(ptr + i) (o incrementando el puntero directamente). +* +* Dentro del bucle, suma 10 al valor actual almacenado en cada posición del arreglo. +* +* Salida por Consola: +* +* Muestra en pantalla los valores del arreglo antes y después de aplicar la modificación +* para verificar que el cambio se realizó correctamente en la memoria del arreglo original. +* +* Restricciones: +* +* Está prohibido utilizar la notación de corchetes (arreglo[i]) para acceder o modificar +* los elementos del arreglo dentro del bucle. Debes usar estrictamente la sintaxis de punteros (*(ptr + i)). +*/ + +#include + +#define V_LENGTH 5 + +void print_arr(int *); + +int main(void){ + int v1[V_LENGTH] = {5, 10, 15, 20, 25}; + int* ptr_v1 = v1; + print_arr(ptr_v1); + for(int i=0; i +int main(void){ + fprintf(stdout, "Iniciando reporte.\n"); + fprintf(stdout, "Procesando 128 registros.\n"); + fprintf(stdout, "Reporte generado correctamente.\n"); + + fprintf(stderr, "Se encontraron 3 registros invalidos.\n"); + return 1; +} diff --git a/c/pipes1/programa b/c/pipes1/programa new file mode 100755 index 0000000..a02e209 Binary files /dev/null and b/c/pipes1/programa differ diff --git a/c/pipes1/salida.txt b/c/pipes1/salida.txt new file mode 100644 index 0000000..7681363 --- /dev/null +++ b/c/pipes1/salida.txt @@ -0,0 +1,3 @@ +Iniciando reporte. +Procesando 128 registros. +Reporte generado correctamente. diff --git a/c/pipes1/test.txt b/c/pipes1/test.txt new file mode 100644 index 0000000..27b1238 --- /dev/null +++ b/c/pipes1/test.txt @@ -0,0 +1,2 @@ +test +segunda linea diff --git a/c/pipes2/main.c b/c/pipes2/main.c new file mode 100644 index 0000000..d32e0a1 --- /dev/null +++ b/c/pipes2/main.c @@ -0,0 +1,16 @@ +#include +int main(void){ + int c, count = 0, countbr = 0; + + while((c = getchar()) != EOF){ + if(c == '\n'){ + countbr++; + } + count++; + } + + fprintf(stdout, "Se leyeron %d bytes\n", count); + fprintf(stdout, "Se leyeron %d
\n", countbr); + + return 0; +} diff --git a/c/pipes2/programa b/c/pipes2/programa new file mode 100755 index 0000000..13ca060 Binary files /dev/null and b/c/pipes2/programa differ diff --git a/c/pipes3/.vscode/tasks.json b/c/pipes3/.vscode/tasks.json new file mode 100644 index 0000000..08d9005 --- /dev/null +++ b/c/pipes3/.vscode/tasks.json @@ -0,0 +1,28 @@ +{ + "tasks": [ + { + "type": "cppbuild", + "label": "C/C++: gcc build active file", + "command": "/usr/bin/gcc", + "args": [ + "-fdiagnostics-color=always", + "-g", + "${file}", + "-o", + "${fileDirname}/${fileBasenameNoExtension}" + ], + "options": { + "cwd": "${fileDirname}" + }, + "problemMatcher": [ + "$gcc" + ], + "group": { + "kind": "build", + "isDefault": true + }, + "detail": "Task generated by Debugger." + } + ], + "version": "2.0.0" +} \ No newline at end of file diff --git a/c/pipes3/a.out b/c/pipes3/a.out new file mode 100755 index 0000000..3d1eda8 Binary files /dev/null and b/c/pipes3/a.out differ diff --git a/c/pipes3/entrada.txt b/c/pipes3/entrada.txt new file mode 100644 index 0000000..85857a8 --- /dev/null +++ b/c/pipes3/entrada.txt @@ -0,0 +1,2 @@ +este es un archivo +de texto diff --git a/c/pipes3/main b/c/pipes3/main new file mode 100755 index 0000000..93307eb Binary files /dev/null and b/c/pipes3/main differ diff --git a/c/pipes3/main.c b/c/pipes3/main.c new file mode 100644 index 0000000..ae1529b --- /dev/null +++ b/c/pipes3/main.c @@ -0,0 +1,42 @@ +#include +#include +#include + +int count_words(char*); + +int main(void){ + + char buffer[50]; + int total_words = 0; + + while((fgets(buffer, sizeof(buffer), stdin)) != NULL){ + total_words += count_words(buffer); + } + + printf("El total de palabras es: %d\n", total_words); + + return 0; +} + +int count_words(char* line){ + int palabras = 0; + bool hay_espacio = false; + + printf("line: %s", line); + + if((line[0] != ' ') && strlen(line) > 0){ + palabras++; + } + + for(int i = 0; i < strlen(line); i++){ + if(line[i] == ' '){ + hay_espacio = true; + } + + if((line[i] != ' ') && (line[i] != '\n') && (hay_espacio)){ + palabras++; + hay_espacio = false; + } + } + return palabras; +} diff --git a/c/pipes3/programa b/c/pipes3/programa new file mode 100755 index 0000000..3d1eda8 Binary files /dev/null and b/c/pipes3/programa differ diff --git a/c/struct1/main.c b/c/struct1/main.c new file mode 100644 index 0000000..fdf4e39 --- /dev/null +++ b/c/struct1/main.c @@ -0,0 +1,69 @@ +/* + * EJERCICIO DE LENGUAJE C: STRUCTS Y PUNTEROS + * + * 1. Define una struct llamada Coordenada que contenga dos campos enteros: x e y. + * 2. Implementa una función constructora llamada Coordenada* crear_coordenada(int x, int y) que: + * - Reserve memoria dinámicamente utilizando malloc para una nueva estructura Coordenada. + * - Verifique si la reserva de memoria fue exitosa. + * - Inicialice sus campos x e y con los valores pasados como parámetros. + * - Devuelva el puntero a la estructura creada. + * 3. En la función main: + * - Utiliza la función constructora para crear una coordenada. + * - Muestra por pantalla los valores iniciales utilizando el operador flecha (->). + * - Modifica los valores de los campos de la estructura utilizando también el operador flecha (->). + * - Muestra los nuevos valores por pantalla. + * - Libera la memoria reservada dinámicamente utilizando free para evitar pérdidas de memoria. + */ + +#include +#include + + +typedef struct{ + int x; + int y; +}Coordenada; + +Coordenada* crear_coordenada(int x, int y); +void modificar_coordenada(Coordenada**, int x, int y); +void imprimir_coordenada(Coordenada**); + +int main(void){ + + Coordenada* cord = crear_coordenada(10, 20); + + imprimir_coordenada(&cord); + modificar_coordenada(&cord, 30, 40); + imprimir_coordenada(&cord); + + free(cord); + + return 0; +} + +Coordenada* crear_coordenada(int x, int y){ + Coordenada* new_cord = malloc(sizeof(Coordenada)); + if(new_cord == NULL){ + perror("No se pudo crear la coordenada\n"); + exit(1); + } + + new_cord->x = x; + new_cord->y = y; + + return new_cord; +} + +void modificar_coordenada(Coordenada** cord_address, int x, int y){ + if((*cord_address) == NULL){ + perror("No se ha proporcionado una coordenada para modificar\n"); + exit(1); + } + (*cord_address)->x = x; + (*cord_address)->y = y; +} + +void imprimir_coordenada(Coordenada** a){ + printf("Coordenada(%d, %d);\n", (*a)->x, (*a)->y); +} + diff --git a/c/struct1/programa b/c/struct1/programa new file mode 100755 index 0000000..7ac7461 Binary files /dev/null and b/c/struct1/programa differ diff --git a/c/struct2/main.c b/c/struct2/main.c new file mode 100644 index 0000000..9e5b42d --- /dev/null +++ b/c/struct2/main.c @@ -0,0 +1,92 @@ +/******************************************************************************* + * TRABAJO PRÁCTICO / EJERCICIO INTEGRADOR: GESTIÓN DE PUNTEROS Y ESTRUCTURAS + * + * OBJETIVO: + * El propósito de este ejercicio es consolidar el manejo de estructuras, + * aritmética de punteros, indirección y diseño de funciones conpaso por referencia + * en el lenguaje C, evitando el uso de código resuelto y enfocándose en la + * especificación formal del problema. + * + * CONSIGNA: + * Desarrolle un programa en Lenguaje C que cumpla rigurosamente con los + * siguientes requerimientos técnicos y estructurales: + * + * 1. Definición del Tipo de Dato (Struct con Punteros Internos): + * - Defina una estructura denominada `Persona` que contenga dos campos: + * * Un puntero a caracteres (`char *nombre`) destinado a almacenar + * dinámicamente o mediante literales la identificación de la persona. + * * Un número entero (`int edad`) que represente los años de la persona. + * + * 2. Estructura de Almacenamiento (Arreglo de Estructuras): + * - En la función principal (`main`), declare un arreglo estático con + * capacidad exactamente para 3 elementos de tipo `Persona`. + * - Inicialice cada uno de los elementos del arreglo asignando valores + * válidos tanto para el puntero `nombre` como para la `edad`. + * - Implemente una función específica (cuya firma y diseño quedan a su cargo) + * que reciba como parámetro el puntero al inicio del arreglo de estructuras + * y su tamaño, y se encargue de recorrerlo sistemáticamente para + * imprimir en la consola los datos de todos sus elementos. + * + * 3. Encapsulamiento y Modificación (Funciones Modificadoras / Setters): + * - Escriba una función modular de tipo `void` llamada `cambiar_edad` + * cuya firma obligatoria sea: + * `void cambiar_edad(Persona *p, int nueva_edad)` + * - Dicha función debe recibir un puntero a una estructura `Persona` + * para actualizar el campo correspondiente de forma segura mediante + * el operador de indirección adecuado, reflejando el cambio en el ámbito + * del programa principal. + * + * 4. Pautas de Entrega y Validación: + * - El programa debe compilar sin errores ni advertencias bajo un estándar + * moderno de C (por ejemplo, -std=c11 o superior). + * - No se deben utilizar variables globales; toda la comunicación entre + * funciones debe realizarse mediante parámetros y punteros. + *******************************************************************************/ + +#include + +#define P_LENGTH 3 + +typedef struct{ + char* nombre; + int edad; +}Persona; + +void listar_personas(Persona*, int length); +void cambiar_edad(Persona *p, int nueva_edad); + +int main(void){ + + Persona personas[P_LENGTH] = { + { + .nombre = "Horacio", + .edad = 43 + }, + { + .nombre = "Raquel", + .edad = 44 + }, { + .nombre = "Luna", + .edad = 15 + } + }; + + listar_personas(personas, P_LENGTH); + cambiar_edad(personas, 21); + cambiar_edad(personas+1, 22); + cambiar_edad(personas+2, -5); + listar_personas(personas, P_LENGTH); + + return 0; +} + +void listar_personas(Persona* p, int length){ + for(int i=0; i < length; i++){ + printf("%s \t %d \n", (p+i)->nombre, (p+i)->edad); + } +} + +void cambiar_edad(Persona *p, int nueva_edad){ + p->edad = nueva_edad; +} + diff --git a/c/struct2/programa b/c/struct2/programa new file mode 100755 index 0000000..f428a07 Binary files /dev/null and b/c/struct2/programa differ diff --git a/c/struct3/main.c b/c/struct3/main.c new file mode 100644 index 0000000..450fa79 --- /dev/null +++ b/c/struct3/main.c @@ -0,0 +1,347 @@ +/* ========================================================================= + * PROYECTO: Sistema de Registro y Telemetría para el Nanosatélite "Andrómeda-1" + * ------------------------------------------------------------------------- + * CONTEXTO: + * La Agencia Espacial Experimental está desarrollando el software de a bordo + * para su próximo nanosatélite. El sistema necesita gestionar memoria de + * forma dinámica y eficiente debido a los recursos limitados del microcontrolador + * y a la naturaleza impredecible de las ráfagas de datos en órbita. + * + * OBJETIVO: + * Diseñar e implementar un programa en lenguaje C que resuelva los siguientes + * módulos de gestión de memoria dinámica requeridos por la estación de tierra: + * + * 1. Vector Dinámico Básico (Canales de Sensores): + * Pide al operador un número N de canales activos, utiliza malloc para + * reservar un arreglo de enteros con las lecturas iniciales, muéstralo en + * consola y libera correctamente la memoria con free al terminar. + * + * 2. Cadenas Dinámicas (Identificadores de Misión): + * Escribe una función que reciba una cadena estática (char *) con el nombre + * de código del satélite, calcule su longitud exacta, reserve espacio + * dinámicamente con malloc, copie la cadena y devuelva el nuevo puntero + * dinámico para ser registrado en los logs del sistema. + * + * 3. Estructura Dinámica (Buffer de Archivos de Telemetría): + * Define una struct Archivo que contenga dos campos: size_t tamano y + * uint8_t *datos. Escribe una función que reciba el tamaño deseado y reserve + * memoria dinámicamente tanto para la estructura en sí como para su búfer + * interno de datos binarios. + * + * 4. Redimensionamiento con realloc (Stream de Datos en Tiempo Real): + * Crea una rutina que lea números enteros (paquetes de telemetría) desde + * la consola de forma indefinida hasta una condición de parada. Almacénalos + * en un arreglo dinámico que duplique su tamaño cada vez que se llene + * utilizando realloc para optimizar el almacenamiento. + * + * 5. Estructuras Anidadas Dinámicas (Subsistemas del Satélite): + * Crea una estructura principal (por ejemplo, MisionEspacial) que contenga + * un puntero a un arreglo dinámico de subestructuras (representando varios + * subsistemas como energía, propulsión y comunicación). Asegúrate de + * implementar un protocolo estricto de liberación en orden inverso + * (primero las subestructuras internas y sus recursos, luego el arreglo + * principal) para evitar fugas de memoria (memory leaks) críticas en órbita. + * + * REQUISITOS TÉCNICOS: + * - Uso obligatorio de las funciones de (malloc, realloc, free). + * - Validación de punteros (verificar que no sean NULL tras cada reserva). + * - Código limpio, modularizado en funciones y bien comentado. + * ========================================================================= */ + +#include +#include +#include +#include +#include +#include + +typedef struct{ + size_t size; + uint8_t *datos; +}TelemetryFile; + +typedef struct{ + TelemetryFile base; + size_t offset; +}TelemetryArray; + +typedef struct{ + int n_chanels; + int* chanels; + TelemetryFile* telemetry_file; + TelemetryArray telemetry_array; +}ProgramData; + + +void print_menu(ProgramData *); +void print_data(ProgramData *); +void get_nchanels(ProgramData *); +void get_chanels(ProgramData *); + +void get_telemetry_file(ProgramData *); +TelemetryFile* telemetry_file_create(size_t fs); +void telemetry_file_free(ProgramData *); + +void get_telemetry_data(ProgramData *); +bool telemetry_array_is_full(ProgramData *); +void telemetry_array_alloc(ProgramData *); +void telemetry_array_free(ProgramData *); +void telemetry_array_set(ProgramData *, uint8_t data); + +void free_data(ProgramData*); +void pause(void); + + +int main(void){ + + ProgramData data = { + .n_chanels = 0, + .chanels = NULL, + .telemetry_file = NULL, + .telemetry_array = { + .base = { + .size = 0, + .datos = NULL + }, + .offset = 0 + } + }; + + print_menu(&data); + + free_data(&data); + + return 0; +} + +void print_menu(ProgramData* ref_data){ + + int option = 0; + int exit = 0; + + system("clear"); + printf("MENU DE OPCIONES\n"); + printf("\t 1- Cargar canales\n"); + printf("\t 2- Mostrar Datos\n"); + printf("\t 3- Crear archivo de telemetría\n"); + printf("\t 4- Recibir telemetria\n"); + printf("\t 5- Salir\n"); + + scanf("%d", &option); + + switch (option) { + case 1: + get_nchanels(ref_data); + get_chanels(ref_data); + break; + case 2: + print_data(ref_data); + break; + case 3: + get_telemetry_file(ref_data); + break; + case 4: + get_telemetry_data(ref_data); + break; + case 5: + exit = 1; + break; + } + + if(!exit){ + print_menu(ref_data); + } + +} + +void get_telemetry_data(ProgramData *ref_data){ + system("clear"); + printf("RECEPCION DE TELEMETRIA\n"); + uint8_t read_data; + + do{ + printf("\nIngresar valor (0 para terminar):"); + scanf("%" SCNu8, &read_data); + + //printf("Se ha leido: %" SCNu8 "\n", read_data); + + if(read_data > 0){ + telemetry_array_set(ref_data, read_data); + } + + }while(read_data > 0); +} + +bool telemetry_array_is_full(ProgramData *ref_data){ + + uint8_t* start_add = ref_data->telemetry_array.base.datos; + + if(start_add == NULL){ + return true; + } + + uint8_t* end_add = start_add + ref_data->telemetry_array.base.size; + uint8_t* test_add = start_add + ref_data->telemetry_array.offset; + return test_add >= (end_add); +} + +void telemetry_array_alloc(ProgramData *ref_data){ + //Si esta vacio reserva espacio para uno. + if(ref_data->telemetry_array.base.datos == NULL){ + ref_data->telemetry_array.base.datos = malloc(sizeof(uint8_t)); + if(ref_data->telemetry_array.base.datos == NULL){ + perror("Error asignando memoria para streaming de telemetria."); + exit(1); + } + ref_data->telemetry_array.base.size = 1; + ref_data->telemetry_array.offset = 0; + return; + } + + uint8_t* result = realloc(ref_data->telemetry_array.base.datos, ref_data->telemetry_array.base.size * 2); + + if(result == NULL){ + perror("Error reasignando memoria para streaming de telemetria."); + exit(1); + } + + ref_data->telemetry_array.base.datos = result; + ref_data->telemetry_array.base.size *= 2; + + printf("La nueva capacidad es: %zu \n", ref_data->telemetry_array.base.size); +} + +void telemetry_array_free(ProgramData *ref_data){ + if(ref_data->telemetry_array.base.datos == NULL){ + free(ref_data->telemetry_array.base.datos); + ref_data->telemetry_array.base.datos = NULL; + } +} + +void telemetry_array_set(ProgramData *ref_data, uint8_t data){ + if(telemetry_array_is_full(ref_data)){ + printf("Esta lleno, vamos a agrandar \n"); + telemetry_array_alloc(ref_data); + } + + *(ref_data->telemetry_array.base.datos + ref_data->telemetry_array.offset) = data; + ref_data->telemetry_array.offset += 1; +} + + +void get_telemetry_file(ProgramData *ref_data){ + + size_t fs; + + system("clear"); + + printf("CREAR ARCHIVO DE TELEMETRIA\n"); + printf("\tEnter de size in bytes:"); + scanf("%zu", &fs); + + telemetry_file_free(ref_data); + ref_data->telemetry_file = telemetry_file_create(fs); + +} + +void telemetry_file_free(ProgramData *ref_data){ + if(ref_data->telemetry_file != NULL){ + if(ref_data->telemetry_file->datos != NULL){ + free(ref_data->telemetry_file->datos); + ref_data->telemetry_file->datos = NULL; + } + free(ref_data->telemetry_file); + ref_data->telemetry_file = NULL; + } +} + +TelemetryFile* telemetry_file_create(size_t fs){ + TelemetryFile* telemetry_file = malloc(sizeof(TelemetryFile)); + + if(telemetry_file == NULL){ + perror("Error creating telemetry file."); + exit(1); + } + + telemetry_file->size = fs; + telemetry_file->datos = malloc(sizeof(uint8_t)*fs); + + if(telemetry_file->datos == NULL){ + free(telemetry_file); + telemetry_file = NULL; + perror("Error allocating memory for the buffer to telemetry file."); + exit(1); + } + + return telemetry_file; + +} + +void get_nchanels(ProgramData* ref_data){ + system("clear"); + int n_chanels = 0; + printf("Cantidad de canales: "); + scanf("%d", &n_chanels); + + ref_data->n_chanels = n_chanels; + +} + +void get_chanels(ProgramData* ref_data){ + if(ref_data->chanels != NULL){ + free(ref_data->chanels); + ref_data->chanels = NULL; + } + ref_data->chanels = malloc(sizeof(int)*ref_data->n_chanels); + if(ref_data->chanels == NULL){ + perror("No se pudo reservar memoria para los canales."); + exit(1); + } + for(int i=0; i < ref_data->n_chanels; i++){ + int chanel; + printf("Frecuacia en Mhz del canal%d:", i); + scanf("%d", &chanel); + *(ref_data->chanels + i) = chanel; + } +} + +void print_data(ProgramData* ref_data){ + system("clear"); + printf("DATOS DEL PROGRAMA\n"); + printf("Cantidad de canales: %d\n", ref_data->n_chanels); + + for (int i=0; i < ref_data->n_chanels; i++){ + printf("\t CH %d Mhz\n", *(ref_data->chanels + i)); + } + + if(ref_data->telemetry_file != NULL){ + printf("Archivo de telemetria creado. Size: %zu bytes.\n", ref_data->telemetry_file->size); + } + + printf("Datos de telemetria: "); + for(size_t i=0; i < ref_data->telemetry_array.offset; i++){ + printf("%" SCNu8 ", ", *(ref_data->telemetry_array.base.datos + i)); + } + if(ref_data->telemetry_array.base.size == 0){ + printf("No hay datos."); + } + printf("\n"); + pause(); +} + +void free_data(ProgramData* ref_data){ + if(ref_data->chanels){ + free(ref_data->chanels); + } + telemetry_file_free(ref_data); + telemetry_array_free(ref_data); +} + +void pause(void){ + // 1. Limpiamos el búfer por si quedó algún caracter pendiente del scanf anterior + int c; + while ((c = getchar()) != '\n' && c != EOF); + // 2. Mostramos el mensaje y esperamos a que el usuario presione Enter de verdad + printf("Presione Enter para continuar...\n"); + getchar(); +} diff --git a/c/struct3/programa b/c/struct3/programa new file mode 100755 index 0000000..554a794 Binary files /dev/null and b/c/struct3/programa differ diff --git a/c/swap/main.c b/c/swap/main.c new file mode 100644 index 0000000..e3c101a --- /dev/null +++ b/c/swap/main.c @@ -0,0 +1,28 @@ +#include + +void swap(char **, char**); +void swap_int(int *, int *); + +int main(void){ + char *s1 = "Hola"; + char *s2 = "Mundo"; + int n1 = 10; + int n2 = 20; + swap(&s1, &s2); + swap_int(&n1, &n2); + printf("s1: %s s2: %s\n", s1, s2); + printf("n1: %d n2: %d\n", n1, n2); + return 0; +} + +void swap(char **s1, char **s2){ + char *aux = *s1; + *s1 = *s2; + *s2 = aux; +} + +void swap_int(int* n1, int* n2){ + int aux = *n1; + *n1 = *n2; + *n2 = aux; +} diff --git a/c/swap/programa b/c/swap/programa new file mode 100755 index 0000000..623d92d Binary files /dev/null and b/c/swap/programa differ diff --git a/c/swap2/main.c b/c/swap2/main.c new file mode 100644 index 0000000..627b99d --- /dev/null +++ b/c/swap2/main.c @@ -0,0 +1,48 @@ +/* ============================================================================ + * Ejercicio: Modificación de un Puntero a través de un Puntero a Puntero (int **) + * ============================================================================ + * Objetivo: + * Comprender el uso de punteros a punteros para modificar la dirección a la + * que apunta un puntero original dentro de una función (pasaje por referencia). + * + * Descripción: + * Escribe un programa en C que cumpla con los siguientes requisitos: + * + * 1. Define dos variables enteras, por ejemplo: `int x = 10;` e `int y = 20;`. + * 2. Declara un puntero simple a entero, por ejemplo: `int *ptr = &x;`. + * 3. Crea una función llamada `cambiar_puntero` que reciba un puntero a puntero + * (`int **p_ref`) y la dirección de otra variable entera (`int *nueva_dir`). + * La función debe actualizar el puntero original para que ahora apunte a + * esa nueva dirección (`*p_ref = nueva_dir;`). + * 4. En la función `main`, imprime el valor al que apunta `ptr` antes de llamar + * a la función. + * 5. Llama a `cambiar_puntero` pasando la dirección de `ptr` (`&ptr`) y la + * dirección de `y` (`&y`). + * 6. Vuelve a imprimir el valor al que apunta `ptr` después de la llamada para + * verificar que ahora apunta a `y` (su valor debe ser 20). + * + * Restricciones: + * - Debes utilizar obligatoriamente el operador de indirección doble (**). + * - No olvides validar los conceptos de memoria y desreferenciación. + * ============================================================================ */ +#include + +void cambiar_puntero(int**, int*); + +int main(void){ + + int x = 20, y = 30; + int* ptr = &x; + + printf("contenido de ptr = %d \n", *ptr); + + cambiar_puntero(&ptr, &y); + + + printf("contenido de ptr = %d\n", *ptr); + +} + +void cambiar_puntero(int** ptr, int *address){ + *ptr = address; +} diff --git a/c/swap2/programa b/c/swap2/programa new file mode 100755 index 0000000..e11628f Binary files /dev/null and b/c/swap2/programa differ