C/C++

Tema 4 · Vectors, matrius, cadenes

Introducció

Per treballar amb múltiples dades del mateix tipus utilitzem vectors (arrays) i matrius (arrays bidimensionals). Les cadenes de caràcters són vectors de char acabats amb '\0'. Aquestes estructures són fonamentals per emmagatzemar seqüències d'ADN, llistes de pacients, dades experimentals, etc.

Objectius

  • Declarar i inicialitzar vectors i matrius
  • Recórrer arrays amb bucles i realitzar càlculs (mitjana, màxim, cerca)
  • Treballar amb cadenes: strlen(), strcpy(), strcmp(), strcat()
  • Processar seqüències d'ADN (comptar bases, %GC, complementària)
  • Passar arrays com a paràmetres a funcions

1. Vectors (arrays 1D)

Un vector agrupa variables del mateix tipus, accessibles per un índex (comença a 0).

1.1 Declaració i inicialització

#include <stdio.h>

int main() {
    // Inicialització directa
    float temps[5] = {36.2, 36.8, 37.1, 36.5, 37.0};
    
    // O bé, declarar i després assignar
    int edats[3];
    edats[0] = 25;
    edats[1] = 32;
    edats[2] = 41;

    for (int i = 0; i < 5; i++) {
        printf("Temps[%d] = %.1f\n", i, temps[i]);
    }
    return 0;
}
Els índexs van de 0 a N-1

1.2 Recorregut i càlculs

Calcular la mitjana de les temperatures:

#include <stdio.h>

int main() {
    float temps[] = {36.2, 36.8, 37.1, 36.5, 37.0};
    int n = sizeof(temps) / sizeof(temps[0]); // nombre d'elements
    float suma = 0.0;

    for (int i = 0; i < n; i++) {
        suma += temps[i];
    }
    printf("Mitjana: %.2f °C\n", suma / n);
    return 0;
}
sizeof(temps)/sizeof(temps[0]) dóna la longitud
int max = temps[0];
for (int i = 1; i < n; i++) {
    if (temps[i] > max) max = temps[i];
}
printf("Màxim: %.1f\n", max);

2. Matrius (arrays 2D)

Una matriu és un vector de vectors. S'utilitza per a taules de dades (files i columnes).

2.1 Declaració i recorregut

Dades de glucosa de 3 pacients durant 4 dies:

#include <stdio.h>

int main() {
    int glucosa[3][4] = {
        {110, 125, 118, 130},
        {95,  102, 88,  91},
        {140, 135, 142, 138}
    };

    for (int p = 0; p < 3; p++) {
        printf("Pacient %d: ", p+1);
        for (int d = 0; d < 4; d++) {
            printf("%d ", glucosa[p][d]);
        }
        printf("\n");
    }
    return 0;
}
Accés: glucosa[fila][columna]

2.2 Càlcul de la mitjana per pacient

for (int p = 0; p < 3; p++) {
    int suma = 0;
    for (int d = 0; d < 4; d++) {
        suma += glucosa[p][d];
    }
    printf("Pacient %d: mitjana = %.1f\n", p+1, suma / 4.0);
}

3. Cadenes de caràcters

Les cadenes són arrays de char acabats amb '\0'. Cal incloure <string.h> per a les funcions.

3.1 Funcions bàsiques

#include <stdio.h>
#include <string.h>

int main() {
    char seq1[50] = "AGCT";
    char seq2[50];

    // Copiar
    strcpy(seq2, seq1);
    printf("seq2: %s\n", seq2);

    // Longitud
    printf("Longitud: %zu\n", strlen(seq2)); // %zu per size_t

    // Comparar
    if (strcmp(seq1, seq2) == 0)
        printf("Són iguals\n");

    // Concatenar
    strcat(seq2, "TTA");
    printf("seq2 concatenada: %s\n", seq2); // AGCTTTA

    return 0;
}

3.2 Processament d'ADN

Comptar bases en una seqüència:

#include <stdio.h>
#include <string.h>

int main() {
    char adn[100];
    printf("Introdueix seqüència d'ADN: ");
    scanf("%s", adn); // sense &, ja que és un array

    int a=0, c=0, g=0, t=0;
    for (int i = 0; i < strlen(adn); i++) {
        switch (adn[i]) {
            case 'A': a++; break;
            case 'C': c++; break;
            case 'G': g++; break;
            case 'T': t++; break;
        }
    }
    printf("A:%d C:%d G:%d T:%d\n", a, c, g, t);
    return 0;
}
scanf("%s", adn) llegeix fins a espai o salt de línia

3.3 Seqüència complementària

void complementaria(char *adn, char *resultat) {
    int len = strlen(adn);
    for (int i = 0; i < len; i++) {
        switch (adn[i]) {
            case 'A': resultat[i] = 'T'; break;
            case 'T': resultat[i] = 'A'; break;
            case 'C': resultat[i] = 'G'; break;
            case 'G': resultat[i] = 'C'; break;
            default:  resultat[i] = adn[i]; // si hi ha caràcter no vàlid
        }
    }
    resultat[len] = '\0'; // important!
}

4. Funcions amb arrays

Els arrays es passen per referència (es modifiquen dins de la funció). Hem de passar també la seva mida.

#include <stdio.h>

// Funció que retorna la mitjana d'un array de floats
float mitjana(float arr[], int n) {
    float suma = 0;
    for (int i = 0; i < n; i++) {
        suma += arr[i];
    }
    return suma / n;
}

// Funció que inverteix l'array (modifica l'original)
void invertir(int arr[], int n) {
    for (int i = 0; i < n/2; i++) {
        int temp = arr[i];
        arr[i] = arr[n-1-i];
        arr[n-1-i] = temp;
    }
}

int main() {
    float temps[5] = {36.2, 36.8, 37.1, 36.5, 37.0};
    printf("Mitjana: %.2f\n", mitjana(temps, 5));

    int nums[4] = {1, 2, 3, 4};
    invertir(nums, 4);
    for (int i = 0; i < 4; i++) printf("%d ", nums[i]); // 4 3 2 1
    return 0;
}
La funció pot modificar l'array original

Exercicis

  1. Inversa d'un vector: Llegeix 5 enters i mostra'ls en ordre invers.
  2. 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.
  3. 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).
  4. Cerca en array: Implementa una funció que retorni la posició d'un valor en un array, o -1 si no es troba.
  5. Eliminar espais: Escriu una funció que elimini tots els espais d'una cadena (modificant-la in situ).

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

Crea un programa amb un menú que permeti:

  • 1. Afegir seqüència: Llegeix una cadena d'ADN (màxim 100 caràcters) i l'emmagatzema en un array de cadenes (màxim 10 seqüències).
  • 2. Llistar seqüències: Mostra totes les seqüències emmagatzemades amb el seu índex.
  • 3. Mostrar estadístiques: Per a una seqüència donada (per índex), mostra el nombre de cada base, el %GC i la seva complementària.
  • 4. Complementària de totes: Mostra la complementària de cada seqüència.
  • 0. Sortir.

Utilitza funcions per a cada operació i manté les seqüències en un array bidimensional de char.