Array e Funzioni

26 marzo 2024

Array

Array

Generalmente una variabile può contenere un solo valore, spesso però si vuole eseguire operazioni su una sequenza di variabili, una soluzione è l’utilizzo di un array (o vettore). Un array è una collezione di elementi omogenei (tutti dello stesso tipo).

Array

La dichiarazione di un array avviene specificando il tipo e il numero degli elementi:

int a[10]

La dimensione dell’array è una costante intera, spesso definita tramite una macro o una costante:

#define N 10
int a[N];

oppure:

const int N = 10;
int a[N];

Array

Si accede a un elemento dell’array tramite subscripting:

int a[2];
a[0] = 1;
a[1] = 2;

int i;
i = a[0] + a[1]; // i = 3

Gli indici degli array in C partono da 0, come in Java.

Array e indici

Il compilatore C non controlla i limiti degli array, quindi è possibile accedere a elementi fuori dal range definito, questo può causare errori difficili da individuare.

int a[10], i;
for (i = 0; i <= 10; i++) {
    a[i] = 0;
}

Array e indici

Si intuisce che C sia molto permissivo con il subscripting, il seguente codice quindi è perfettamente legittimo:

int a[50];
int i = 0, j = 3;
a[i+j*10] = 0;

i = 0;
while (i < j)
    a[i++] = 0;

Array: inizializzazione

Un array può essere inizializzato al momento della dichiarazione:

int a[5] = {1, 2, 3, 4, 5};

Se si mettono meno numeri, i restanti elementi vengono inizializzati a 0 (ma questo non succede se non ne specifico nessuno!):

int a[5] = {1, 2, 3}; // a = {1, 2, 3, 0, 0}
int b[4] = {0}; // b = {0, 0, 0, 0}

Array: inizializzazione

Se metto più elementi di quelli dichiarati il compilatore segnala un errore. Se invece si omette la dimensione dell’array, il compilatore la calcola automaticamente dalla lista di initializzazione:

int a[] = {1, 2, 3}; // a ha dimensione 3

Dimensione di un array

In C non esiste un sistema per ottenere senza sforzo la dimensione di un array, per questo, spesso, si utilizza una variabile per memorizzare la dimensione dell’array.

Tuttavia si può usare sizeof per ottenere la dimensione di un array:

int a[10];
sizeof(a); /* restituisce 40 su una macchina a 32 bit */
sizeof(a[0]); /* 4 */
sizeof(a)/sizeof(a[0]); /* 10, la dimensione dell'array */

Array multidimensionali

Un array può contenere elementi di qualsiasi tipo, anche altri array! Per dichiarare un array multidimensionale si specifica il numero di elementi per ogni dimensione:

int matrix[5][9];

Per accedere a un elemento di un array multidimensionale si usano più indici:

matrix[1][5] = 42; e NON matrix[1,5] = 42;

Array multidimensionali

int matrix[5][9]; matrix[1][5] = 42;

Array: esempio di esercizio

Scrivere un programma che distribuisca una mano di carte per il gioco della briscola (3 carte) e le stampi a video.

Array: esercizi (1)

Scrivere un programma per calcolare la somma di due array di interi di dimensione 10. La soluzione si compone di 2 parti:

  1. inizializzazione di due array di interi di dimensione 10;
  2. somma degli elementi dei due array e stampa del risultato.

Array: esercizi (2)

Scrivere un programma che stampi la somma delle righe e delle colonne di una matrice \(5 \times 5\) di interi.

La matrice è la seguente: 8 3 9 0 10 3 5 17 1 1 2 8 6 23 1 15 7 3 2 9 6 14 2 6 0

Esempio di esecuzione:

Somma righe: 30 27 40 36 28
Somma colonne: 34 37 37 32 21

Funzioni

Funzioni in C

In C si può pensare a una qualsiasi funzione come una scatola nera con un certo numero di ingressi e un solo output.

Praticamente una funzione è un sottoprogramma, un insieme di istruzioni che esegue un compito specifico.

Funzioni: sintassi

return_type function_name( parameters )
{
    declarations
    statements
}

Esempio:

double average(int a, int b)
{
    double average;
    average = (a + b) / 2.0;
    return average;
}

Funzioni

Il valore di ritorno può non esserci, anche i parametri possono essere void oppure si possono omettere:

void print_hello(void)
{
    printf("Hello, world!\n");
    return;
}

Nota

L’istruzione return può essere omessa in una funzione void.

Dichiarazione e definizione

Le funzioni possono essere dichiarate e definite in due momenti diversi del programma.

La dichiarazione di una funzione è una promessa che il programmatore fa al compilatore: “presto ti dirò cosa fa questa funzione”.

La sintassi della dichiarazione è la stessa della definizione, ma senza il corpo della funzione:

return_type function_name( parameters );

Dichiarazione e definizione

Esempio:

#include <stdio.h>

int sum(int a, int b); // dichiarazione

int main(void)
{
    int x = 3, y = 4;
    int z = sum(x, y);
    printf("La somma di %d e %d è %d\n", x, y, z);
    return 0;
}

int sum(int a, int b) // definizione
{
    return a + b;
}

Argomenti di funzione

Gli argomenti possono anche essere degli array, mentre il tipo di ritorno no.

Se si passa un array come argomento, si può omettere la sua dimensione, ma in tal caso non sarà possibile conoscere la dimensione dell’array all’interno della funzione, per questo spesso si passa anche la dimensione dell’array come argomento.

Esercizi

  1. Scrivere una funzione che trovi il valore minimo in un array di numeri interi la firma della funzione è int array_min(int arr[], int size).

  2. Scrivere una funzione ricorsiva per sommare gli elementi di un array di double, la firma della funzione è double array_sum(double arr[], int size).

  3. Scrivere una funzione ricorsiva che, dato un array di caratteri, ne stampi il contenuto su standard output. La firma della funzione è void print_string(char arr[], int size).

  4. Modificare la soluzione dell’esercizio precedente per stampare l’array in ordine inverso. Implementare poi una soluzione non ricorsiva allo stesso problema.

  5. Scrivere una funzione ricorsiva all che, dato un array di interi, restituisca true se tutti gli elementi dell’array sono diversi da 0, false altrimenti.