Perché alcuni programmatori classificano C, Python, C ++ in modo diverso? - per quanto riguarda il livello


16

Sto seguendo un corso introduttivo su Python e l'istruttore afferma che Python è un linguaggio di alto livello e C e C ++ sono linguaggi di basso livello. È solo confuso. Pensavo che C, C ++, Python, Java, ecc. Fossero tutti linguaggi di alto livello.

Stavo leggendo domande su StackOverflow su C, C ++, ecc. E tutti sembrano riferirsi a quei linguaggi come di alto livello. Mi sembra che alcuni programmatori usino questi termini in modo intercambiabile.


1
Come molte altre cose, il livello alto vs basso è una semplificazione - utile per la comprensione, ma potenzialmente fuorviante se si dimentica che si tratta di una semplificazione. Quale livello è sicuramente relativo, come altri hanno già detto. Ma non è necessariamente una linea - ci sono diverse direzioni in cui puoi astrarre (ad esempio paradigmi diversi). Solo perché ti stai allontanando dall'astrazione della macchina non significa necessariamente che ti stai muovendo verso un'astrazione appropriata per la tua applicazione.
Steve314,

Anche il punto di partenza può variare. Ad esempio, IMO il calcolo lambda è un livello di astrazione molto basso - molto astratto nella macchina, ma è un'astrazione molto semplice che funge da punto di partenza per linguaggi funzionali su cui iniziare a costruire astrazioni. In ogni caso, il calcolo lambda non è probabilmente più vicino all'astrazione ideale per qualsiasi applicazione particolare rispetto al codice macchina.
Steve314,

Risposte:


31

Alto e basso livello sono termini relativi, quindi l'utilizzo è cambiato nel tempo. Negli anni '70 UNIX fece onde perché dimostrava che un sistema operativo poteva essere scritto principalmente in un linguaggio di alto livello: C. All'epoca C era considerato di alto livello in contrasto con l'assemblatore.

Oggi C è considerato un linguaggio di basso livello perché né la lingua né le librerie standard forniscono alcuna delle strutture di dati di pane e burro come vettori, dizionari, iteratori e così via. Puoi avere tutte quelle strutture in un programma C, ma finirai per scriverle tu stesso. Python, Java, ecc. Sono di alto livello rispetto a C perché molte di quelle strutture di dati standard sono integrate nel linguaggio o fanno parte delle librerie standard. Avere quelli pronti all'uso semplifica la programmazione a un livello più astratto.

C è di basso livello in un secondo senso: consente la manipolazione diretta dell'hardware del computer (almeno quanto il sistema operativo lo consentirà). Le implementazioni più comuni di Python, Java, ecc. Vengono rimosse almeno un passo dall'hardware perché eseguite in una macchina virtuale. Se vuoi manipolare l'hardware da Python dovrai scrivere un'estensione nella VM Python, di solito in C o C ++.

Il C ++ è un caso strano. Fornisce tonnellate di belle strutture di dati come parte della libreria standard, ma consente anche manipolazioni di basso livello dell'hardware.


3
Il C ++ non è un caso così strano, IMO - è semplicemente un linguaggio di livello misto. Il livello di astrazione che ottieni dipende dalle funzionalità che usi.
Steve314,

1
@ Steve314: Sì e no: normalmente l'astrazione arriva con informazioni nascoste, cioè una lingua o una libreria è come una scatola nera che fornisce un'interfaccia, e nessuno vuole sapere cosa c'è dentro la scatola nera. Il C ++ è un po 'strano in questo perché offre costrutti di livello superiore ma non impedisce al programmatore di accedere alla propria rappresentazione e romperli. Il C ++ è l'unico linguaggio che conosco che non isola diversi livelli di astrazione (ma forse ci sono altre lingue che non conosco).
Giorgio,

1
@Giorgio - C ++ ti consente di nascondere qualsiasi dettaglio di implementazione, ad esempio renderlo parte degli interni privati ​​di una classe, quindi l'unico modo ufficiale per usarlo è tramite l'interfaccia pubblica di quella classe. Ovviamente puoi infrangere le regole e confondere la tua memoria tutto ciò che vuoi, ma in pratica puoi farlo in qualsiasi lingua che supporti lo sviluppo di applicazioni nel mondo reale.
Steve314,

@Giorgio - Prendi ad esempio Haskell. "Non sicuro" in quel caso tende a significare non referenzialmente trasparente (come in unsafePerformIO). Esistono IOReftipi, ma non esiste un equivalente di reinterpret_castI so, e nessun equivalente dell'aritmetica del puntatore. Ma ciò non significa che sia al sicuro dalle persone che vanno in giro con la memoria. Per essere un linguaggio pratico, Haskell deve interfacciarsi con i sistemi operativi e le librerie del mondo reale. Ha una "interfaccia di funzione straniera". Se voglio davvero sovvertirlo, tutto ciò che devo fare è usare FFI per scrivere le funzioni di sovversione primitive.
Steve314,

@Giorgio - Certo, potrei avere difficoltà a trovare i valori che voglio corrompere in memoria, ma lo stesso può valere in C ++, a seconda di quanto li ho nascosti. Ad esempio, potrei usare una PIMPL . Se poi fornisco solo il codice oggetto e l'intestazione per la libreria che comprende ciò a cui punta, il potenziale sovversivo deve decodificare quel codice oggetto per capire cosa sovvertire e come.
Steve314,

8

Pensa a questo in termini di scala mobile, dalle lingue di livello BASSO fino alle lingue di livello ALTO. Man mano che una lingua sale di livello, da BASSO a ALTO, la lingua fornisce sempre più astrazioni dall'interfaccia specifica con il computer.

Le lingue di livello BASSO sono scritte per dirigere esplicitamente il computer - pensa al codice macchina e al codice assembly.

I linguaggi di alto livello tentano di sottrarre i dettagli chiacchieroni (in particolare l'allocazione e il rilascio della memoria). L'idea è di fornire un'interfaccia più "naturale" alla programmazione e, si spera, consentire al programmatore di concentrarsi sulla progettazione e produzione.

In questi giorni, C è considerato un linguaggio di livello BASSO. Ha ancora alcune astrazioni significative dal codice macchina e dal codice assembly, quindi tecnicamente è "più alto" di questi. Tuttavia, fornisce comunque l'indirizzamento diretto della memoria e non fornisce la garbage collection. Quindi questi sono i dettagli per i quali un programmatore deve progettare.

Confronta questo con altre lingue come Python, Ruby o Haskell e hai un'interfaccia molto più oscura. Queste lingue hanno grandi librerie di codice che astraggono gran parte del comando del computer. Ti sei mai chiesto cosa succede a una variabile in Python quando lasci l'ambito locale di una funzione o la elimini? Probabilmente no? E questo perché in una lingua di alto livello non è necessario! Si occupano dell'allocazione / rilascio della memoria per te.

Le lingue di alto livello hanno il vantaggio della funzione. Ci consentono di progettare e sviluppare liberamente (e in sicurezza!).

Le lingue di basso livello hanno il vantaggio della velocità nella maggior parte dei casi. L'interpretazione del codice di alto livello comporta un costo. Inoltre, è un po 'bello scrivere qualcosa in "computer speek".

Spero che sia di aiuto


5

Alto e basso livello non è una cosa in bianco e nero, ma una scala continua. I termini sono usati per descrivere quanto è vicino un linguaggio di programmazione all'hardware; più alto è il livello, più asporta l'hardware.

Il livello più basso, ovviamente, è il codice binario della macchina: è l'esatta rappresentazione che il sistema operativo carica e invia alla CPU. L'assemblaggio è il primo livello di astrazione costruito su di esso: al posto del codice binario, si scrivono mnemoici, codici simbolici leggibili dall'uomo che rappresentano le istruzioni binarie della macchina. Questo è ciò che le persone usavano per la programmazione dei sistemi prima di UNIX.

C è il passo successivo nella catena dell'astrazione, raggruppando schemi comuni in costrutti di controllo del flusso e astraggendo istruzioni specifiche della macchina nella sintassi agnostica della piattaforma, e quest'ultima astrazione è stata uno dei principali fattori che hanno reso UNIX rivoluzionario e di grande successo, perché significava che lo stesso codice poteva essere compilato per qualsiasi piattaforma senza grandi cambiamenti.

Il C ++ aggiunge un altro livello di astrazioni: aggiunge classi (astrazione di vtables e contesto che passa in una sintassi OOP) newe delete(raggruppamento dell'allocazione di memoria e inizializzazione variabile in un singolo costrutto), verifica del tipo di tempo di compilazione, modelli (compilazione-tempo di tipo sicuro metaprogrammazione) e un sacco di comodità di sintassi in fase di compilazione come spazi dei nomi, sovraccarico di funzioni e operatori, ecc.

Python fa un altro grande passo dall'hardware. C ++ fornisce ancora al programmatore il pieno controllo sull'allocazione della memoria e consente la manipolazione diretta della RAM; Python si occupa della gestione della memoria per te. Inoltre, invece di compilare il codice in istruzioni di tutte le macchine native, lo esegue su una macchina virtuale; questo comporta una penalità per le prestazioni (che a volte può essere pesante, ma di solito non è qualcosa di cui preoccuparsi), ma consente anche cose ordinate che sarebbero complicate in C ++ e terribilmente difficili in C, come manipolare funzioni e classi in esecuzione tempo, ottenere i nomi di oggetti arbitrari in fase di esecuzione, istanziare le classi per nome in fase di esecuzione, patch di scimmie, ecc. ecc.

Quindi quando le persone dividono le lingue in "alto livello" e "basso livello", tracciano una linea arbitraria da qualche parte, e quella linea non è sempre la stessa. Nel 1970, la linea di demarcazione era tra assemblaggio e C (il fattore decisivo era l'astrazione delle istruzioni macchina specifiche della piattaforma); nel 1987, potrebbe essere stato da qualche parte tra C e C ++; oggi potrebbe essere tra C ++ e Java (con la gestione automatica della memoria come fattore decisivo).

Per farla breve: l'alto livello è una scala mobile, e per le tre lingue menzionate è C <C ++ <Python.


Direi che alto e basso livello non è una scala, ma sono invece due scale separate. Il livello basso si riferisce a quanto un linguaggio si relaziona al comportamento della macchina, mentre il livello alto si riferisce alla sua capacità di fornire un'astrazione. C # è più di un linguaggio di alto livello rispetto a C99, ma è anche di livello inferiore rispetto al linguaggio definito dallo standard C, poiché il comportamento, ad esempio, dell'uso di un puntatore "int" per elaborare valori "corti" in un array due in un il tempo è definito in C #, ma non in C99.
supercat

3

La linea tra le lingue "di basso livello" e "di alto livello" cambia di volta in volta.
Ad esempio:
ai tempi di UNIX, C era un linguaggio di alto livello.
Oggi C non ha le strutture come i tipi di mappatura (dizionari), iteratori ecc. Che hanno oggi i linguaggi di alto livello come Python. Quindi la linea si è spostata e C è ora entrato nel gruppo di basso livello.

Lingue di basso livello:
queste lingue sono "vicine" a ciò che la macchina può eseguire (il livello più basso è: Codice di assemblaggio!).
Quando lavora con questi linguaggi, il programmatore deve pensare alle cose di livello più basso come la gestione della memoria. In questo senso sei vicino all'hardware e devi lavorare direttamente con esso.

Lingue di alto livello:
queste lingue ti allontanano dall'hardware, poiché gestiscono cose come la memoria. Quando lavori con queste lingue, la memoria è un fattore (ovviamente), ma non lavori direttamente con l'hardware. Invece la lingua lo gestisce, tenendoti lontano (forse più in alto) dall'interfaccia hardware inferiore.

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.