Ci sono alcune risposte eccellenti in questa discussione, ma vorrei aggiungere una per una persona che ha imparato la programmazione del computer partendo da un linguaggio strongmente tipizzato come Java o C #, e mai programmato in un linguaggio tipizzato debole come C o C ++.
(Si noti che sto parlando della tipizzazione strong o debole, non della tipizzazione dinamica rispetto a quella statica.La definizione esatta di tipizzazione debole è una discussione affascinante da sola, ma al di fuori dello scopo di questa risposta:)
Per comprendere le stringhe con terminazione nulla, dobbiamo iniziare dal modo in cui i dati vengono archiviati in sistemi con errori tipografici. In questi sistemi l'intera memoria è solo una grande sequenza di byte e il programma ha accesso a qualsiasi di questi byte in qualsiasi momento. Spetta al programma interpretare correttamente i byte. Ad esempio, quando il programma deve leggere un numero intero a 32 bit sull'indirizzo A1, legge 4 byte a partire dall'indirizzo A1 e li interpreta come un singolo intero a 32 bit. Sa che il numero intero a 32 bit è di 4 byte di dimensione, quindi non è necessario avere alcun marcatore per dove dovrebbe finire il numero intero.
Questo non è vero per le stringhe di testo, che nella maggior parte delle lingue possono avere dimensioni arbitrarie e sono rappresentate da un singolo byte per carattere (o 2 byte per stringhe UNICODE). Quindi conoscere l'indirizzo iniziale di una stringa non significa che il programma sappia dove finisce la stringa. Tieni presente che, nelle lingue con caratteri non corretti, nulla impedisce al programma di leggere la memoria oltre la fine della stringa e di continuare a interpretare i byte che rappresentano i dati memorizzati dietro la stringa come ulteriori caratteri.
Quindi per leggere una stringa di testo sull'indirizzo A2 il programma ha bisogno di sapere quanto è lunga la stringa, in modo che sappia quanti byte dovrebbe leggere. Alcuni linguaggi si occuperanno di esso memorizzando la dimensione della stringa di testo nel primo byte (o 2 o anche 4 byte). Una stringa "pippo" potrebbe essere lunga 4 byte e apparire come segue:
3 102 111 111
dove 3 è la lunghezza della stringa e 102 e 111 sono codici ASCII per i caratteri "f" e "o". Questo è piuttosto semplice, ma limita la lunghezza massima di qualsiasi stringa, in questo caso a 255 caratteri (poiché 255 è il valore intero massimo che può essere memorizzato in un singolo byte che abbiamo usato per mantenere la lunghezza della stringa).
Un altro modo di affrontare questo problema è contrassegnare la fine della stringa, e questo è esattamente ciò che fa una stringa con terminazione null. Usa un carattere NULL rappresentato dal valore ASCII di 0 (zero). Quindi la stessa stringa "pippo" potrebbe assomigliare a questo:
102 111 111 0
Si noti che in questo caso non esiste un limite per la lunghezza di una stringa che può essere rappresentata in questo formato e il sovraccarico della rappresentazione è sempre esattamente un byte (lo zero finale). Ovviamente le stringhe di testo contenenti il carattere NULL non possono essere rappresentate come stringhe con terminazione nulla.