Tema 4 - Arrays, Matrius i Cadenes

Inversa d'un vector

Llegeix 5 enters i mostra'ls en ordre invers.

#include <stdio.h>  /* Inclou la biblioteca estàndard d'entrada/sortida */
                     /* Necessària per a printf() i scanf() */

int main(){  /* Funció principal del programa, punt d'entrada d'execució */

    int nombres[5];  /* Declara un array (vector) de 5 enters */
                     /* La mida 5 es fixa entre claudàtors [] */
                     /* Els índexs vàlids van de 0 a 4 (total 5 elements) */
                     /* Cada element ocupa 4 bytes en memòria (tipus int) */

    printf("Introdueix 5 nombres enters:\n");  /* Missatge informatiu per a l'usuari */

    /* Bucle per llegir els 5 nombres i emmagatzemar-los a l'array */
    for(int i = 0; i < 5; i++){  /* Inicialitza i=0, itera mentre i<5, incrementa i */
                                 /* i++ augmenta i en 1 després de cada iteració */
        printf("Nombre %d: ", i + 1);  /* Mostra el número de l'element (1 a 5) */
                                       /* i+1 perquè l'usuari vegi 1,2,3,4,5 en lloc de 0,1,2,3,4 */
        scanf("%d", &nombres[i]);  /* Llegeix un enter i l'emmagatzema a la posició i */
                                   /* &nombres[i] passa l'adreça de l'element i-èssim */
                                   /* nombres[i] accedeix a l'element a la posició i */
    }

    printf("\nNombres en ordre invers:\n");  /* Títol per a la sortida en ordre invers */
                                             /* \n inicial crea una línia en blanc */

    /* Bucle per mostrar els nombres en ordre invers */
    for(int i = 4; i >= 0; i--){  /* Inicialitza i=4 (últim índex), itera mentre i>=0 */
                                  /* i-- decrementa i en 1 després de cada iteració */
                                  /* Comença des del final i va cap al principi */
        printf("%d ", nombres[i]);  /* Mostra l'element a la posició i seguit d'un espai */
                                    /* Quan i=4 mostra l'últim, i=3 el penúltim, etc. */
    }
    printf("\n");  /* Salt de línia final per netejar la sortida */

    return 0;  /* Retorna 0 al sistema operatiu indicant execució correcta */
               /* El valor 0 és l'estàndard per indicar èxit en C */
}

Matriu de notes

Crea una matriu 3x4 amb notes de 3 assignatures i 4 alumnes. Calcula la mitjana de cada alumne i de cada assignatura.

#include <stdio.h>  /* Inclou la biblioteca estàndard d'entrada/sortida */

int main(){  /* Funció principal del programa */

    /* Declara una matriu (array bidimensional) de 3 files x 4 columnes */
    /* 3 files = 3 assignatures, 4 columnes = 4 alumnes */
    float notes[3][4];  /* Matriu de floats (nombres decimals) */
                         /* Primer índex [3]: nombre de files (assignatures) */
                         /* Segon índex [4]: nombre de columnes (alumnes) */
                         /* Total: 3 x 4 = 12 elements */

    /* Arrays amb els noms de les assignatures per mostrar-los */
    char assignatures[3][20] = {"Matematiques", "Fisica", "Quimica"};  /* Matriu de cadenes */
                                                                       /* 3 files, cada una amb màxim 19 caràcters + '\0' */

    /* Bucle per introduir les notes de tots els alumnes i assignatures */
    for(int i = 0; i < 3; i++){  /* Bucle extern: recorre les files (assignatures) */
                                 /* i=0: Matemàtiques, i=1: Física, i=2: Química */
        printf("\nNotes de %s:\n", assignatures[i]);  /* Mostra el nom de l'assignatura */
        for(int j = 0; j < 4; j++){  /* Bucle intern: recorre les columnes (alumnes) */
                                     /* j=0: Alumne 1, j=1: Alumne 2, etc. */
            printf("  Alumne %d: ", j + 1);  /* Demana la nota de l'alumne j+1 */
            scanf("%f", ¬es[i][j]);  /* Llegeix un float i l'emmagatzema */
                                        /* notes[i][j] accedeix a la fila i, columna j */
                                        /* ¬es[i][j] passa l'adreça de l'element */
        }
    }

    /* CÀLCUL DE MITJANES PER ALUMNE (columnes) */
    printf("\n=== MITJANES PER ALUMNE ===\n");  /* Títol de la secció */
    for(int j = 0; j < 4; j++){  /* Bucle per recórrer cada alumne (columna) */
        float suma = 0;  /* Acumulador per a la suma de notes de l'alumne j */
                         /* S'inicialitza a 0 per començar la suma correctament */
                         /* Es reinicia a 0 per a cada alumne */
        for(int i = 0; i < 3; i++){  /* Bucle per sumar les 3 notes de l'alumne */
            suma = suma + notes[i][j];  /* Acumula la nota de l'assignatura i, alumne j */
                                        /* notes[i][j]: fila i (assignatura), columna j (alumne) */
        }
        float mitjana = suma / 3;  /* Calcula la mitjana dividint per 3 assignatures */
                                   /* 3 és el nombre total d'assignatures */
        printf("Alumne %d: %.2f\n", j + 1, mitjana);  /* Mostra la mitjana amb 2 decimals */
                                                      /* %.2f formata el float amb 2 decimals */
    }

    /* CÀLCUL DE MITJANES PER ASSIGNATURA (files) */
    printf("\n=== MITJANES PER ASSIGNATURA ===\n");  /* Títol de la secció */
    for(int i = 0; i < 3; i++){  /* Bucle per recórrer cada assignatura (fila) */
        float suma = 0;  /* Acumulador per a la suma de notes de l'assignatura i */
        for(int j = 0; j < 4; j++){  /* Bucle per sumar les 4 notes de l'assignatura */
            suma = suma + notes[i][j];  /* Acumula la nota de l'assignatura i, alumne j */
        }
        float mitjana = suma / 4;  /* Calcula la mitjana dividint per 4 alumnes */
                                   /* 4 és el nombre total d'alumnes */
        printf("%s: %.2f\n", assignatures[i], mitjana);  /* Mostra l'assignatura i la seva mitjana */
    }

    return 0;  /* Finalitza el programa amb èxit */
}

Comptador de codons

Donada una seqüència d'ADN (per exemple "ATGCCGTA"), calcula quants codons (triplets) conté (ignora caràcters no A,C,G,T).

#include <stdio.h>  /* Inclou la biblioteca estàndard d'entrada/sortida */
#include <string.h>  /* Inclou la biblioteca per a funcions de cadenes */
                     /* Necessària per a strlen() que calcula la longitud */
#include <ctype.h>   /* Inclou la biblioteca per a classificació de caràcters */
                     /* Necessària per a toupper() que converteix a majúscules */

int main(){  /* Funció principal del programa */

    char adn[101];  /* Array per emmagatzemar la seqüència d'ADN */
                    /* Mida 101: fins a 100 caràcters + '\0' */

    printf("Introdueix una sequencia d'ADN: ");  /* Demana la seqüència a l'usuari */
    scanf("%100s", adn);  /* Llegeix fins a 100 caràcters per evitar desbordaments */
                          /* %100s limita la lectura a 100 caràcters màxim */

    int longitud = strlen(adn);  /* Calcula la longitud de la cadena introduïda */
                                 /* strlen() compta els caràcters fins a trobar '\0' */
                                 /* Retorna un valor de tipus size_t (enter sense signe) */

    int bases_valides = 0;  /* Comptador de bases vàlides (A, C, G, T) */
                            /* S'inicialitza a 0 per començar el recompte */

    /* Bucle per comptar les bases vàlides */
    for(int i = 0; i < longitud; i++){  /* Recorre cada caràcter de la cadena */
                                        /* i va de 0 fins a longitud-1 */
        char base = toupper(adn[i]);  /* Converteix el caràcter actual a majúscula */
                                      /* toupper() retorna la versió majúscula */
                                      /* Si ja és majúscula, la retorna igual */
                                      /* Això permet acceptar tant minúscules com majúscules */

        /* Comprova si el caràcter és una base nitrogenada vàlida */
        if(base == 'A' || base == 'C' || base == 'G' || base == 'T')
            bases_valides++;  /* Si és vàlida, incrementa el comptador en 1 */
                              /* bases_valides++ és equivalent a bases_valides = bases_valides + 1 */
        /* Si no és una base vàlida, simplement s'ignora (no s'incrementa el comptador) */
    }

    /* Calcula el nombre de codons complets */
    int codons = bases_valides / 3;  /* Divisió entera: quants grups de 3 es poden formar */
                                     /* Exemple: 9 bases / 3 = 3 codons */
                                     /* Exemple: 7 bases / 3 = 2 codons (1 base sobrant) */
                                     /* L'operador / amb enters trunca els decimals */

    int residu = bases_valides % 3;  /* Calcula les bases que sobren amb l'operador mòdul */
                                     /* % retorna el residu de la divisió entera */
                                     /* 7 % 3 = 1 (una base sobrant) */
                                     /* 9 % 3 = 0 (cap base sobrant) */

    /* Mostra els resultats a l'usuari */
    printf("\nSequencia: %s\n", adn);  /* Mostra la seqüència original */
    printf("Bases valides trobades: %d\n", bases_valides);  /* Nombre de bases vàlides */
    printf("Nombre de codons complets: %d\n", codons);  /* Nombre de codons */

    if(residu > 0)  /* Si hi ha bases sobrants */
        printf("Queden %d base(s) sense formar un codo complet.\n", residu);
        /* Informa de les bases que no completen un triplet */

    return 0;  /* Finalitza el programa amb èxit */
}

Cerca en array

Implementa una funció que retorni la posició d'un valor en un array, o -1 si no es troba.

#include <stdio.h>  /* Inclou la biblioteca estàndard d'entrada/sortida */

/* Prototip (declaració) de la funció de cerca */
/* Informa al compilador sobre l'existència de la funció abans d'usar-la */
int cerca_valor(int array[], int mida, int valor);  /* Rep un array, la seva mida i el valor a buscar */
                                                    /* Retorna un enter: la posició trobada o -1 */
                                                    /* int array[] és equivalent a int* array (punter) */

int main(){  /* Funció principal del programa */

    int nombres[8] = {12, 45, 7, 89, 23, 56, 3, 78};  /* Declara i inicialitza un array amb 8 valors */
                                                       /* La mida es calcula automàticament (8 elements) */
                                                       /* Els valors s'assignen en ordre: nombres[0]=12, nombres[1]=45, etc. */

    int mida = 8;  /* Variable que emmagatzema la mida de l'array */
                   /* És important conèixer la mida per no accedir fora dels límits */
    int buscar;  /* Variable per emmagatzemar el valor que l'usuari vol buscar */

    /* Mostra el contingut de l'array perquè l'usuari sàpiga quins valors hi ha */
    printf("Array: ");  /* Etiqueta per a la llista de valors */
    for(int i = 0; i < mida; i++)  /* Bucle per recórrer tot l'array */
        printf("%d ", nombres[i]);  /* Mostra cada element seguit d'un espai */
    printf("\n");  /* Salt de línia al final */

    printf("Quin valor vols buscar? ");  /* Demana el valor a buscar */
    scanf("%d", &buscar);  /* Llegeix l'enter introduït per l'usuari */

    /* Crida a la funció de cerca i guarda el resultat */
    int posicio = cerca_valor(nombres, mida, buscar);  /* Passa l'array, la mida i el valor */
                                                       /* 'nombres' passa l'adreça del primer element */
                                                       /* El resultat s'emmagatzema a 'posicio' */

    /* Avalua el resultat de la cerca */
    if(posicio != -1)  /* Si la posició és diferent de -1 (s'ha trobat) */
        printf("Valor %d trobat a la posicio %d (index %d).\n", buscar, posicio + 1, posicio);
        /* Mostra la posició en format humà (posicio+1) i l'índex real (posicio) */
        /* posicio+1 perquè l'usuari vegi 1,2,3... en lloc de 0,1,2... */
    else  /* Si la funció ha retornat -1 (no trobat) */
        printf("Valor %d no trobat a l'array.\n", buscar);  /* Missatge de valor no trobat */

    return 0;  /* Finalitza el programa amb èxit */
}

/* Implementació de la funció de cerca */
int cerca_valor(int array[], int mida, int valor){  /* Paràmetres: array, mida i valor a buscar */
                                                    /* Retorna un enter (int) */

    /* Bucle per recórrer l'array seqüencialment */
    for(int i = 0; i < mida; i++){  /* Itera des de l'índex 0 fins a mida-1 */
        if(array[i] == valor)  /* Comprova si l'element actual és igual al valor buscat */
                               /* == és l'operador de comparació d'igualtat */
            return i;  /* Si el troba, retorna immediatament l'índex i */
                       /* 'return' finalitza la funció i retorna el valor */
                       /* No cal seguir buscant un cop trobat */
    }

    return -1;  /* Si el bucle acaba sense haver trobat el valor, retorna -1 */
                /* -1 és un valor convencional per indicar "no trobat" */
                /* No pot ser un índex vàlid perquè els índexs comencen a 0 */
}

Eliminar espais

Escriu una funció que elimini tots els espais d'una cadena (modificant-la in situ).

#include <stdio.h>  /* Inclou la biblioteca estàndard d'entrada/sortida */
#include <string.h>  /* Inclou la biblioteca per a funcions de cadenes */

/* Prototip de la funció per eliminar espais */
void eliminar_espais(char cadena[]);  /* Rep una cadena (array de caràcters) */
                                      /* 'void' indica que no retorna cap valor */
                                      /* Modifica la cadena directament (in situ) */

int main(){  /* Funció principal del programa */

    char text[200];  /* Array per emmagatzemar la cadena introduïda */
                     /* Mida 200: fins a 199 caràcters + '\0' */

    printf("Introdueix una frase amb espais: ");  /* Demana text a l'usuari */
    /* Utilitza fgets() en lloc de scanf() per llegir una línia completa amb espais */
    fgets(text, 200, stdin);  /* Llegeix fins a 199 caràcters de l'entrada estàndard (teclat) */
                              /* fgets() inclou espais i llegeix fins a newline */
                              /* stdin és el flux d'entrada estàndard (teclat) */
                              /* A diferència de scanf("%s"), fgets() llegeix tota la línia */

    /* Elimina el salt de línia final que fgets() afegeix */
    /* fgets() inclou el caràcter '\n' al final si hi cap */
    int len = strlen(text);  /* Calcula la longitud de la cadena */
    if(len > 0 && text[len-1] == '\n')  /* Si l'últim caràcter és un salt de línia */
        text[len-1] = '\0';  /* El substitueix pel caràcter nul (final de cadena) */
                             /* Així eliminem el '\n' sobrant */

    printf("Original: \"%s\"\n", text);  /* Mostra la cadena original entre cometes */
                                         /* \" imprimeix una cometa doble literal */

    eliminar_espais(text);  /* Crida a la funció que modifica la cadena */
                            /* 'text' es passa per referència (com a array) */
                            /* La funció modificarà directament l'array original */

    printf("Sense espais: \"%s\"\n", text);  /* Mostra la cadena ja modificada */

    return 0;  /* Finalitza el programa amb èxit */
}

/* Implementació de la funció per eliminar espais */
void eliminar_espais(char cadena[]){  /* Rep la cadena a modificar */
                                      /* No retorna res (void) */

    int i = 0;  /* Índex per recórrer la cadena original (índex de lectura) */
    int j = 0;  /* Índex per construir la nova cadena sense espais (índex d'escriptura) */

    /* Bucle per processar tota la cadena */
    while(cadena[i] != '\0'){  /* Continua mentre no s'arribi al final de la cadena */
                               /* '\0' és el caràcter nul que marca el final */

        if(cadena[i] != ' '){  /* Si el caràcter actual NO és un espai */
            cadena[j] = cadena[i];  /* Copia el caràcter a la posició j */
                                    /* Això "compacta" la cadena, saltant els espais */
            j++;  /* Incrementa l'índex d'escriptura per al següent caràcter */
        }
        /* Si el caràcter ÉS un espai, simplement no es copia (es "salta") */

        i++;  /* Sempre incrementa l'índex de lectura per avançar en la cadena */
    }

    cadena[j] = '\0';  /* Un cop processada tota la cadena, afegeix el caràcter nul */
                       /* a la posició j per marcar el nou final de la cadena */
                       /* Sense això, la cadena conservaria caràcters antics al final */
}

/*
 * EXEMPLE D'EXECUCIÓ:
 * Entrada: "Hola mon bon dia"
 * Procés:
 *   i=0: 'H' != ' ' -> cadena[0]='H', j=1
 *   i=1: 'o' != ' ' -> cadena[1]='o', j=2
 *   i=2: 'l' != ' ' -> cadena[2]='l', j=3
 *   i=3: 'a' != ' ' -> cadena[3]='a', j=4
 *   i=4: ' ' == ' ' -> NO es copia, j es queda a 4
 *   i=5: 'm' != ' ' -> cadena[4]='m', j=5
 *   ... i així successivament
 * Resultat: "Holamonbondia"
 */

Mini Projecte – Gestor de seqüències d'ADN

Crea un programa amb un menú per gestionar un conjunt de seqüències d'ADN.

#include <stdio.h>  /* Inclou la biblioteca estàndard d'entrada/sortida */
#include <string.h>  /* Inclou la biblioteca per a funcions de cadenes */
#include <ctype.h>   /* Inclou la biblioteca per a classificació de caràcters */
                     /* Necessària per a toupper() */

/* Constants del programa (valors que no canvien) */
#define MAX_SEQUENCIES 10  /* Nombre màxim de seqüències que es poden emmagatzemar */
                           /* #define crea una macro: el compilador substitueix el text */
#define MAX_LONGITUD 100   /* Longitud màxima de cada seqüència (caràcters) */
                           /* S'usa per definir les dimensions dels arrays */

/* Variable global: array bidimensional per emmagatzemar totes les seqüències */
/* És global perquè totes les funcions hi puguin accedir fàcilment */
char sequencies[MAX_SEQUENCIES][MAX_LONGITUD + 1];  /* 10 files x 101 columnes */
                                                    /* +1 per al caràcter nul '\0' */
                                                    /* Cada fila és una seqüència */

int total_sequencies = 0;  /* Variable global: comptador de seqüències emmagatzemades */
                           /* S'inicialitza a 0 (cap seqüència emmagatzemada) */
                           /* S'actualitza cada cop que s'afegeix una seqüència */

/* Prototips (declaracions) de totes les funcions del programa */
/* Això permet cridar les funcions des de main() abans de definir-les */
void afegir_sequencia();  /* Funció per afegir una nova seqüència */
void llistar_sequencies();  /* Funció per mostrar totes les seqüències */
void mostrar_estadistiques();  /* Funció per mostrar estadístiques d'una seqüència */
void complementaria_totes();  /* Funció per mostrar la complementària de totes */

/* Funció auxiliar per obtenir la base complementària (usada internament) */
char base_complementaria(char base);  /* Rep una base i retorna la seva complementària */

int main(){  /* Funció principal del programa */

    int opcio;  /* Variable per emmagatzemar l'opció del menú seleccionada */

    do{  /* Bucle do-while: el menú s'executa almenys una vegada */
         /* La condició es comprova al final del bucle */

        /* Mostra el menú principal d'opcions */
        printf("\n========================================\n");  /* Línia separadora */
        printf("     GESTOR DE SEQUENCIES D'ADN\n");  /* Títol del programa */
        printf("========================================\n");
        printf("  Sequencies emmagatzemades: %d / %d\n", total_sequencies, MAX_SEQUENCIES);
        /* Mostra quantes seqüències hi ha i el màxim permès */
        printf("----------------------------------------\n");
        printf("  1. Afegir sequencia\n");  /* Opció 1 */
        printf("  2. Llistar sequencies\n");  /* Opció 2 */
        printf("  3. Mostrar estadistiques\n");  /* Opció 3 */
        printf("  4. Complementaria de totes\n");  /* Opció 4 */
        printf("  0. Sortir\n");  /* Opció per sortir */
        printf("----------------------------------------\n");
        printf("  Selecciona una opcio: ");  /* Demana la selecció */
        scanf("%d", &opcio);  /* Llegeix l'opció triada */
        getchar();  /* Consumeix el salt de línia que queda al buffer */
                    /* Necessari perquè scanf() deixa '\n' al buffer d'entrada */
                    /* Evita problemes amb lectures posteriors de caràcters */

        /* Estructura switch per executar l'opció seleccionada */
        switch(opcio){  /* Avalua el valor de 'opcio' */
            case 1:  /* Si l'usuari tria 1 */
                afegir_sequencia();  /* Crida a la funció per afegir seqüència */
                break;  /* Surt de l'estructura switch */
            case 2:  /* Si l'usuari tria 2 */
                llistar_sequencies();  /* Crida a la funció per llistar */
                break;
            case 3:  /* Si l'usuari tria 3 */
                mostrar_estadistiques();  /* Crida a la funció d'estadístiques */
                break;
            case 4:  /* Si l'usuari tria 4 */
                complementaria_totes();  /* Crida a la funció de complementàries */
                break;
            case 0:  /* Si l'usuari tria 0 */
                printf("\n  Adeu! Fins aviat.\n");  /* Missatge de comiat */
                break;
            default:  /* Si l'opció no és cap de les anteriors */
                printf("\n  Opcio no valida. Torna-ho a intentar.\n");  /* Missatge d'error */
        }
    } while(opcio != 0);  /* El bucle continua mentre opcio sigui diferent de 0 */
                          /* Quan opcio==0, la condició és falsa i el bucle acaba */

    return 0;  /* Finalitza el programa amb èxit */
}

/* Funció per afegir una nova seqüència d'ADN */
void afegir_sequencia(){

    /* Comprova si hi ha espai per a més seqüències */
    if(total_sequencies >= MAX_SEQUENCIES){  /* Si ja s'ha arribat al màxim */
        printf("\n  ERROR: No es poden afegir mes sequencies (maxim %d).\n", MAX_SEQUENCIES);
        return;  /* Surt de la funció sense fer res més */
    }

    printf("\n  Introdueix la sequencia d'ADN (maxim %d bases): ", MAX_LONGITUD);
    scanf("%100s", sequencies[total_sequencies]);  /* Llegeix la seqüència */
                                                   /* sequencies[total_sequencies] és la fila actual */
                                                   /* %100s limita a 100 caràcters */

    /* Converteix tota la seqüència a majúscules */
    for(int i = 0; sequencies[total_sequencies][i] != '\0'; i++)  /* Recorre la cadena */
        sequencies[total_sequencies][i] = toupper(sequencies[total_sequencies][i]);
        /* Converteix cada caràcter a majúscula amb toupper() */

    total_sequencies++;  /* Incrementa el comptador de seqüències */
                         /* Ara total_sequencies apunta a la següent posició lliure */

    printf("  Sequencia afegida correctament (index %d).\n", total_sequencies - 1);
    /* Confirma que s'ha afegit i mostra l'índex assignat */
    /* total_sequencies-1 perquè ja s'ha incrementat */
}

/* Funció per llistar totes les seqüències emmagatzemades */
void llistar_sequencies(){

    /* Comprova si hi ha seqüències per mostrar */
    if(total_sequencies == 0){  /* Si el comptador és 0 */
        printf("\n  No hi ha sequencies emmagatzemades.\n");  /* Missatge informatiu */
        return;  /* Surt de la funció */
    }

    printf("\n  === SEQUENCIES EMMAGATZEMADES ===\n");  /* Títol */
    for(int i = 0; i < total_sequencies; i++){  /* Recorre totes les seqüències */
        printf("  [%d] %s\n", i, sequencies[i]);  /* Mostra índex i contingut */
                                                  /* sequencies[i] accedeix a la fila i */
    }
}

/* Funció per mostrar estadístiques d'una seqüència concreta */
void mostrar_estadistiques(){

    if(total_sequencies == 0){  /* Verifica que hi hagi seqüències */
        printf("\n  No hi ha sequencies emmagatzemades.\n");
        return;
    }

    int index;  /* Variable per a l'índex de la seqüència a analitzar */
    printf("\n  Quin index de sequencia vols analitzar? (0 a %d): ", total_sequencies - 1);
    scanf("%d", &index);  /* Llegeix l'índex triat */

    /* Valida que l'índex estigui dins del rang permès */
    if(index < 0 || index >= total_sequencies){  /* Si és negatiu o massa gran */
        printf("  Index no valid.\n");  /* Missatge d'error */
        return;  /* Surt de la funció */
    }

    /* Mostra la seqüència seleccionada */
    printf("\n  Sequencia [%d]: %s\n", index, sequencies[index]);

    int comptador[4] = {0, 0, 0, 0};  /* Array per comptar A, C, G, T */
                                       /* índex 0=A, 1=C, 2=G, 3=T */
    int total = 0;  /* Comptador del total de bases vàlides */

    /* Bucle per analitzar la seqüència caràcter per caràcter */
    for(int i = 0; sequencies[index][i] != '\0'; i++){  /* Recorre la cadena */
        switch(sequencies[index][i]){  /* Avalua el caràcter actual */
            case 'A': comptador[0]++; total++; break;  /* Adenina */
            case 'C': comptador[1]++; total++; break;  /* Citosina */
            case 'G': comptador[2]++; total++; break;  /* Guanina */
            case 'T': comptador[3]++; total++; break;  /* Timina */
            /* Altres caràcters s'ignoren */
        }
    }

    /* Mostra el recompte i percentatges de cada base */
    printf("\n  --- COMPOSICIO ---\n");
    char bases_nom[] = {'A', 'C', 'G', 'T'};  /* Array amb les lletres */
    for(int i = 0; i < 4; i++){  /* Per a cada base */
        float pct = 0.0;  /* Percentatge, inicialitzat a 0 */
        if(total > 0)  /* Evita divisió per zero */
            pct = (float)comptador[i] / total * 100;  /* Calcula el percentatge */
        printf("  %c: %d (%.1f%%)\n", bases_nom[i], comptador[i], pct);
    }

    /* Calcula i mostra el contingut GC */
    if(total > 0){  /* Si hi ha bases vàlides */
        float gc = (float)(comptador[1] + comptador[2]) / total * 100;
        /* comptador[1]=C, comptador[2]=G */
        printf("  Contingut GC: %.1f%%\n", gc);
    }

    /* Calcula i mostra la complementària */
    printf("\n  Complementaria: ");
    for(int i = 0; sequencies[index][i] != '\0'; i++)  /* Recorre la seqüència */
        printf("%c", base_complementaria(sequencies[index][i]));  /* Mostra cada base complementària */
    printf("\n");
}

/* Funció per mostrar la complementària de totes les seqüències */
void complementaria_totes(){

    if(total_sequencies == 0){  /* Verifica que hi hagi seqüències */
        printf("\n  No hi ha sequencies emmagatzemades.\n");
        return;
    }

    printf("\n  === COMPLEMENTARIES DE TOTES LES SEQUENCIES ===\n");
    for(int i = 0; i < total_sequencies; i++){  /* Recorre cada seqüència */
        printf("  [%d] %s\n", i, sequencies[i]);  /* Mostra l'original */
        printf("      ");  /* Espai per alinear */
        for(int j = 0; sequencies[i][j] != '\0'; j++)  /* Recorre la cadena */
            printf("%c", base_complementaria(sequencies[i][j]));  /* Complementària */
        printf("\n\n");  /* Doble salt de línia entre seqüències */
    }
}

/* Funció auxiliar: retorna la base complementària d'una base donada */
char base_complementaria(char base){  /* Rep un caràcter i retorna un caràcter */
    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 */
        default:  return base;  /* Si no és una base, retorna el mateix caràcter */
                                /* Així es mantenen caràcters no vàlids sense canvis */
    }
}