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;
}
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;
}
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;
}
Exercicis
- Inversa d'un vector: Llegeix 5 enters i mostra'ls en ordre invers.
- 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.
- 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).
- Cerca en array: Implementa una funció que retorni la posició d'un valor en un array, o -1 si no es troba.
- 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.