1. Introduzione agli Array

Gli array sono strutture dati che consentono di immagazzinare una sequenza di variabili omogenee (dello stesso tipo) in memoria. Ogni elemento è accessibile tramite un indice.

Caratteristiche degli Array

2. Dichiarazione e Uso

Sintassi

Tipo nomeArray[dimensione];

Esempi

int numeri[10]; // Array di 10 interi
float valori[5]; // Array di 5 float
char lettere[20]; // Array di 20 caratteri

Inizializzazione

3. Accesso agli Elementi

numeri[0] = 10; // Assegna il valore 10 al primo elemento
printf("%d", numeri[1]); // Stampa il secondo elemento

Nota: L'accesso a un indice fuori dai limiti dell'array causa un errore (segmentation fault).

4. Operazioni su Array

Popolamento

for (int i = 0; i < 5; i++) {
  scanf("%d", &numeri[i]); // Input dall'utente
}

Calcolo della Somma

int somma = 0;
for (int i = 0; i < 5; i++) {
  somma += numeri[i];
}

Ricerca del Massimo

int max = numeri[0];
for (int i = 1; i < 5; i++) {
  if (numeri[i] > max) max = numeri[i];
}

5. Esempi Completi

Scrivere i primi 300 numeri

#include <stdio.h>
int main() {
    int numeri[300];
    for (int i = 0; i < 300; i++) numeri[i] = i + 1;
    return 0;
}

Media, Minimo e Massimo

#include <stdio.h>
int main() {
    int numeri[5] = {5, 3, 7, 2, 9}, somma = 0, max = numeri[0], min = numeri[0];
    for (int i = 0; i < 5; i++) {
      somma += numeri[i];
      if (numeri[i] > max) max = numeri[i];
      if (numeri[i] < min) min = numeri[i];
    }
    printf("Media: %.2f, Massimo: %d, Minimo: %d", somma / 5.0, max, min);
    return 0;
}

6. Copia e Confronto

Copia di Array

for (int i = 0; i < 5; i++) {
    array2[i] = array1[i];
}

Confronto

int uguali = 1;
for (int i = 0; i < 5; i++) {
    if (array1[i] != array2[i]) {
      uguali = 0;
      break;
    }
}

7. Algoritmi Avanzati

Stampare Array in Ordine Inverso

for (int i = 4; i >= 0; i--) {
    printf("%d ", numeri[i]);
}

Ricerca Sequenziale

int trovato = -1;
for (int i = 0; i < 5; i++) {
    if (numeri[i] == valoreCercato) {
      trovato = i;
      break;
    }
}
printf("Indice trovato: %d", trovato);

8. Errori Comuni

int dim;
scanf("%d", &dim);
int array[dim]; // Errore se dim non è noto a tempo di compilazione

9. Esercizi Proposti

Esempio di Soluzione

#include <stdio.h>
int main() {
    int numeri[10], x, somma = 0, prodotto = 1;
    printf("Inserisci 10 numeri:\n");
    for (int i = 0; i < 10; i++) scanf("%d", &numeri[i]);
    printf("Inserisci l'indice X (0-9): ");
    scanf("%d", &x);
    for (int i = 0; i < x; i++) somma += numeri[i];
    for (int i = x + 1; i < 10; i++) prodotto *= numeri[i];
    printf("Somma: %d, Prodotto: %d\n", somma, prodotto);
    return 0;
}












C-Strings

Una C-string è una sequenza di caratteri che rappresenta una stringa in linguaggio C. Questa sequenza è implementata come un array di caratteri, con un carattere speciale di terminazione '\0' (nullo) posto subito dopo l'ultimo carattere utile della stringa.

Dettagli

Ad esempio, la stringa "bisio" viene rappresentata in memoria come:

'b' 'i' 's' 'i' 'o' '\0'
// Con gli indici:
  0   1   2   3   4   5

Modi per Definire una C-String



11. Utilizzo di %s in printf

Il formato %s nella funzione printf in C è utilizzato per stampare una C-string. Questa funzione interpreta l'indirizzo fornito come l'inizio di una sequenza di caratteri (array di caratteri) e stampa i caratteri uno per uno fino a incontrare il carattere terminatore '\0'.

Comportamento

Esempio

#include <stdio.h>
int main() {
    char Cognome[30] = "bisio";
    printf("%s", Cognome);
    return 0;
}

Output

bisio

L'array contiene: {'b', 'i', 's', 'i', 'o', '\0', indeterminati...}.

La funzione printf stampa i caratteri fino al terminatore '\0'.



12. Stampa di una stringa in ordine inverso

Questo programma stampa una stringa in ordine inverso utilizzando un array di caratteri in C.

Codice

#include <stdio.h>
#define MAX 10

int main() {
    int i;
    char Parola[MAX];

    // Legge una stringa da input
    scanf("%s", Parola);

    // Trova la lunghezza della stringa (fino al carattere terminatore '\0')
    i = 0;
    while (i < MAX - 1 && Parola[i] != '\0') {
        i++;
    }

    // Riduce l'indice di uno per escludere il terminatore
    if (Parola[i] == '\0') {
        i--;
    }

    // Stampa la stringa in ordine inverso
    while (i >= 0) {
        printf("%c", Parola[i]);
        i--;
    }

    return 0;
}

Funzionamento

Esempio di Esecuzione

Input:
bisio

Output:
oisib


11.2 Inversione di una stringa all'interno di un array

Questo esempio mostra come invertire una stringa direttamente all'interno di un array di caratteri in C.

Codice

#include <stdio.h>
#define MAX 10

int main() {
    int i, j;
    char Parola[MAX], temp;

    // Legge una stringa da input
    scanf("%s", Parola);

    // Trova la lunghezza della stringa (fino al carattere terminatore '\0')
    i = 0;
    while (i < MAX - 1 && Parola[i] != '\0') {
        i++;
    }

    // Riduce l'indice per posizionarsi sull'ultimo carattere utile
    if (Parola[i] == '\0') {
        i--;
    }

    // Invertire la stringa utilizzando due indici
    j = 0; // inizio della stringa
    while (i > j) {
        // Scambio degli elementi
        temp = Parola[i];
        Parola[i] = Parola[j];
        Parola[j] = temp;

        // Aggiorna gli indici
        i--;
        j++;
    }

    // Stampa la stringa invertita
    printf("\n%s\n", Parola);

    return 0;
}

Spiegazione del funzionamento

Esempio di Esecuzione

Input:
bisio

Output:
oisib


11.3 Verifica di una stringa palindroma

La verifica di una stringa palindroma si basa sul confronto dei caratteri simmetrici, utilizzando due indici: uno che parte dall'inizio della stringa e l'altro dalla fine. Una stringa è considerata palindroma se può essere letta allo stesso modo da sinistra a destra e da destra a sinistra, come nel caso della parola "anna".

Strategia e Fasi

1° FASE: Posizionamento degli Indici

L'obiettivo è determinare la posizione iniziale (i) e finale (j) della stringa. Questo viene fatto iterando sull'array di caratteri che rappresenta la stringa:

int j = 0;
while (j < MAX && Str[j] != '\0') {
    j++;
}
j--; // L'indice `j` viene spostato sull'ultimo carattere utile
int i = 0; // Inizio della stringa

2° FASE: Verifica dei Caratteri Simmetrici

Confronta i caratteri agli estremi della stringa (ai due indici i e j) e avanza verso il centro.

while (i < j && Str[i] == Str[j]) {
    i++; // Avanza da sinistra verso il centro
    j--; // Avanza da destra verso il centro
}
// Se `i` >= `j`, la stringa è palindroma

Caso Pratico

Input: "anna"

Implementazione Completa

#include <stdio.h>
#define MAX 100

// Funzione per calcolare la lunghezza della stringa
int string_length(const char *str) {
    int length = 0;
    while (str[length] != '\0') {
        length++;
    }
    return length;
}

// Funzione per verificare se la stringa è palindroma
int is_palindrome(const char *str) {
    int length = string_length(str);
    int i = 0;
    int j = length - 1;

    while (i < j) {
        if (str[i] != str[j]) {
            return 0; // Non è palindroma
        }
        i++;
        j--;
    }
    return 1; // È palindroma
}

int main() {
    char str[MAX];

    printf("Inserisci una stringa: ");
    scanf("%s", str);

    if (is_palindrome(str)) {
        printf("La stringa \\"%s\\" è palindroma.\\n", str);
    } else {
        printf("La stringa \\"%s\\" non è palindroma.\\n", str);
    }

    return 0;
}

Spiegazione del Codice

Esempio di Esecuzione

Input:
anna

Output:
La stringa "anna" è palindroma.


13. Individuazione dei Massimi Locali in un Array

Per individuare i massimi locali in un array, è necessario confrontare ciascun elemento con i suoi vicini immediati. Un elemento è considerato un massimo locale se il suo valore è maggiore di quello dei suoi vicini.

Definizione di Massimo Locale

Un massimo locale in un array è un elemento che è maggiore dei due elementi che lo precedono (se presenti) e dei due elementi che lo seguono (se presenti). Ad esempio, nell'array [3, 5, 4, 6, 3, 2, 9], i massimi locali sono:

Algoritmo per Trovare i Massimi Locali

  1. Inizializzazione:
  2. Controllo del Primo Elemento:
  3. Controllo degli Elementi Interni:
  4. Controllo dell'Ultimo Elemento:

Implementazione in C

#include <stdio.h>
#define N 7

int main() {
    int A[N] = {3, 5, 4, 6, 3, 2, 9};
    int i;

    // Controllo del primo elemento
    if (A[0] > A[1]) {
        printf("Massimo locale: A[0] = %d\\n", A[0]);
    }

    // Controllo degli elementi interni
    for (i = 1; i < N - 1; i++) {
        if (A[i] > A[i - 1] && A[i] > A[i + 1]) {
            printf("Massimo locale: A[%d] = %d\\n", i, A[i]);
        }
    }

    // Controllo dell'ultimo elemento
    if (A[N - 1] > A[N - 2]) {
        printf("Massimo locale: A[%d] = %d\\n", N - 1, A[N - 1]);
    }

    return 0;
}

Spiegazione del Codice

Esempio di Esecuzione

Input:
A = {3, 5, 4, 6, 3, 2, 9}

Output:
Massimo locale: A[1] = 5
Massimo locale: A[3] = 6
Massimo locale: A[6] = 9


14. Fusione di Due Array Ordinati

Per la fusione di due array ordinati, l'obiettivo è unire i due array in un unico array ordinato mantenendo l'ordine crescente. Questo processo è particolarmente utile in algoritmi di ordinamento come il Merge Sort.

Approccio e Algoritmo

Dati

Passaggi dell'Algoritmo

  1. Inizializzazione:
  2. Confronto degli elementi:
  3. Gestione degli elementi rimanenti:
  4. Termine:

Codice in C

#include <stdio.h>
#define NA 10
#define NB 5

int main() {
    int A[NA] = {2, 4, 5, 8, 11, 13, 18, 23, 29, 37};
    int B[NB] = {3, 5, 9, 12, 15};
    int C[NA + NB];
    int iA = 0, iB = 0, k = 0;

    // Fusione
    while (iA < NA && iB < NB) {
        if (A[iA] <= B[iB]) {
            C[k++] = A[iA++];
        } else {
            C[k++] = B[iB++];
        }
    }

    // Copia degli elementi rimanenti di A
    while (iA < NA) {
        C[k++] = A[iA++];
    }

    // Copia degli elementi rimanenti di B
    while (iB < NB) {
        C[k++] = B[iB++];
    }

    // Stampa dell'array fuso
    printf("Array fuso:\\n");
    for (int i = 0; i < NA + NB; i++) {
        printf("%d ", C[i]);
    }
    printf("\\n");

    return 0;
}

Esempio di Esecuzione

Input:
A = {2, 4, 5, 8, 11, 13, 18, 23, 29, 37}
B = {3, 5, 9, 12, 15}

Output:
C = {2, 3, 4, 5, 5, 8, 9, 11, 12, 13, 15, 18, 23, 29, 37}


15. Conta i caratteri letti in ingresso fino a una stringa di terminazione

Per contare i caratteri letti in ingresso fino a una stringa di terminazione in un programma C, si utilizza un algoritmo che legge carattere per carattere e tiene traccia del conteggio totale. Il ciclo si interrompe quando la sequenza dei caratteri coincide con la stringa terminatrice.

Algoritmo

  1. Inizializzazione:
  2. Lettura carattere per carattere:
  3. Uscita dal ciclo:
  4. Stampa del risultato:

Codice Esempio

#include <stdio.h>
#define LMAX 15

int main() {
    char Term[LMAX + 1] = "fine";
    int cont = 0;
    int n = 0;
    char carletto;

    printf("Inserisci caratteri, termina con la stringa 'fine':\\n");

    while (Term[n] != '\0') {
        scanf("%c%*c", &carletto); // Legge un carattere
        cont++;

        if (carletto == Term[n]) {
            n++; // Avanza nella verifica della stringa terminatrice
        } else if (carletto == Term[0]) {
            n = 1; // Riprendi dal primo carattere della stringa terminatrice
        } else {
            n = 0; // Reimposta il controllo
        }
    }

    printf("\\nNumero di caratteri letti: %d\\n", cont);
    return 0;
}

Esempio di Esecuzione

Input:
a b c f i n e

Output:
Numero di caratteri letti: 7


16. Visibilità di edifici allineati

Per risolvere il problema della visibilità di edifici allineati, dobbiamo determinare quali edifici di una sequenza sono visibili rispetto a una fonte di luce posta in una direzione. Gli edifici non visibili sono quelli coperti dall'ombra di edifici più alti precedenti.

Algoritmo

  1. Dati di input:
  2. Concetti principali:
  3. Passaggi:
  4. Output: L'array Illuminati con le altezze degli edifici visibili e 0 per quelli non visibili.

Codice in C

#include <stdio.h>

#define L 7

int main() {
    int Sequenza[L] = {36, 32, 43, 71, 68, 56, 74};
    int Illuminati[L];
    int ombra, i;

    // Primo edificio: sempre visibile
    ombra = Sequenza[0];
    Illuminati[0] = Sequenza[0];

    // Analizza gli edifici successivi
    for (i = 1; i < L; i++) {
        if (Sequenza[i] > ombra) {
            Illuminati[i] = Sequenza[i];
            ombra = Sequenza[i];
        } else {
            Illuminati[i] = 0;
        }
    }

    // Stampa l'array risultato
    printf("Edifici visibili:\\n");
    for (i = 0; i < L; i++) {
        printf("%d ", Illuminati[i]);
    }
    printf("\\n");

    return 0;
}

Esempio

Input:

Sequenza = {36, 32, 43, 71, 68, 56, 74}

Output:

Illuminati = {36, 0, 43, 71, 0, 0, 74}

Passaggi:



17. La più lunga sequenza crescente in un array

Codice

#include <stdio.h>
#define N 10

int main() {
    int A[N] = {1, 2, 2, 5, 6, 3, 4, 8, 9, 10};
    int max_len = 0, current_len = 1;
    int start_max = 0, start_current = 0;

    for (int i = 0; i < N - 1; i++) {
        if (A[i] < A[i + 1]) {
            current_len++;
        } else {
            if (current_len > max_len) {
                max_len = current_len;
                start_max = start_current;
            }
            current_len = 1;
            start_current = i + 1;
        }
    }

    if (current_len > max_len) {
        max_len = current_len;
        start_max = start_current;
    }

    printf("Lunghezza della più lunga sequenza crescente: %d\\n", max_len);
    printf("Elementi della sequenza: ");
    for (int i = start_max; i < start_max + max_len; i++) {
        printf("%d ", A[i]);
    }
    printf("\\n");

    return 0;
}

Spiegazione