Il funzionamento del for è abbastanza semplice. Immagino che tu conosca già il meccanismo sintattico che ci sta dietro, quindi passo direttamente a farti un esempio. Il tuo codice è una cosa di questo tipo:
C:
for(int pass = 1; pass < SIZE; pass++) {
for(int i = 0; i < SIZE - 1; i++) {
printf("i = %d\n" i);
}
}
quindi la variabile i assumerà i valori da 0 a SIZE-1 (senza stampare SIZE-1) per SIZE volte: in totale, avrai SIZE*(SIZE-1) print.
Immagino che il tuo dubbio principale sia sul funzionamento di bubblesort e sul perché sia necessario ripetere i SIZE-1 confronti fatti nel for interno debbano essere ripetuti per SIZE-2 volte (for esterno). Iniziamo a capire cosa fa il for interno e visto che si chiama bubblesort facciamo un analogia con le bolle in acqua. Partendo dal fondale e salendo verso la superficie, se la bolla in basso è più grande della bolla che gli sta immediatamente sopra effettui un sorpasso (ie., uno scambio di posizione). Così facendo è ovvio che la bolla più grande di tutte arriva in cima perché nel momento in cui la trovi quella sorpassa tutte le altre, ma cosa succede a tutte le altre? Nel momento in cui la bolla più grande di tutte sorpassa la seconda bolla più grande di tutte, questa seconda bolla non ha più modo di salire perché noi (la variabile i) stiamo seguendo la bolla che l'ha sorpassata. Per risolvere questo inconveniente, dobbiamo ripetere il for interno per (al più) SIZE-2 volte: la prima volta ci assicuriamo che la bolla più grande di tutte vada in cima, la seconda volta ci assicuriamo che la seconda bolla più grande di tutte vada dietro a quella più grande di tutte, e così via finché non mi assicuro che la seconda bolla più piccola abbia la possibilità di sorpassare la bolla più piccola. La bolla più piccola non dovrà fare alcun sorpasso, quindi non è necessario ripetere per SIZE-1 volte. Per farti capire meglio, aggiungo delle printf al tuo codice:
C:
#include <stdio.h>
#include <stdlib.h>
#define SIZE 10
void print_array(int *a, size_t n) {
printf("[ ");
for (size_t i = 0; i < n; i++) printf("%d ", a[i]);
printf("]\n");
}
int main() {
int a[SIZE] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
print_array(a, SIZE);
printf("\n");
for (size_t pass = 1; pass < SIZE; pass++) {
printf("pass number %zu\n", pass);
for (size_t i = 0; i < SIZE - 1; i++) {
printf("a[%zu] > a[%zu] (%d > %d) %c ", i, i+1, a[i], a[i+1], a[i] > a[i+1] ? 'T' : 'F');
if (a[i] > a[i + 1]) {
int hold = a[i];
a[i] = a[i + 1];
a[i + 1] = hold;
}
print_array(a, SIZE);
}
printf("\n");
}
return 0;
}
Questo è l'output:
Codice:
[ 9 8 7 6 5 4 3 2 1 0 ]
pass number 1
a[0] > a[1] (9 > 8) T [ 8 9 7 6 5 4 3 2 1 0 ]
a[1] > a[2] (9 > 7) T [ 8 7 9 6 5 4 3 2 1 0 ]
a[2] > a[3] (9 > 6) T [ 8 7 6 9 5 4 3 2 1 0 ]
a[3] > a[4] (9 > 5) T [ 8 7 6 5 9 4 3 2 1 0 ]
a[4] > a[5] (9 > 4) T [ 8 7 6 5 4 9 3 2 1 0 ]
a[5] > a[6] (9 > 3) T [ 8 7 6 5 4 3 9 2 1 0 ]
a[6] > a[7] (9 > 2) T [ 8 7 6 5 4 3 2 9 1 0 ]
a[7] > a[8] (9 > 1) T [ 8 7 6 5 4 3 2 1 9 0 ]
a[8] > a[9] (9 > 0) T [ 8 7 6 5 4 3 2 1 0 9 ]
pass number 2
a[0] > a[1] (8 > 7) T [ 7 8 6 5 4 3 2 1 0 9 ]
a[1] > a[2] (8 > 6) T [ 7 6 8 5 4 3 2 1 0 9 ]
a[2] > a[3] (8 > 5) T [ 7 6 5 8 4 3 2 1 0 9 ]
a[3] > a[4] (8 > 4) T [ 7 6 5 4 8 3 2 1 0 9 ]
a[4] > a[5] (8 > 3) T [ 7 6 5 4 3 8 2 1 0 9 ]
a[5] > a[6] (8 > 2) T [ 7 6 5 4 3 2 8 1 0 9 ]
a[6] > a[7] (8 > 1) T [ 7 6 5 4 3 2 1 8 0 9 ]
a[7] > a[8] (8 > 0) T [ 7 6 5 4 3 2 1 0 8 9 ]
a[8] > a[9] (8 > 9) F [ 7 6 5 4 3 2 1 0 8 9 ]
pass number 3
a[0] > a[1] (7 > 6) T [ 6 7 5 4 3 2 1 0 8 9 ]
a[1] > a[2] (7 > 5) T [ 6 5 7 4 3 2 1 0 8 9 ]
a[2] > a[3] (7 > 4) T [ 6 5 4 7 3 2 1 0 8 9 ]
a[3] > a[4] (7 > 3) T [ 6 5 4 3 7 2 1 0 8 9 ]
a[4] > a[5] (7 > 2) T [ 6 5 4 3 2 7 1 0 8 9 ]
a[5] > a[6] (7 > 1) T [ 6 5 4 3 2 1 7 0 8 9 ]
a[6] > a[7] (7 > 0) T [ 6 5 4 3 2 1 0 7 8 9 ]
a[7] > a[8] (7 > 8) F [ 6 5 4 3 2 1 0 7 8 9 ]
a[8] > a[9] (8 > 9) F [ 6 5 4 3 2 1 0 7 8 9 ]
pass number 4
a[0] > a[1] (6 > 5) T [ 5 6 4 3 2 1 0 7 8 9 ]
a[1] > a[2] (6 > 4) T [ 5 4 6 3 2 1 0 7 8 9 ]
a[2] > a[3] (6 > 3) T [ 5 4 3 6 2 1 0 7 8 9 ]
a[3] > a[4] (6 > 2) T [ 5 4 3 2 6 1 0 7 8 9 ]
a[4] > a[5] (6 > 1) T [ 5 4 3 2 1 6 0 7 8 9 ]
a[5] > a[6] (6 > 0) T [ 5 4 3 2 1 0 6 7 8 9 ]
a[6] > a[7] (6 > 7) F [ 5 4 3 2 1 0 6 7 8 9 ]
a[7] > a[8] (7 > 8) F [ 5 4 3 2 1 0 6 7 8 9 ]
a[8] > a[9] (8 > 9) F [ 5 4 3 2 1 0 6 7 8 9 ]
pass number 5
a[0] > a[1] (5 > 4) T [ 4 5 3 2 1 0 6 7 8 9 ]
a[1] > a[2] (5 > 3) T [ 4 3 5 2 1 0 6 7 8 9 ]
a[2] > a[3] (5 > 2) T [ 4 3 2 5 1 0 6 7 8 9 ]
a[3] > a[4] (5 > 1) T [ 4 3 2 1 5 0 6 7 8 9 ]
a[4] > a[5] (5 > 0) T [ 4 3 2 1 0 5 6 7 8 9 ]
a[5] > a[6] (5 > 6) F [ 4 3 2 1 0 5 6 7 8 9 ]
a[6] > a[7] (6 > 7) F [ 4 3 2 1 0 5 6 7 8 9 ]
a[7] > a[8] (7 > 8) F [ 4 3 2 1 0 5 6 7 8 9 ]
a[8] > a[9] (8 > 9) F [ 4 3 2 1 0 5 6 7 8 9 ]
pass number 6
a[0] > a[1] (4 > 3) T [ 3 4 2 1 0 5 6 7 8 9 ]
a[1] > a[2] (4 > 2) T [ 3 2 4 1 0 5 6 7 8 9 ]
a[2] > a[3] (4 > 1) T [ 3 2 1 4 0 5 6 7 8 9 ]
a[3] > a[4] (4 > 0) T [ 3 2 1 0 4 5 6 7 8 9 ]
a[4] > a[5] (4 > 5) F [ 3 2 1 0 4 5 6 7 8 9 ]
a[5] > a[6] (5 > 6) F [ 3 2 1 0 4 5 6 7 8 9 ]
a[6] > a[7] (6 > 7) F [ 3 2 1 0 4 5 6 7 8 9 ]
a[7] > a[8] (7 > 8) F [ 3 2 1 0 4 5 6 7 8 9 ]
a[8] > a[9] (8 > 9) F [ 3 2 1 0 4 5 6 7 8 9 ]
pass number 7
a[0] > a[1] (3 > 2) T [ 2 3 1 0 4 5 6 7 8 9 ]
a[1] > a[2] (3 > 1) T [ 2 1 3 0 4 5 6 7 8 9 ]
a[2] > a[3] (3 > 0) T [ 2 1 0 3 4 5 6 7 8 9 ]
a[3] > a[4] (3 > 4) F [ 2 1 0 3 4 5 6 7 8 9 ]
a[4] > a[5] (4 > 5) F [ 2 1 0 3 4 5 6 7 8 9 ]
a[5] > a[6] (5 > 6) F [ 2 1 0 3 4 5 6 7 8 9 ]
a[6] > a[7] (6 > 7) F [ 2 1 0 3 4 5 6 7 8 9 ]
a[7] > a[8] (7 > 8) F [ 2 1 0 3 4 5 6 7 8 9 ]
a[8] > a[9] (8 > 9) F [ 2 1 0 3 4 5 6 7 8 9 ]
pass number 8
a[0] > a[1] (2 > 1) T [ 1 2 0 3 4 5 6 7 8 9 ]
a[1] > a[2] (2 > 0) T [ 1 0 2 3 4 5 6 7 8 9 ]
a[2] > a[3] (2 > 3) F [ 1 0 2 3 4 5 6 7 8 9 ]
a[3] > a[4] (3 > 4) F [ 1 0 2 3 4 5 6 7 8 9 ]
a[4] > a[5] (4 > 5) F [ 1 0 2 3 4 5 6 7 8 9 ]
a[5] > a[6] (5 > 6) F [ 1 0 2 3 4 5 6 7 8 9 ]
a[6] > a[7] (6 > 7) F [ 1 0 2 3 4 5 6 7 8 9 ]
a[7] > a[8] (7 > 8) F [ 1 0 2 3 4 5 6 7 8 9 ]
a[8] > a[9] (8 > 9) F [ 1 0 2 3 4 5 6 7 8 9 ]
pass number 9
a[0] > a[1] (1 > 0) T [ 0 1 2 3 4 5 6 7 8 9 ]
a[1] > a[2] (1 > 2) F [ 0 1 2 3 4 5 6 7 8 9 ]
a[2] > a[3] (2 > 3) F [ 0 1 2 3 4 5 6 7 8 9 ]
a[3] > a[4] (3 > 4) F [ 0 1 2 3 4 5 6 7 8 9 ]
a[4] > a[5] (4 > 5) F [ 0 1 2 3 4 5 6 7 8 9 ]
a[5] > a[6] (5 > 6) F [ 0 1 2 3 4 5 6 7 8 9 ]
a[6] > a[7] (6 > 7) F [ 0 1 2 3 4 5 6 7 8 9 ]
a[7] > a[8] (7 > 8) F [ 0 1 2 3 4 5 6 7 8 9 ]
a[8] > a[9] (8 > 9) F [ 0 1 2 3 4 5 6 7 8 9 ]
Fammi sapere se è tutto chiaro. Io ho intuiti che la tua domanda fosse più incentrata sul bubblesort, ma magari volevi una spiegazione generale sui cicli innestati.