Perché le structs / array sono basate su zero? [duplicare]

33

Come è stato deciso che se hai un array / struct o qualcosa di simile in un linguaggio di programmazione dovrebbe essere basato su zero? Non sarebbe stato più facile se fosse basato su 1. Dopo tutto, quando ci viene insegnato a contare, iniziamo con uno.

    
posta RHPT 23.04.2011 - 03:58
fonte

9 risposte

33

Tutte le buone risposte. Una buona parte della mia "carriera" è stata spesa in Fortran, dove tutti gli array sono basati su 1. Va bene se stai scrivendo algoritmi matematici su vettori e matrici, dove gli indici vanno naturalmente a 1 .. N.

Ma non appena inizi a provare a fare algoritmi di tipo informatico, in cui hai un grande array e lavori su parti di esso, come nella ricerca binaria o nell'ordinamento heap, o se è un array di memoria e stai scrivendo allocazione di memoria e algoritmi di liberazione, o iniziando ad agire come parti di esso sono in realtà array multidimensionali in cui devi calcolare gli indici, quella roba a base 1 diventa una vera fonte di confusione.

Ad esempio, se hai un array 1-dimensionale A e vuoi trattarlo come un array NxM bidimensionale, dove I e J sono le variabili dell'indice, in C devi solo dire:

A[ I + N*J ]

ma in Fortran dici

A( (I-1) + N*(J-1) + 1 )
       or
A( I + N*(J-1) )

Se era tridimensionale, dovevi fare

A( I + N*(J-1) + N*M*(K-1) )

(Questo è se si trattasse di un ordine di colonna maggiore rispetto all'ordine di riga maggiore che è più comune in C).

Quello che ho imparato a fare in Fortran, quando facevo gli algoritmi di manipolazione delle stringhe, non era mai di pensare ad un indice I come alla posizione di un elemento in un array. Piuttosto, penserei a una "distanza" N come il numero di elementi che precedono l'elemento di interesse. In altre parole, pensa sempre in termini di "numero di elementi" piuttosto che "indice di elemento". Ciò mi ha permesso di lavorare all'interno di uno schema di indicizzazione innaturale.

    
risposta data 23.04.2011 - 04:56
fonte
30

Pensa a un indice di array esattamente come un offset dall'inizio.

    
risposta data 23.04.2011 - 04:06
fonte
23

Dijkstra ha risposto molto chiaramente in link - sebbene i programmatori Pascal non abbiano Sono d'accordo.

    
risposta data 23.04.2011 - 04:09
fonte
10

La differenza è che non è un conteggio umano, è il computer. È più facile per i computer pensare a 0 come primo elemento, poiché di solito è solo un offset dalla posizione di memoria. È logico iniziare a 0000, quindi a 0001, quindi a 0010. Se hai iniziato da 1, perderai l'indice disponibile (che si comporta come 0000 non è valido) o hai difficoltà a fare in modo che il compilatore sappia sempre che deve decrementare l'indice da uno prima che funzioni effettivamente.

Inoltre non è quello difficile da raccogliere dopo la tua prima lezione di programmazione e ti viene detto che questo è il modo in cui funzionano le cose.

    
risposta data 23.04.2011 - 04:08
fonte
10

In matematica per secoli l'indice di una serie è stato scelto per convenienza e significato. Per esempio in un polinomio, i coefficienti sono solitamente etichettati a0, a1, a2, a3, ecc. Perché lo zero rappresenta la potenza del termine corrispondente. In informatica, il pedice rappresenta lo scostamento relativo all'inizio dell'array.

    
risposta data 23.04.2011 - 04:17
fonte
6

Vedo due motivi:

Il livello basso. Se inizi con 0, l'elemento puntatore indicato dall'indice è puntatore di array + indice ( a[i] e a + i puntano allo stesso indirizzo di memoria). Questo è molto conveniente.

Su un livello un po 'più alto di astrazione - molto spesso dovrai usare la funzione modulo per gli indici. Modulo n restituisce sempre i valori da 0 a n -1. Quindi è anche più comodo quando gli indici iniziano con 0.

    
risposta data 23.04.2011 - 13:46
fonte
5

Da un punto di vista moderno (cioè linguaggi interpretati o linguaggi sviluppati di recente come C #) questo è probabilmente dovuto agli sviluppatori e quindi i progettisti di linguaggi hanno imparato a svilupparsi poiché linguaggi come C fanno uso di matrici indicizzate zero. Per quanto riguarda il motivo per cui le lingue hanno fatto uso dell'indice zero per gli array, l'indice è dovuto al modo in cui l'array è memorizzato. In C, l'uso dell'indice dell'array array[1] è uguale all'utilizzo del riferimento del puntatore, cioè array + 1 . Wikipedia ha anche un un po 'di più sull'argomento , ma questa è una ragione in poche parole.

    
risposta data 23.04.2011 - 04:10
fonte
4

Come è stato sottolineato, non tutte le lingue usano l'indicizzazione basata su 0. Ad esempio in Ada puoi definire liberamente la tua base di indicizzazione. Per il tipo String viene utilizzata l'indicizzazione basata su 1 esempio.

Il vantaggio di questo è che è possibile definire l'indicizzazione per abbinare al meglio l'utilizzo previsto. In alcuni casi potrebbe essere utile definire, ad esempio, i limiti dell'array come -1..+1 .

Ad esempio un kernel simmetrico 5x5 per la convoluzione può essere definito come

type KernelT is array (-2..+2, -2..+2) of Real;

I tipi enumerati similari possono essere usati direttamente per l'indicizzazione degli array.

    
risposta data 23.04.2011 - 08:10
fonte
3

La semplice risposta è zero è più semplice quando si tenta di calcolare l'indirizzo reale in memoria. Se un array inizia nella posizione 12345 e si desidera accedere all'elemento 678, l'aggiunta dei due fornisce la posizione che deve essere letta. Si noti quanto sopra presuppone che l'array contenga i byte ed è ovviamente più grande di 678. Se si è utilizzata l'indicizzazione basata su 1, sarà richiesta una sottrazione aggiuntiva 1. Questo diventa rapidamente un dolore e tutte le cose dicono che 1 non compra davvero nulla.

    
risposta data 23.04.2011 - 13:24
fonte

Leggi altre domande sui tag