Escriu una funció swap(int *a, int *b) que intercanviï dos enters mitjançant punters.
#include <stdio.h> /* Inclou la biblioteca estàndard d'entrada/sortida */
/* Necessària per a printf() */
/* Prototip (declaració) de la funció swap */
/* Els paràmetres són punters a enter (int*) */
/* Un punter és una variable que emmagatzema una adreça de memòria */
void swap(int *a, int *b); /* Rep dos punters a enters */
/* 'void' indica que no retorna cap valor */
/* Modificarà els valors a través dels punters */
int main(){ /* Funció principal del programa */
int x = 10; /* Declara i inicialitza x amb el valor 10 */
int y = 25; /* Declara i inicialitza y amb el valor 25 */
printf("Abans de l'intercanvi:\n"); /* Títol per a l'estat inicial */
printf(" x = %d, y = %d\n", x, y); /* Mostra els valors originals */
swap(&x, &y); /* Crida a la funció swap passant les ADRECES de x i y */
/* L'operador & obté l'adreça de memòria d'una variable */
/* &x és l'adreça on està emmagatzemat x */
/* &y és l'adreça on està emmagatzemat y */
/* La funció rebrà aquestes adreces i podrà modificar els valors */
printf("Despres de l'intercanvi:\n"); /* Títol per a l'estat final */
printf(" x = %d, y = %d\n", x, y); /* Mostra els valors ja intercanviats */
/* Demostració addicional per verificar que funciona */
printf("\nComprovacio:\n");
if(x == 25 && y == 10) /* Verifica que els valors s'han intercanviat correctament */
printf(" Intercanvi realitzat correctament!\n");
else
printf(" ERROR: L'intercanvi no ha funcionat.\n");
return 0; /* Finalitza el programa amb èxit */
}
/* Implementació de la funció swap */
void swap(int *a, int *b){ /* Rep dos punters a enters */
/* *a i *b són punters: contenen adreces de memòria */
/* No retorna res, modifica els valors a través dels punters */
int temp = *a; /* Guarda el valor apuntat per 'a' en una variable temporal */
/* L'operador * (desreferència) accedeix al valor emmagatzemat a l'adreça */
/* *a significa "el valor que hi ha a l'adreça continguda en a" */
/* temp rep el valor original de x (10) */
*a = *b; /* Assigna al lloc apuntat per 'a' el valor apuntat per 'b' */
/* *a accedeix a la variable x (a través de l'adreça) */
/* *b accedeix a la variable y (a través de l'adreça) */
/* Ara x conté el valor de y (25) */
*b = temp; /* Assigna al lloc apuntat per 'b' el valor guardat a temp */
/* *b accedeix a la variable y */
/* temp conté el valor original de x (10) */
/* Ara y conté el valor original de x (10) */
/* NOTA: Sense punters, una funció swap(x, y) no funcionaria perquè */
/* C passa els arguments per valor (còpia), no per referència */
/* Amb punters, passem les adreces i podem modificar els originals */
}
Llegeix un nombre enter n, reserva un vector de float de mida n, omple'l i calcula la mitjana i la desviació estàndard.
#include <stdio.h> /* Inclou la biblioteca estàndard d'entrada/sortida */
#include <stdlib.h> /* Inclou la biblioteca estàndard */
/* Necessària per a malloc() i free() */
#include <math.h> /* Inclou la biblioteca matemàtica */
/* Necessària per a sqrt() (arrel quadrada) */
int main(){ /* Funció principal del programa */
int n; /* Variable per emmagatzemar la mida del vector */
printf("Quants nombres vols introduir? "); /* Demana la mida a l'usuari */
scanf("%d", &n); /* Llegeix el nombre d'elements */
/* Validació de l'entrada: la mida ha de ser positiva */
if(n <= 0){ /* Si n és negatiu o zero */
printf("Error: la mida ha de ser un nombre positiu.\n");
return 1; /* Retorna 1 per indicar error (0 és èxit) */
}
/* Reserva de memòria dinàmica amb malloc() */
/* malloc() demana un bloc de memòria al sistema operatiu */
float *vector = (float*)malloc(n * sizeof(float)); /* Reserva espai per a n floats */
/* n * sizeof(float) calcula els bytes necessaris */
/* sizeof(float) retorna la mida en bytes d'un float (normalment 4) */
/* (float*) és un cast: converteix el punter void* a float* */
/* 'vector' és un punter al primer element de l'array reservat */
/* Verifica que la reserva de memòria ha tingut èxit */
if(vector == NULL){ /* Si malloc() retorna NULL, ha fallat la reserva */
/* NULL és una constant que indica "punter nul" (cap adreça vàlida) */
printf("Error: no s'ha pogut reservar memoria.\n");
return 1; /* Surt amb error */
}
/* Bucle per omplir el vector amb dades de l'usuari */
printf("\nIntrodueix %d nombres:\n", n); /* Instruccions */
for(int i = 0; i < n; i++){ /* Itera n vegades */
printf(" Element %d: ", i + 1); /* Demana l'element i+1 */
scanf("%f", &vector[i]); /* Llegeix un float i l'emmagatzema */
/* vector[i] és equivalent a *(vector + i) */
/* Accedeix a l'element i-èssim de l'array dinàmic */
}
/* Càlcul de la mitjana (suma de tots els valors / nombre de valors) */
float suma = 0.0; /* Acumulador per a la suma, inicialitzat a 0 */
for(int i = 0; i < n; i++) /* Recorre tot el vector */
suma += vector[i]; /* Acumula cada element: suma = suma + vector[i] */
float mitjana = suma / n; /* Calcula la mitjana aritmètica */
/* Càlcul de la desviació estàndard */
/* Fórmula: sqrt( sumatori((xi - mitjana)^2) / n ) */
float suma_quadrats = 0.0; /* Acumulador per a la suma de diferències al quadrat */
for(int i = 0; i < n; i++){ /* Recorre tot el vector */
float diferencia = vector[i] - mitjana; /* Calcula (xi - mitjana) */
suma_quadrats += diferencia * diferencia; /* Acumula (xi - mitjana)^2 */
}
float desviacio = sqrt(suma_quadrats / n); /* Calcula l'arrel quadrada de la variància */
/* sqrt() retorna l'arrel quadrada d'un nombre */
/* Mostra els resultats */
printf("\n=== RESULTATS ===\n");
printf("Valors introduits: "); /* Etiqueta */
for(int i = 0; i < n; i++) /* Recorre el vector */
printf("%.2f ", vector[i]); /* Mostra cada valor amb 2 decimals */
printf("\n");
printf("Mitjana: %.4f\n", mitjana); /* Mostra la mitjana amb 4 decimals */
printf("Desviacio estandard: %.4f\n", desviacio); /* Mostra la desviació amb 4 decimals */
/* Allibera la memòria reservada amb free() */
/* És OBLIGATORI alliberar la memòria dinàmica per evitar fuites de memòria */
free(vector); /* Allibera el bloc de memòria apuntat per 'vector' */
/* Després de free(), el punter ja no és vàlid */
/* La memòria torna a estar disponible per al sistema */
return 0; /* Finalitza el programa amb èxit */
}
Crea un programa que llegeixi enters fins que l'usuari introdueixi 0, emmagatzemant-los en un array que creixi amb realloc().
#include <stdio.h> /* Inclou la biblioteca estàndard d'entrada/sortida */
#include <stdlib.h> /* Inclou la biblioteca estàndard */
/* Necessària per a malloc(), realloc() i free() */
int main(){ /* Funció principal del programa */
int capacitat = 2; /* Capacitat inicial de l'array (quants elements hi caben) */
/* Comencem amb poc espai per demostrar realloc() */
int total = 0; /* Comptador d'elements emmagatzemats (quants elements hi ha) */
int *array = NULL; /* Punter a l'array dinàmic, inicialitzat a NULL */
/* NULL indica que encara no s'ha reservat memòria */
printf("Introdueix nombres enters (0 per acabar):\n"); /* Instruccions */
int nombre; /* Variable per llegir cada nombre */
/* Bucle de lectura: continua fins que l'usuari introdueixi 0 */
do{
printf("Nombre: "); /* Demana un nombre */
scanf("%d", &nombre); /* Llegeix l'enter */
if(nombre != 0){ /* Si el nombre no és 0 (el 0 és la condició de sortida) */
/* Comprova si cal redimensionar l'array */
if(total >= capacitat){ /* Si ja hem omplert l'espai reservat */
/* total >= capacitat: no hi ha espai per a més elements */
int nova_capacitat = capacitat * 2; /* Duplica la capacitat */
/* Estratègia comuna per créixer eficientment */
/* realloc() redimensiona un bloc de memòria existent */
/* Si array és NULL, realloc() es comporta com malloc() */
int *temp = (int*)realloc(array, nova_capacitat * sizeof(int));
/* realloc() intenta expandir el bloc actual o moure'l a una altra zona */
/* nova_capacitat * sizeof(int): nova mida total en bytes */
/* Es guarda en un punter temporal per si realloc() falla */
if(temp == NULL){ /* Si realloc() retorna NULL, ha fallat */
printf("Error: no s'ha pogut redimensionar l'array.\n");
free(array); /* Allibera la memòria reservada fins ara */
return 1; /* Surt amb error */
}
array = temp; /* Actualitza el punter amb la nova adreça */
capacitat = nova_capacitat; /* Actualitza la capacitat */
printf(" [Array redimensionat a %d elements]\n", capacitat); /* Informa del canvi */
}
array[total] = nombre; /* Emmagatzema el nombre a la posició actual */
total++; /* Incrementa el comptador d'elements */
}
} while(nombre != 0); /* Continua mentre el nombre no sigui 0 */
/* Mostra el resum dels nombres introduïts */
printf("\n=== RESUM ===\n");
printf("Total de nombres introduits: %d\n", total); /* Mostra quants nombres hi ha */
printf("Capacitat final de l'array: %d\n", capacitat); /* Mostra la capacitat reservada */
printf("Memoria utilitzada: %d bytes\n", total * (int)sizeof(int)); /* Memòria real usada */
printf("Memoria reservada: %d bytes\n", capacitat * (int)sizeof(int)); /* Memòria total reservada */
if(total > 0){ /* Si hi ha elements emmagatzemats */
printf("\nNombres introduits: "); /* Etiqueta */
for(int i = 0; i < total; i++) /* Recorre els elements */
printf("%d ", array[i]); /* Mostra cada element */
printf("\n");
/* Calcula i mostra la suma dels nombres */
int suma = 0; /* Acumulador */
for(int i = 0; i < total; i++) /* Recorre l'array */
suma += array[i]; /* Acumula */
printf("Suma total: %d\n", suma); /* Mostra la suma */
}
/* Allibera la memòria reservada */
free(array); /* Sempre s'ha d'alliberar la memòria dinàmica */
/* Evita fuites de memòria (memory leaks) */
/* Després de free(), array ja no apunta a memòria vàlida */
return 0; /* Finalitza el programa amb èxit */
}
Fes una funció que retorni la inversa complementària d'una cadena d'ADN (ex: "ATGC" → "GCAT") utilitzant memòria dinàmica.
#include <stdio.h> /* Inclou la biblioteca estàndard d'entrada/sortida */
#include <stdlib.h> /* Inclou la biblioteca per a funcions de memòria dinàmica */
/* Necessària per a malloc() i free() */
#include <string.h> /* Inclou la biblioteca per a funcions de cadenes */
/* Necessària per a strlen() */
/* Prototip de la funció inversa_complementaria */
/* Retorna un punter a char (cadena dinàmica) */
/* La cadena retornada s'ha d'alliberar amb free() després d'usar-la */
char* inversa_complementaria(const char* adn); /* const char*: la cadena d'entrada no es modificarà */
/* char*: retorna un punter a la nova cadena dinàmica */
/* Funció auxiliar: retorna la base complementària */
char complement(char base){ /* Rep una base, retorna la seva complementària */
switch(base){ /* Avalua la base */
case 'A': return 'T'; /* Adenina -> Timina */
case 'T': return 'A'; /* Timina -> Adenina */
case 'C': return 'G'; /* Citosina -> Guanina */
case 'G': return 'C'; /* Guanina -> Citosina */
case 'a': return 't'; /* Versió minúscula */
case 't': return 'a';
case 'c': return 'g';
case 'g': return 'c';
default: return base; /* Si no és base, retorna el mateix caràcter */
}
}
int main(){ /* Funció principal */
char original[101]; /* Array per a la cadena introduïda per l'usuari */
/* Mida fixa a l'stack, fins a 100 caràcters + '\0' */
printf("Introdueix una sequencia d'ADN: "); /* Demana la seqüència */
scanf("%100s", original); /* Llegeix fins a 100 caràcters */
/* Crida a la funció que crea la inversa complementària */
char *resultat = inversa_complementaria(original); /* La funció retorna memòria dinàmica */
/* 'resultat' és un punter a la cadena creada */
if(resultat == NULL){ /* Verifica que la funció ha tingut èxit */
printf("Error en processar la sequencia.\n");
return 1; /* Surt amb error */
}
/* Mostra els resultats */
printf("\nSequencia original: %s\n", original); /* Cadena original */
printf("Inversa complementaria: %s\n", resultat); /* Cadena processada */
/* Verificació pas a pas */
printf("\nVerificacio pas a pas:\n");
printf(" Original: ");
for(int i = 0; original[i] != '\0'; i++) /* Mostra caràcter a caràcter */
printf("%c ", original[i]);
printf("\n Complement: ");
for(int i = 0; original[i] != '\0'; i++)
printf("%c ", complement(original[i])); /* Mostra la complementària directa */
printf("\n Inv. Complem: ");
for(int i = 0; resultat[i] != '\0'; i++)
printf("%c ", resultat[i]); /* Mostra la inversa complementària */
printf("\n");
/* Allibera la memòria dinàmica creada per la funció */
free(resultat); /* Obligatori: la funció ha creat memòria amb malloc() */
/* Si no s'allibera, es produeix una fuita de memòria */
resultat = NULL; /* Bona pràctica: assignar NULL després de free() */
/* Evita l'ús accidental d'un punter alliberat (dangling pointer) */
return 0; /* Finalitza el programa amb èxit */
}
/* Implementació de la funció inversa_complementaria */
char* inversa_complementaria(const char* adn){ /* Rep una cadena constant (no es modifica) */
/* Retorna un punter a char (cadena dinàmica) */
int longitud = strlen(adn); /* Calcula la longitud de la cadena d'entrada */
/* strlen() compta fins a '\0' sense incloure'l */
/* Reserva memòria per a la nova cadena */
/* longitud + 1: espai per a tots els caràcters + el caràcter nul '\0' */
char *resultat = (char*)malloc((longitud + 1) * sizeof(char));
/* malloc() reserva un bloc de memòria de la mida especificada */
/* sizeof(char) sempre és 1, però s'inclou per claredat */
/* (char*) converteix el punter void* retornat per malloc() a char* */
if(resultat == NULL){ /* Si malloc() ha fallat */
return NULL; /* Retorna NULL per indicar error */
}
/* Bucle per construir la inversa complementària */
/* Es recorre la cadena original des del final fins al principi */
for(int i = 0; i < longitud; i++){ /* i recorre la cadena original */
/* Per a la posició i del resultat, s'agafa la base des del final de l'original */
char base_original = adn[longitud - 1 - i]; /* Caràcter des del final */
/* Quan i=0: última base de l'original */
/* Quan i=1: penúltima base */
resultat[i] = complement(base_original); /* Assigna la complementària */
}
resultat[longitud] = '\0'; /* Afegeix el caràcter nul al final */
/* Sense '\0', no seria una cadena vàlida en C */
return resultat; /* Retorna el punter a la nova cadena dinàmica */
/* El programador que crida ha de recordar fer free() */
}
Llegeix noms de pacients fins que l'usuari introdueixi "fi" i emmagatzema'ls en un vector de punters (memòria dinàmica). Després ordena'ls alfabèticament i mostra'ls.
#include <stdio.h> /* Inclou la biblioteca estàndard d'entrada/sortida */
#include <stdlib.h> /* Inclou la biblioteca per a memòria dinàmica */
/* Necessària per a malloc(), realloc() i free() */
#include <string.h> /* Inclou la biblioteca per a funcions de cadenes */
/* Necessària per a strlen(), strcpy() i strcmp() */
#define MAX_NOM 100 /* Longitud màxima per a cada nom de pacient */
/* #define crea una constant simbòlica */
int main(){ /* Funció principal */
/* Vector de punters a char (cadenes dinàmiques) */
/* Cada element és un punter que apuntarà a una cadena amb un nom */
char **noms = NULL; /* Punter a punter a char, inicialitzat a NULL */
/* **noms: array dinàmic de punters a cadenes */
int capacitat = 0; /* Capacitat actual del vector de punters */
int total = 0; /* Nombre total de noms emmagatzemats */
char buffer[MAX_NOM]; /* Buffer temporal per llegir cada nom */
/* Array a l'stack, no dinàmic */
printf("Introdueix noms de pacients (escriu 'fi' per acabar):\n");
/* Bucle de lectura de noms */
while(1){ /* Bucle infinit: se surt amb break */
printf("Nom %d: ", total + 1); /* Mostra el número del pacient */
scanf("%99s", buffer); /* Llegeix un nom (fins a 99 caràcters) */
/* Comprova si és la condició de sortida */
if(strcmp(buffer, "fi") == 0 || strcmp(buffer, "FI") == 0)
/* strcmp() compara dues cadenes */
/* Retorna 0 si són iguals */
/* Acceptem tant "fi" com "FI" */
break; /* Surt del bucle while */
/* Comprova si cal expandir el vector de punters */
if(total >= capacitat){ /* Si no hi ha espai per a més punters */
int nova_cap = (capacitat == 0) ? 2 : capacitat * 2; /* Nova capacitat */
/* Operador ternari: si capacitat==0, nova_cap=2; sinó, duplica */
/* realloc() per expandir el vector de punters */
char **temp = (char**)realloc(noms, nova_cap * sizeof(char*));
/* sizeof(char*) és la mida d'un punter (8 bytes en sistemes de 64 bits) */
/* realloc() manté les dades existents i expandeix l'espai */
if(temp == NULL){ /* Si realloc() falla */
printf("Error de memoria.\n");
/* Allibera la memòria ja reservada abans de sortir */
for(int i = 0; i < total; i++)
free(noms[i]); /* Allibera cada cadena */
free(noms); /* Allibera el vector de punters */
return 1;
}
noms = temp; /* Actualitza el punter */
capacitat = nova_cap; /* Actualitza la capacitat */
}
/* Reserva memòria per al nou nom (longitud exacta + 1 per a '\0') */
noms[total] = (char*)malloc((strlen(buffer) + 1) * sizeof(char));
/* strlen(buffer) + 1: espai per als caràcters + '\0' */
if(noms[total] == NULL){ /* Si malloc() falla */
printf("Error de memoria.\n");
for(int i = 0; i < total; i++)
free(noms[i]);
free(noms);
return 1;
}
strcpy(noms[total], buffer); /* Copia el nom al nou espai reservat */
/* strcpy() copia la cadena fins a '\0' */
total++; /* Incrementa el comptador de noms */
}
/* Mostra els noms abans d'ordenar */
printf("\n=== NOMS INTRODUITS (%d) ===\n", total);
for(int i = 0; i < total; i++)
printf(" %d. %s\n", i + 1, noms[i]);
/* Ordenació alfabètica amb el mètode de bombolla (bubble sort) */
for(int i = 0; i < total - 1; i++){ /* Passades del bubble sort */
for(int j = 0; j < total - 1 - i; j++){ /* Comparacions per passada */
if(strcmp(noms[j], noms[j+1]) > 0){ /* Si noms[j] > noms[j+1] alfabèticament */
/* strcmp() retorna >0 si la primera és major */
/* Intercanvia els punters (no les cadenes!) */
char *temp = noms[j]; /* Guarda el punter temporalment */
noms[j] = noms[j+1]; /* Assigna el punter de j+1 a j */
noms[j+1] = temp; /* Assigna el punter guardat a j+1 */
/* Avantatge: intercanviar punters és més ràpid que intercanviar cadenes */
}
}
}
/* Mostra els noms ordenats */
printf("\n=== NOMS ORDENATS ALFABETICAMENT ===\n");
for(int i = 0; i < total; i++)
printf(" %d. %s\n", i + 1, noms[i]);
/* Allibera tota la memòria reservada */
for(int i = 0; i < total; i++)
free(noms[i]); /* Allibera cada cadena individual */
free(noms); /* Allibera el vector de punters */
noms = NULL; /* Bona pràctica: evita punters penjants */
return 0; /* Finalitza el programa amb èxit */
}
Crea un programa amb un menú per gestionar seqüències en format FASTA utilitzant memòria dinàmica.
#include <stdio.h> /* Inclou la biblioteca estàndard d'entrada/sortida */
/* Necessària per a printf(), scanf(), fopen(), fprintf(), fclose() */
#include <stdlib.h> /* Inclou la biblioteca per a memòria dinàmica */
/* Necessària per a malloc(), realloc(), free() */
#include <string.h> /* Inclou la biblioteca per a funcions de cadenes */
/* Necessària per a strlen(), strcpy(), strcmp() */
#include <ctype.h> /* Inclou la biblioteca per a classificació de caràcters */
/* Necessària per a toupper() */
/* Estructura per emmagatzemar una seqüència FASTA */
/* Una estructura agrupa dades relacionades sota un mateix nom */
typedef struct { /* typedef crea un àlies per a l'estructura */
char *capcalera; /* Punter a la capçalera (ex: >gen1) */
/* Memòria dinàmica: es reserva segons la longitud */
char *sequencia; /* Punter a la seqüència d'ADN */
/* Memòria dinàmica: es reserva segons la longitud */
int longitud; /* Longitud de la seqüència (nombre de bases) */
} Fasta; /* 'Fasta' és el nom del tipus d'estructura */
/* Variables globals del gestor */
Fasta *sequencies = NULL; /* Array dinàmic d'estructures Fasta */
/* Comença buit (NULL), creix amb realloc() */
int total_seq = 0; /* Comptador de seqüències emmagatzemades */
int capacitat_seq = 0; /* Capacitat actual de l'array */
/* Prototips de les funcions del programa */
void afegir_sequencia(); /* Afegeix una nova seqüència */
void llistar_sequencies(); /* Llista totes les seqüències */
void analitzar_sequencia(); /* Analitza una seqüència concreta */
void guardar_fitxer(); /* Desa totes les seqüències a un fitxer FASTA */
void alliberar_memoria(); /* Allibera tota la memòria reservada */
/* Funció auxiliar: calcula el percentatge GC d'una seqüència */
float calcular_gc(const char* seq); /* Rep la seqüència, retorna el %GC */
/* Funció auxiliar: obté la base complementària */
char complementaria(char base); /* Rep una base, retorna la complementària */
/* Funció auxiliar: llegeix una línia completa (inclou espais) */
void llegir_línia(char *buffer, int mida); /* Llegeix fins a newline */
int main(){ /* Funció principal */
int opcio; /* Variable per a l'opció del menú */
printf("========================================\n");
printf(" GESTOR DE SEQUENCIES FASTA (DINAMIC)\n");
printf("========================================\n");
do{ /* Bucle del menú principal */
printf("\n--- MENU PRINCIPAL ---\n");
printf(" Sequencies emmagatzemades: %d\n", total_seq);
printf(" 1. Afegir sequencia\n");
printf(" 2. Llistar sequencies\n");
printf(" 3. Analitzar una sequencia\n");
printf(" 4. Guardar a fitxer (output.fasta)\n");
printf(" 0. Sortir\n");
printf(" Opcio: ");
scanf("%d", &opcio);
getchar(); /* Consumeix el '\n' del buffer */
switch(opcio){
case 1: afegir_sequencia(); break;
case 2: llistar_sequencies(); break;
case 3: analitzar_sequencia(); break;
case 4: guardar_fitxer(); break;
case 0:
printf("\nAlliberant memoria i sortint...\n");
alliberar_memoria(); /* Allibera tot abans de sortir */
printf("Adeu!\n");
break;
default:
printf("Opcio no valida.\n");
}
} while(opcio != 0);
return 0; /* Finalitza el programa */
}
/* Funció per afegir una nova seqüència FASTA */
void afegir_sequencia(){
char buffer_cap[200]; /* Buffer per a la capçalera */
char buffer_seq[1000]; /* Buffer per a la seqüència (pot ser llarga) */
printf("\n--- AFEGIR SEQUENCIA ---\n");
/* Llegeix la capçalera */
printf("Capcalera (ex: >gen1): ");
llegir_línia(buffer_cap, 200); /* Llegeix tota la línia */
/* Verifica que la capçalera comenci amb '>' (format FASTA) */
if(buffer_cap[0] != '>'){
printf("Error: la capcalera ha de comencar amb '>'.\n");
return;
}
/* Llegeix la seqüència */
printf("Sequencia d'ADN: ");
llegir_línia(buffer_seq, 1000);
/* Converteix la seqüència a majúscules */
for(int i = 0; buffer_seq[i] != '\0'; i++)
buffer_seq[i] = toupper(buffer_seq[i]);
/* Comprova si cal expandir l'array d'estructures */
if(total_seq >= capacitat_seq){
int nova_cap = (capacitat_seq == 0) ? 2 : capacitat_seq * 2;
Fasta *temp = (Fasta*)realloc(sequencies, nova_cap * sizeof(Fasta));
/* sizeof(Fasta) és la mida de l'estructura completa */
if(temp == NULL){
printf("Error: no s'ha pogut reservar memoria.\n");
return;
}
sequencies = temp;
capacitat_seq = nova_cap;
}
/* Reserva memòria exacta per a la capçalera */
int len_cap = strlen(buffer_cap) + 1;
sequencies[total_seq].capcalera = (char*)malloc(len_cap * sizeof(char));
/* Reserva memòria exacta per a la seqüència */
int len_seq = strlen(buffer_seq) + 1;
sequencies[total_seq].sequencia = (char*)malloc(len_seq * sizeof(char));
/* Verifica que les reserves han tingut èxit */
if(sequencies[total_seq].capcalera == NULL ||
sequencies[total_seq].sequencia == NULL){
printf("Error de memoria.\n");
/* Allibera el que s'hagi pogut reservar */
if(sequencies[total_seq].capcalera) free(sequencies[total_seq].capcalera);
if(sequencies[total_seq].sequencia) free(sequencies[total_seq].sequencia);
return;
}
/* Copia les dades als espais reservats */
strcpy(sequencies[total_seq].capcalera, buffer_cap);
strcpy(sequencies[total_seq].sequencia, buffer_seq);
sequencies[total_seq].longitud = strlen(buffer_seq); /* Guarda la longitud */
total_seq++; /* Incrementa el comptador */
printf("Sequencia afegida correctament! (%d total)\n", total_seq);
}
/* Funció per llistar totes les seqüències */
void llistar_sequencies(){
if(total_seq == 0){
printf("\nNo hi ha sequencies emmagatzemades.\n");
return;
}
printf("\n=== SEQUENCIES EMMAGATZEMADES ===\n");
for(int i = 0; i < total_seq; i++){
printf("[%d] %s\n", i, sequencies[i].capcalera);
printf(" Longitud: %d bases\n", sequencies[i].longitud);
printf(" %%GC: %.1f%%\n", calcular_gc(sequencies[i].sequencia));
/* Mostra els primers 50 caràcters de la seqüència */
printf(" Sequencia: %.50s", sequencies[i].sequencia);
if(sequencies[i].longitud > 50) printf("...");
printf("\n\n");
}
}
/* Funció per analitzar una seqüència concreta */
void analitzar_sequencia(){
if(total_seq == 0){
printf("\nNo hi ha sequencies per analitzar.\n");
return;
}
char cerca[200];
printf("\nIntrodueix la capcalera a analitzar (ex: >gen1): ");
llegir_línia(cerca, 200);
/* Busca la capçalera */
int index = -1;
for(int i = 0; i < total_seq; i++){
if(strcmp(sequencies[i].capcalera, cerca) == 0){
index = i;
break;
}
}
if(index == -1){
printf("Capcalera no trobada.\n");
return;
}
/* Anàlisi de la seqüència trobada */
printf("\n=== ANALISI DE %s ===\n", sequencies[index].capcalera);
printf("Sequencia: %s\n", sequencies[index].sequencia);
printf("Longitud: %d bases\n", sequencies[index].longitud);
/* Comptatge de bases */
int a=0, c=0, g=0, t=0;
for(int i = 0; sequencies[index].sequencia[i] != '\0'; i++){
switch(sequencies[index].sequencia[i]){
case 'A': a++; break;
case 'C': c++; break;
case 'G': g++; break;
case 'T': t++; break;
}
}
int total_bases = a + c + g + t;
printf("\nComposicio:\n");
if(total_bases > 0){
printf(" A: %d (%.1f%%)\n", a, (float)a/total_bases*100);
printf(" C: %d (%.1f%%)\n", c, (float)c/total_bases*100);
printf(" G: %d (%.1f%%)\n", g, (float)g/total_bases*100);
printf(" T: %d (%.1f%%)\n", t, (float)t/total_bases*100);
}
printf(" %%GC: %.1f%%\n", calcular_gc(sequencies[index].sequencia));
/* Complementària */
printf("\nComplementaria: ");
for(int i = 0; sequencies[index].sequencia[i] != '\0'; i++)
printf("%c", complementaria(sequencies[index].sequencia[i]));
printf("\n");
}
/* Funció per guardar totes les seqüències a un fitxer FASTA */
void guardar_fitxer(){
if(total_seq == 0){
printf("\nNo hi ha sequencies per guardar.\n");
return;
}
/* Obre el fitxer en mode escriptura ("w") */
FILE *fitxer = fopen("output.fasta", "w"); /* fopen() obre/crea un fitxer */
/* "w": mode escriptura (sobreescriu si existeix) */
if(fitxer == NULL){ /* Si no s'ha pogut obrir */
printf("Error: no s'ha pogut crear el fitxer output.fasta.\n");
return;
}
/* Escriu cada seqüència al fitxer en format FASTA */
for(int i = 0; i < total_seq; i++){
fprintf(fitxer, "%s\n", sequencies[i].capcalera); /* Escriu la capçalera */
/* Per a seqüències llargues, es poden dividir en línies de 60 caràcters */
int len = sequencies[i].longitud;
for(int j = 0; j < len; j += 60){ /* 60 caràcters per línia (estàndard FASTA) */
fprintf(fitxer, "%.60s\n", sequencies[i].sequencia + j);
/* %.60s imprimeix com a màxim 60 caràcters */
/* sequencies[i].sequencia + j: punter al caràcter j */
}
}
fclose(fitxer); /* Tanca el fitxer (important!) */
/* fclose() assegura que totes les dades s'escriguin al disc */
printf("\nFitxer 'output.fasta' creat correctament amb %d sequencies.\n", total_seq);
}
/* Funció per alliberar tota la memòria reservada */
void alliberar_memoria(){
for(int i = 0; i < total_seq; i++){
free(sequencies[i].capcalera); /* Allibera la capçalera */
free(sequencies[i].sequencia); /* Allibera la seqüència */
}
free(sequencies); /* Allibera l'array d'estructures */
sequencies = NULL; /* Evita punters penjants */
total_seq = 0;
capacitat_seq = 0;
}
/* Funció auxiliar: calcula el percentatge GC */
float calcular_gc(const char* seq){
int gc = 0, total = 0;
for(int i = 0; seq[i] != '\0'; i++){
if(seq[i] == 'G' || seq[i] == 'C') gc++;
if(seq[i] == 'A' || seq[i] == 'C' || seq[i] == 'G' || seq[i] == 'T') total++;
}
if(total == 0) return 0.0;
return (float)gc / total * 100;
}
/* Funció auxiliar: retorna la base complementària */
char complementaria(char base){
switch(base){
case 'A': return 'T';
case 'T': return 'A';
case 'C': return 'G';
case 'G': return 'C';
default: return base;
}
}
/* Funció auxiliar: llegeix una línia completa (inclou espais) */
void llegir_línia(char *buffer, int mida){
fgets(buffer, mida, stdin); /* Llegeix fins a newline o mida-1 */
/* Elimina el salt de línia final si existeix */
int len = strlen(buffer);
if(len > 0 && buffer[len-1] == '\n')
buffer[len-1] = '\0'; /* Substitueix '\n' per '\0' */
}