Le giovani menti devono imparare i concetti del puntatore?


89

Perché il maestro C Dennis Ritchie ha introdotto i puntatori in C? E perché gli altri linguaggi di programmazione come VB.NET o Java o C # li hanno eliminati? Ho trovato alcuni punti su Google e voglio ascoltare anche i tuoi commenti. Perché stanno eliminando i concetti di puntatore nelle lingue moderne?

La gente dice che C è il linguaggio di base e puntatori è il concetto che rende C potente ed eccezionale e rende C ancora in competizione con linguaggi più moderni. Allora perché hanno eliminato i puntatori nelle lingue più moderne?

Pensi che la conoscenza dei puntatori sia ancora importante per i nuovi programmatori? Al giorno d'oggi le persone usano VB.NET o Java, che supporta funzionalità più avanzate di C (e non usa alcun concetto di puntatore) e molte persone come vedo ora (i miei amici) scelgono queste lingue ignorando C poiché supportano funzionalità avanzate. Dico loro di iniziare con C. Dicono che è uno spreco apprendere i concetti di puntatori quando si stanno facendo cose avanzate in VB.NET o Java che non sono possibili in C.

Cosa ne pensi?

Aggiornato :

I commenti che ho letto su Google sono:

  1. I computer precedenti erano troppo lenti e non ottimizzati.

  2. L'uso dei puntatori consente di accedere direttamente a un indirizzo e questo fa risparmiare tempo invece di crearne una copia nelle chiamate di funzione.

  3. La sicurezza è significativamente peggiore usando i puntatori, ed è per questo che Java e C # non li hanno inclusi.

Questi e altri ancora quello che ho trovato. Ho ancora bisogno di alcune risposte preziose. Sarebbe molto apprezzato.


52
Java non ha puntatori? Non è vero. Ogni riferimento ad oggetto in Java è, in sostanza, un puntatore.
quant_dev,

20
Ciò che quant_dev significa è che Java è pieno di puntatori usati in modo trasparente, mentre i programmatori non possono usarli esplicitamente.
sakisk,

9
Ecco un articolo di Joel Spolsky che è rilevante ... joelonsoftware.com/articles/fog0000000319.html
Joe Internet

11
"Perché il maestro C Dennis Ritchie ha introdotto i puntatori in c?" I puntatori non sono stati introdotti in c, si sono imbattuti direttamente nella pratica dell'assemblea, nome incluso.
dmckee,

14
@quaint_dev: Beh, Java in realtà non ha puntatori. I riferimenti non possono fare tutto ciò che i puntatori possono fare, quindi tentare di capirli in termini di riferimenti non è la strada da percorrere (e un errore che molti programmatori imparano in C o C ++). I puntatori possono fare l'aritmetica. I riferimenti non possono. (Una limitazione che puzza davvero ogni volta che sono costretto a usare Java)
Billy ONeal,

Risposte:


128

A quei tempi, gli sviluppatori stavano lavorando molto più vicino al metal. C era essenzialmente un sostituto di livello superiore per l'assemblaggio, che è quasi il più vicino possibile all'hardware, quindi era naturale che aveste bisogno di puntatori per essere efficienti nella risoluzione dei problemi di codifica. Tuttavia, i puntatori sono strumenti affilati, che possono causare gravi danni se usati con noncuranza. Inoltre, l'uso diretto dei puntatori apre la possibilità a molti problemi di sicurezza, che all'epoca non erano un problema (nel 1970 Internet consisteva in circa una dozzina di macchine in un paio di università e non si chiamava nemmeno così ...), ma è diventato sempre più importante da allora. Al giorno d'oggi, i linguaggi di livello superiore sono progettati consapevolmente per evitare i puntatori di memoria grezza.

Dire che "le cose avanzate fatte in VB.Net o Java non sono possibili in C" mostra un punto di vista molto limitato, per non dire altro :-)

Prima di tutto, tutte queste lingue (persino l'assemblaggio) sono Turing complete, quindi in teoria tutto ciò che è possibile in una lingua, è possibile in tutti. Pensa a cosa succede quando un pezzo di codice VB.Net o Java viene compilato ed eseguito: alla fine, viene tradotto in (o mappato a) codice macchina, perché questa è l'unica cosa che la macchina capisce. In linguaggi compilati come C e C ++, puoi effettivamente ottenere l'intero corpo del codice macchina equivalente al codice sorgente di livello superiore originale, come uno o più file / librerie eseguibili. Nei linguaggi basati su VM, è più difficile (e potrebbe non essere nemmeno possibile) ottenere l'intera rappresentazione equivalente del codice macchina del programma, ma alla fine è ancora lì da qualche parte, all'interno dei profondi recessi del sistema di runtime e del JIT.

Ora, naturalmente, è una questione completamente diversa se una soluzione sia fattibile in una lingua specifica. Nessuno sviluppatore sensibile inizierebbe a scrivere un'app Web in assembly :-) Ma è utile tenere presente che la maggior parte o tutti quei linguaggi di livello superiore sono costruiti su un'enorme quantità di runtime e codice della libreria di classi, un grosso pezzo di che è implementato in un linguaggio di livello inferiore, in genere in C.

Quindi per arrivare alla domanda,

Pensi che la conoscenza dei consigli ai giovani [...] sia importante?

Il concetto dietro i puntatori è il riferimento indiretto . Questo è un concetto molto importante e IMHO ogni buon programmatore dovrebbe coglierlo a un certo livello. Anche se qualcuno lavora esclusivamente con linguaggi di livello superiore, l'indirizzamento indiretto e i riferimenti sono ancora importanti. Non capire questo significa non essere in grado di utilizzare un'intera classe di strumenti molto potenti, limitando seriamente la propria capacità di risolvere i problemi a lungo termine.

Quindi la mia risposta è sì, se vuoi diventare un programmatore veramente bravo, devi capire anche i suggerimenti (oltre alla ricorsione - questo è l'altro tipico ostacolo per gli sviluppatori in erba). Potrebbe non essere necessario iniziare con questo - al giorno d'oggi non credo che C sia ottimale come prima lingua. Ma a un certo punto si dovrebbe acquisire familiarità con l'indirizzamento indiretto. Senza di essa, non potremo mai capire come funzionano effettivamente gli strumenti, le librerie e i framework che stiamo utilizzando. E un artigiano che non capisce come funzionano i suoi strumenti è molto limitato. Abbastanza giusto, si può capire anche nei linguaggi di programmazione di livello superiore. Un buon tornasole sta implementando correttamente un elenco doppiamente collegato: se riesci a farlo nella tua lingua preferita, puoi affermare di aver capito abbastanza bene l'indirizzamento indiretto.

Ma se non altro, dovremmo farlo per imparare il rispetto per i vecchi programmatori che sono riusciti a costruire cose incredibili usando gli strumenti ridicolmente semplici che avevano (rispetto a quello che abbiamo ora). Siamo tutti in piedi sulle spalle dei giganti, e ci fa bene riconoscerlo, piuttosto che fingere di essere noi stessi i giganti.


5
Questa è una buona risposta ma in realtà non risponde alla domanda: "Le giovani menti devono imparare i concetti del puntatore?"
Falcon,

11
+1 Buona risposta. Vorrei abbandonare l'argomento della completezza turing - per la programmazione pratica, è un'aringa rossa, come noterai anche tu in seguito. La sua teoria della computabilità, cioè il completamento completo significa solo che esiste un programma nello spazio (per molte lingue, infinito) di potenziali programmi che implementa lo stesso algoritmo, non se sia effettivamente fattibile o addirittura umanamente possibile. Il solo fatto di sottolineare che tutto il codice macchina alla fine dimostra il punto altrettanto bene senza piantare lo stupido "Posso fare tutto in una lingua perché sono tutti uguali, harhar!" seme.

5
+1 per "E un artigiano che non capisce come funzionano i suoi strumenti è molto limitato."
quick_now

6
Inoltre, non comprendere la meccanica dei puntatori (e dai riferimenti di estensione) di conseguenza significa che non si capiscono i concetti di copia della struttura di dati superficiale / profonda, che può causare gravi bug difficili da rintracciare. Anche nelle lingue "moderne" di alto livello.
Mavrik,

1
C è stato progettato per essere assemblatore portatile per Unix, ovvero vicino al metallo.

39

Penso che tu debba differire.

Java e altri linguaggi di livello superiore non hanno rimosso i puntatori. Quello che fecero fu di rimuovere l'aritmetica del puntatore normale.

In effetti, Java consente ancora un'aritmetica puntatore protetta e limitata : l'accesso all'array. Nella vecchia C, l'accesso all'array non è altro che dereferenziazione. È una notazione diversa, uno zucchero sintattico, se vuoi, per comunicare chiaramente ciò che stai facendo.
Tuttavia, array[index]è equivalente a *(array+index). Per questo è anche equivalente, anche index[array]se suppongo che alcuni compilatori C potrebbero darti un avvertimento, se lo fai.
Come corollario, pointer[0]equivale a *pointer. Questo semplicemente perché il "puntatore a un array" è l'indirizzo della prima voce dell'array e gli indirizzi degli elementi successivi vengono calcolati aggiungendo l'indice.

In Java, l'aritmetica del puntatore semplice (riferimento e dereferenziazione) non esiste più. Tuttavia esistono dei puntatori. Li chiamano riferimenti, ma non cambia quello che è. E l'accesso all'array è sempre esattamente la stessa cosa: guarda l'indirizzo, aggiungi l'indice e usa quella posizione di memoria. Tuttavia, in Java, verificherà se quell'indice rientra o meno nei limiti dell'array originariamente allocato. In caso contrario, genererà un'eccezione.

Ora il vantaggio dell'approccio Java è che non si ha codice, che scrive ciecamente byte arbitrari in posizioni di memoria arbitrarie. Questo migliora la sicurezza e anche la sicurezza, perché se non riesci a controllare gli overflow del buffer e simili, il runtime lo farà per te.

Lo svantaggio di questo è che è semplicemente meno potente. È possibile eseguire una programmazione sicura della memoria in C. È impossibile beneficiare della velocità e delle possibilità di una programmazione non sicura in Java.

In realtà, non c'è nulla di difficile nei puntatori o nell'aritmetica dei puntatori. Vengono normalmente spiegati in modi contorti, mentre tutto ciò che è un puntatore è un indice di un array gigante (il tuo spazio di memoria), tutto ciò che fa riferimento a un valore ti dà l'indice dove trovarlo, tutto ciò che fa il dereferenziamento è cercare il valore in un determinato indice. (Questo è solo un po 'semplificato, perché non tiene conto del fatto che i valori hanno dimensioni diverse nella memoria, a seconda del tipo. Ma questo è un dettaglio circostanziale, piuttosto che una parte del concetto reale)

IMHO, tutti nel nostro lavoro dovrebbero essere in grado di capirlo, o sono semplicemente nel campo sbagliato.


13
+1 Java e C # hanno ancora puntatori e ovviamente NullPointerExceptions
jk.

5
Si noti inoltre che i riferimenti possono indicare aree diverse nel tempo, poiché il Garbage Collector sposta le cose in giro. I puntatori sono generalmente statici.

3
+1: questo! E penso che ci siano due cose difficili da capire sui puntatori (in generale): l'indirizzamento indiretto (che accade in C, C #, Java, ...) e l'aritmetica dei puntatori (che non accade in Java allo stesso modo). Secondo me entrambi sono concetti importanti da imparare ed entrambi sono dei principali ostacoli per i principianti. Ma non devono essere confusi: l'indirizzamento indiretto può avvenire senza l' aritmetica del puntatore.
Joachim Sauer,

2
In realtà, back2dosera giusto la prima volta, poiché (array + index)già tiene conto della dimensione degli oggetti (in C).
Matthew Flaschen,

4
@CyberSkull, la risposta stava dando l'equivalente sintattico di array[index], e questo è tutto *(array+index). Se vuoi mostrare come il compilatore fa le cose internamente, puoi parlare esplicitamente di byte o dare l'assemblaggio.
Matthew Flaschen,

24

Il concetto di puntatori è importante nel corpo generale della conoscenza della programmazione informatica. Comprendere il concetto è utile per essere programmatori o programmatori di qualsiasi lingua, anche se la lingua non lo supporta direttamente.

I puntatori hanno il loro utilizzo in Strutture dati (elenchi collegati) e Progettazione di database (Chiave esterna).

Lingue come VB e C # possono passare i dati "facendo riferimento" a metodi, che possono essere considerati come un tipo di puntatore.

Comprendere dove sono allocati i dati in memoria (stack vs. heap) è ancora importante per l'efficienza degli algoritmi.

Imparare le basi giuste è importante secondo me.


Trovo che il concetto generale sia utile, ma non ho mai trovato una situazione in cui ho bisogno di un puntatore (ammesso che io uso principalmente Java e PHP). Gli unici esempi che i miei corsi di C ++ hanno mai avuto per puntatori sono stati usarli per creare strutture di dati più complesse come elenchi e dizionari che esistono in qualsiasi linguaggio di programmazione di alto livello per cominciare ..
Ben Brocka,

2
In un certo senso hai ragione, ma quando passi i dati ai metodi, è probabile che in alcuni casi passi un puntatore alla variabile. Tuttavia, il concetto di puntatore è utile (secondo me) indipendentemente dalla sua implementazione in un linguaggio software.
NoChance,

1
@SirTapTap: Questo perché se hai imparato il C ++ in qualche tipo di corso, ti insegnano il C ++. Non è il modo migliore per usare C ++. L'aritmetica del puntatore viene solitamente ignorata perché è qualcosa con cui puoi avere una conoscenza passante del C ++ e non conoscerla. Ma anche cose come l'iterazione su una raccolta generale sono fatte con puntatori in C ++ reale / idiomatico. (Poiché è il fondamento di come funziona la libreria di modelli standard)
Billy ONeal,

I puntatori @BillyONeal erano quasi la metà del corso, davvero, non ho mai trovato un uso pratico per i puntatori (intelligenti) come programmatore, dato che non ho mai avuto bisogno di quel controllo diretto sulla memoria in qualsiasi cosa abbia fatto. Naturalmente c'è sempre la possibilità che il corso sia stato insegnato male, non era esattamente il mio preferito.
Ben Brocka,

1
@SirTapTap: uso pratico: ogni raccolta e algoritmo nella STL. std::sort, std::partition, std::find, Ecc Lavorano con i puntatori, e funzionano con gli oggetti che si comportano come puntatori (iteratori). E lavorano su qualsiasi collezione generale; elenchi collegati, array dinamici, deques, alberi o qualsiasi altro tipo di raccolta definita dall'utente. Non è possibile quel tipo di astrazione senza puntatori.
Billy ONeal,

19

Sì, sì, sì, sì e sì !!!

Se non conosci le basi, non sarai MAI in grado di risolvere i problemi davvero difficili, strani, difficili e complicati che ti si presentano.

E se capisci davvero bene le basi, sei MOLTO più commerciabile nel mercato del lavoro.


Una volta ho lavorato con un tipo che stava programmando da 10 anni e non avevo idea di come funzionassero i puntatori. Io (molto più junior) ho passato ore a una lavagna per educarlo. Questo mi ha aperto gli occhi. Non aveva IDEA su così tante cose di base.

Conosci il più possibile.


Ma quali sono le basi? Assemblaggio, codice binario?
SiberianGuy,

5
Mentre il tuo punto generale di "sapere il più possibile" è valido, metterei in dubbio l'idea che "NON sarai MAI in grado di risolvere i problemi davvero difficili, strani, difficili e complicati che ti si presentano" se tu non capisco i puntatori. Questo in qualche modo implica che tutti i problemi difficili possono essere risolti usando questi puntatori "magici", il che non è il caso. I concetti tra i puntatori sono utili da sapere, ma non sono direttamente essenziali in molti campi della programmazione.
Dan Diplo,

4
@Idsa: no, ancora più semplice, molti programmatori al giorno d'oggi non sanno nemmeno come funzionano i transistor e le porte logiche nei chip "ole", e sicuramente avrebbero dovuto sapere come si muovono gli elettroni e l'effetto dell'incertezza quantistica sulla miniaturizzazione; Non ho nemmeno iniziato a ciarlatani, rossetti e bisonti! e le particelle di bisonte del singhiozzo!
Lie Ryan,

2
Nozioni di base .... cose come il modo in cui sono archiviate le cose. La differenza tra un byte, una parola, come funziona firmato e non firmato. Come funzionano i puntatori. Che personaggio è. Come le cose sono codificate in ASCII (e oggigiorno, Unicode). Come un elenco collegato può essere creato in memoria usando solo strutture semplici. Come funzionano davvero le stringhe. Da queste piccole cose crescono cose più grandi.
quick_now

5
Sapere quanto è possibile è un buon principio, ma penso che tu abbia il carrello davanti al cavallo. I bravi sviluppatori si sforzano di imparare tutto ciò che possono perché sono bravi sviluppatori. Il desiderio di conoscenza è una caratteristica di un buon sviluppatore. Non è la causa di un buon sviluppatore. Uscire e imparare il più possibile non ti renderà un buon sviluppatore. Ti renderà un'enciclopedia ambulante, niente di più. Se sei un buon sviluppatore, POI puoi applicare quelle conoscenze acquisite per risolvere i problemi. Ma se non eri già un buon sviluppatore, la conoscenza non ti otterrà molto.
corsiKa

18

Sì, la comprensione è importante.

Qualche mese fa stavo programmando in C # e volevo fare una copia di un elenco. Ovviamente quello che ho fatto è stato NewList = OldList;e poi ho iniziato a modificare NewList. Quando ho provato a stampare entrambi gli elenchi, erano entrambi uguali, poiché NewListera solo un puntatore OldListe non una copia, quindi in realtà stavo cambiando da OldListsempre. Non mi ci è voluto troppo tempo per capirlo, ma alcuni dei miei compagni di classe non sono stati così veloci e hanno dovuto spiegare perché questo sta accadendo.

Esempio:

List<int> a = new List<int>();
a.Add(2);
a.Add(9);
a.Add(8);
a.Add(1);
List<int> b = new List<int>();
b = a; //Does not make a copy, b is just a synonym!
b.Sort();
for (int i = 0; i < a.Count; i++)
{
    Console.WriteLine("a: " + a[i] + " b: " + b[i]);
}

E, naturalmente, il risultato è così:

a: 1 b: 1
a: 2 b: 2
a: 8 b: 8
a: 9 b: 9

Sapere come usarli non è così importante, tuttavia capirli è fondamentale!


2
Invece perché usarli e quando usarli è molto importante :)
niko,

5
" NewListera solo un puntatore a OldList" - per essere precisi, entrambi NewListed OldListerano solo puntatori, riferiti allo stesso Listoggetto.
Péter Török,

È anche importante capire che il nuovo elenco creato per bnon ha più riferimenti ad esso e ora è immondizia.
TMN,

14

Puntare il concetto! = Puntare l'aritmetica! = Puntare la sintassi

I primi contano sempre, se hai bisogno (e lo fai) della comprensione della copia profonda / superficiale, passa per riferimento / passa per valore, ecc. Gli altri due contano solo se il tuo linguaggio del giorno ti consente di usarli.


1
Al giorno d'oggi è necessario conoscere solo il concetto base di riferimenti, non la sintassi / matematica del puntatore. Ho imparato i puntatori (con aritmetica e sintassi) in C nel corso della giornata. Le lingue in cui sto programmando ora non trattano i puntatori in stile C che ti consentono di fare cose non sicure. Si può capire perché in pitone a=[1,2]; b=a; a.append(3)che entrambi ae bstanno per entrambi riferimento allo stesso oggetto [1,2,3]senza conoscere roba come in C la iesimo elemento di un array può fare riferimento arr[i]o i[arr]come entrambi sono *(arr+i). Preferisco quando la lingua non i[arr]viene utilizzata.
dr jimbob,

" Gli altri due contano solo se la tua lingua del giorno ti consente di usarli. " - Quella frase porta in giro il suo autodistruttore. È improbabile che la lingua del giorno sia la stessa lingua usata domani. E domani potresti trovarti di fronte a un linguaggio abilitato al puntatore. Linea di fondo? Meglio se ne accorge ora, una volta per sempre. Non è così difficile, ma ne vale la pena.
JensG,

14

Perché il maestro C Dennis Ritchie ha introdotto i puntatori in C?

Perché i puntatori sono un meccanismo molto potente che può essere utilizzato in molti modi.

E perché gli altri linguaggi di programmazione come VB.NET o Java o C # li hanno eliminati?

Perché i puntatori sono un meccanismo molto pericoloso che può essere utilizzato in modo improprio in molti modi.

Penso che i programmatori dovrebbero conoscere i puntatori, ma dal punto di vista educativo, non è saggio presentarli in anticipo. Il motivo è che sono usati per così tanti scopi diversi, è difficile dire come principiante perché stai usando un puntatore in una particolare circostanza.

Ecco un elenco incompleto per cui vengono utilizzati i puntatori:

  • allocazione dinamica ( new T)
  • strutture di dati ricorsive ( struct T { T* next; /* ... */ };)
  • iteratori su array ( for (T* p = &a[0]; p != &a[0] + n; ++p) { ... })
  • accesso condiviso agli oggetti ( T* new_pointer = existing_pointer;)
  • sottotipo polimorfismo ( T* pointer_to_base = pointer_to_derived;)
  • chiamata legacy per riferimento ( mutate(&object);)
  • tipi opzionali ( if (p) { /* ... */ })

Si noti che l'utilizzo di un singolo meccanismo per tutti questi concetti dimostra sia la potenza che l'eleganza per il programmatore esperto e il grande potenziale di confusione per qualcuno che non conosce la programmazione.


" Perché il maestro C Dennis Ritchie ha introdotto i puntatori in C ? Perché i puntatori sono un meccanismo molto potente che può essere utilizzato in molti modi." - Non lo so per certo, ma immagino che abbia qualcosa a che fare con le istruzioni della macchina da avvolgere nel linguaggio C, e i predecessori dei programmatori C. Assembler sono abituati a pensare in puntatori, quindi sarebbe stato una sorpresa se non avesse usato questi noti potenti meccanismi. Qualsiasi altra cosa sarebbe stata troppo lontana per il 1978 o addirittura per gli anni '60.
JensG,

12

Perché? Puoi scrivere un enorme sistema con designer di moduli e generatore di codice. Non è sufficiente? (ironia)

E ora seriamente, i puntatori non sono parte cruciale della programmazione in molte aree, ma consentono alle persone di capire come funzionano gli interni. E se non avremo nessuno che capisca come funzionano gli interni, ci sarà una situazione in cui SQL2020, Windows 15 e Linux 20.04 verranno scritti in una macchina virtuale raccolta rifiuti che esegue oltre 30 strati di astrazione, con codice generato tramite IDE, in JavaScript .

Questo non è sicuramente quello che voglio vedere.

Quindi sì, devono assolutamente!


2
Buon umore! +1 e totalmente d'accordo.
Heltonbiker,

7

Né Java né C # hanno eliminato i puntatori, hanno riferimenti quasi identici. Ciò che è stato eliminato è l'aritmetica del puntatore, che può essere omessa in un corso introduttivo.
Nessuna applicazione non banale potrebbe essere fatta senza il concetto di puntatori o riferimenti, quindi vale la pena insegnare (Nessuna allocazione dinamica della memoria potrebbe essere fatta senza di loro).

Considera quanto segue in C ++ e Java, e immagino che non sia molto diverso in C #:
aClass *x = new aClass();
aClass x = new aClass();
non c'è davvero troppa differenza tra puntatori e riferimenti, giusto?
L'aritmetica del puntatore dovrebbe essere evitata a meno che non sia necessario e durante la programmazione con modelli di alto livello, quindi non ci sono molti problemi.


6

Il programmatore professionista dovrebbe padroneggiare i puntatori.

Le persone che vogliono conoscere la programmazione dovrebbero conoscere la sua esistenza e le sue implicazioni, ma non necessariamente usarle.

Le persone che vogliono risolvere i problemi personali tramite la programmazione (come me, che usano molti script Python) potrebbero ignorarli.

Bene, questa è la mia opinione ...; o)


3

I puntatori a indirizzo variabile sono un caso specifico del concetto più generalizzato di riferimento indiretto. L'indirizzamento viene utilizzato nella maggior parte (tutte?) Le lingue moderne in molti costrutti come delegati e callback. Comprendere il concetto di indiretta consente di sapere quando e come utilizzare al meglio questi strumenti.


3

Assolutamente ! Tutti coloro che programmano devono comprendere i puntatori e l'indirizzamento indiretto.

I puntatori indicano come viene eseguita una grande quantità di accesso ai dati in tutte le lingue. I puntatori sono una funzionalità hardware di tutti i microprocessori. Linguaggi di alto livello come Java, VB & C # essenzialmente bloccano l'accesso diretto ai puntatori dagli utenti della lingua con riferimenti. I riferimenti si riferiscono ad oggetti tramite lo schema di gestione della memoria del linguaggio (potrebbe essere un puntatore con metadati o solo un numero per una tabella di memoria, ad esempio).

Comprendere come funzionano i puntatori è fondamentale per capire come funzionano effettivamente i computer. I puntatori sono anche più flessibili e potenti dei riferimenti.

Ad esempio, il motivo per cui le matrici iniziano all'indice zero è perché le matrici sono in realtà una scorciatoia per l'aritmetica del puntatore. Senza sapere come funzionano i puntatori, molti programmatori principianti non ottengono abbastanza array.

int a, foo[10];
foo[2] = a;

La riga 2 nell'aritmetica del puntatore sarebbe:

*(foo + sizeof(int) * 2) = a;

Senza capire i puntatori, non si può capire la gestione della memoria, lo stack, l'heap o persino gli array! Inoltre, è necessario comprendere i puntatori e la dereferenziazione per capire come vengono passate le funzioni e gli oggetti.

TL: DR : La comprensione dei puntatori è fondamentale per comprendere che i computer funzionano davvero .


2

Penso che si riduca al fatto che la necessità di gestire i puntatori è diminuita mentre i programmatori si occupavano meno dell'hardware diretto su cui erano in esecuzione. Ad esempio, allocare una struttura di dati di elenchi collegati in modo da adattarsi perfettamente alla sequenza di moduli di memoria da 640 byte dell'hardware specializzato.

La gestione manuale dei puntatori può essere soggetta a errori (con conseguenti perdite di memoria e codice sfruttabile) ed è molto dispendiosa in termini di tempo. Quindi Java e C # ecc. Ora gestiscono tutti la tua memoria e i tuoi puntatori tramite le loro macchine virtuali (VM). Ciò è probabilmente meno efficiente rispetto all'utilizzo di C / C ++ non elaborati, sebbene le VM migliorino costantemente.

C (e C ++) sono linguaggi ancora ampiamente utilizzati, in particolare negli spazi di calcolo ad alte prestazioni, giochi e hardware incorporato. Personalmente sono grato di aver appreso dei puntatori poiché la transizione ai riferimenti di Java (un concetto simile ai puntatori) è stata molto semplice e non mi sono perso quando ho visto la mia prima NullPointerException (che dovrebbe davvero essere chiamata NullReferenceException, ma sto divagando) .

Consiglierei di imparare il concetto di puntatori poiché supportano ancora molte strutture di dati, ecc. Quindi, scegli una lingua in cui ti piace lavorare, sapendo che se emerge qualcosa come un NPE, sai cosa sta realmente succedendo .


0

Questa è la verità oggettiva:

Alcune lingue supportano l'accesso diretto alla memoria (puntatori), altre no. Ci sono buone ragioni per ogni caso.

  1. Come qualcuno ha detto qui, ai tempi di C, la gestione automatica della memoria non era così elaborata come lo è oggi. E le persone erano state abituate, comunque. I bravi programmatori di allora avevano una comprensione molto più profonda dei programmi per computer rispetto alla nostra generazione (ho 21 anni). Hanno usato schede perforate e giorni di attesa per un po 'di tempo di compilazione sul mainframe. Probabilmente sapevano perché esistesse ogni bit del loro codice.

  2. L'ovvio vantaggio di linguaggi come C è che ti permettono di avere un controllo più preciso sul tuo programma. Quando ne hai davvero bisogno , in questi giorni? Solo quando crei applicazioni infrastrutturali, come programmi relativi al sistema operativo e ambienti di runtime. Se si desidera sviluppare solo software valido, veloce, robusto e affidabile, la gestione automatica della memoria è spesso la scelta migliore.

  3. Il fatto è che l'accesso diretto alla memoria è stato principalmente abusato nel corso della storia dello sviluppo del software. Le persone avevano creato programmi che perdevano memoria ed erano effettivamente più lenti a causa dell'allocazione di memoria ridondante (in C è facile e comune estendere lo spazio di memoria virtuale del processo per ogni singola allocazione).

  4. In questi giorni, le macchine virtuali / runtime fanno un lavoro molto migliore rispetto al 99% dei programmatori nell'allocazione e nel rilascio della memoria. Inoltre, ti consentono una maggiore flessibilità nel flusso che desideri che il tuo programma abbia, perché non sei (principalmente) occupato a liberare memoria allocata al momento e nel luogo giusti.

  5. Per quanto riguarda la conoscenza. Penso sia ammirevole che i programmatori sappiano come vengono implementati gli ambienti in cui programmano. Non necessariamente nei minimi dettagli, ma nel quadro generale.

Penso che sia interessante sapere come funzionano i puntatori (almeno). Come sapere come si implementa il polimorfismo. Da dove prende il suo processo la memoria e come. Queste sono cose che mi hanno sempre interessato, personalmente. Posso onestamente dire che mi hanno reso un programmatore migliore, ma non posso dire che siano una necessità educativa per chiunque voglia diventare un buon programmatore. In entrambi i casi, saperne di più ti renderà spesso migliore nel tuo lavoro.

  1. Per come la vedo io, se tutto ciò che ti viene chiesto è creare un'applicazione in Java o C # o qualcosa del genere, devi concentrarti su tecniche di progettazione e implementazione adeguate. Codice verificabile, codice pulito, codice flessibile. In questo ordine.

Perché anche se non conosci tutti i piccoli dettagli, qualcuno che lo farà sarà in grado di cambiare ciò che avrai creato in qualcosa che semplicemente funziona meglio. E spesso non è un lavoro difficile, una volta che hai in atto un design adeguato, pulito e testabile (e di solito è la maggior parte del lavoro).

Se fossi un intervistatore che cerca di assumere qualcuno per un'applicazione di alto livello linguistico, queste sarebbero le cose a cui sarei più interessato.

La conoscenza di basso livello è un vantaggio. È utile per il debug e occasionalmente per creare soluzioni leggermente migliori. Ti rende una persona interessante, professionalmente. Ti garantisce un certo rispetto sul posto di lavoro.

Ma nel mondo di oggi, non è un requisito sacro.


-1

Per la maggior parte degli scopi pratici nelle lingue OO di alto livello è sufficiente comprendere i riferimenti, non è necessario capire come queste lingue implementano i riferimenti in termini di puntatori.

Ci sono molti approcci multi-paradigma molto più funzionali e moderni che apprezzerei molto più di quanto sia in grado di fare aritmetica di puntatori fantasiosi per dire, scrivere la 1000esima funzione di copia di stringhe ottimizzata probabilmente con prestazioni peggiori di String.copy della tua libreria standard.

Ti consiglierei di apprendere concetti molto più diversi, di livello superiore, prima di iniziare a studiare lingue di diversi design per ampliare il tuo orizzonte prima di tentare di specializzarti in cose vicine all'hardware.

Vedo spesso tentativi totalmente falliti di micro-ottimizzare il servlet web o il codice simile per un guadagno del 5%, quando la memorizzazione nella cache (memoization), l'ottimizzazione di SQL o solo la regolazione della configurazione del server web possono produrre il 100% o più con poco sforzo. Giocare con i puntatori è l'ottimizzazione prematura nella maggior parte dei casi.


-1

Sicuramente, dobbiamo avere un concetto completo di puntatore, se vuoi davvero essere un buon programmatore. Il motivo del concetto di puntatore era un accesso diretto al tuo valore che diventa più efficiente ed efficace con i vincoli temporali ...

Inoltre, ora un giorno, considerando le applicazioni mobili, che hanno una memoria molto limitata, dobbiamo usarlo con molta attenzione in modo che il suo funzionamento sia molto rapido con la risposta dell'utente ... Quindi a questo scopo abbiamo bisogno di un riferimento diretto al valore ...

Considera i dispositivi Apple o il linguaggio Objective C, che funziona totalmente solo con il concetto di puntatore. Tutta la variabile dichiarata nell'Obiettivo C ha Puntatore. Devi consultare la wiki di Objective C.


Al giorno d'oggi le app mobili hanno più memoria disponibile rispetto ad alcuni data center C concepiti. Molte app mobili sono scritte in Java, o html + javascript, tutte senza puntatore (le hanno REFERENZE). Solo una piccola parte di programmatori molto specializzati riesce a vedere i livelli del sistema operativo sottostante.
Jürgen Strobel,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.