Quali sono le differenze fondamentali tra C e C ++? [chiuso]


41

Molti tendono a scrivere "C / C ++", come se fossero la stessa cosa. Sebbene condividano molte somiglianze, non sono chiaramente le stesse.

Ma quali sono le differenze fondamentali tra C e C ++? C ++ è una versione avanzata di C o ci sono funzionalità in C che non esistono in C ++?


2
Pensavo che C ++ fosse un super set di C
utente il

1
Il C ++ non è migliorato ... è un superset di C ..
Joe DF

2
@JoeDF Era all'inizio ma in realtà è "compatibile con C" ora che non significa affatto la stessa cosa. Non si codifica in C in C ++ e non tutto lo standard C è compatibile con lo standard C ++.
Klaim

+1 Hai ragione, ora ci sono fratelli o cugini. Se capisci cosa intendo.
Joe DF,

Risposte:


43

I seguenti punti si riferiscono al C ++:

  1. Sistema di tipo statico (definito dall'utente): consente controlli statici sui dati e sul loro utilizzo - segnala molti errori facilmente eseguibili in C.
  2. multi- "paradigma": consente di lavorare come in C, con paradigmi orientati agli oggetti, con paradigmi generici ecc.
  3. Costruttore / Distruttore: l'unico modo per dire una volta cosa fare quando si crea o si distrugge qualcosa ed essere sicuri che l'utente non dovrà trovare la funzione giusta e usarla come in C.
  4. RAII (nome errato): non è necessario gestire sempre la memoria. Mantieni gli scopi e usa i puntatori intelligenti che descrivono la durata degli oggetti. È ancora possibile utilizzare i puntatori non elaborati.
  5. Modelli: meglio della macro, un vero linguaggio per manipolare e generare tipi prima della compilazione finale. Manca solo un sistema di tipi (vedi Concetti nei futuri standard C ++).
  6. Sovraccarichi di operatore: consente di descrivere le operazioni in modo sintattico semplice e persino di definire linguaggi specifici specifici del dominio all'interno del codice C ++.
  7. Nomi con ambito: spazi dei nomi, classi / struttura, funzioni, ecc. Hanno regole semplici per assicurarsi che i nomi non si scontrino.
  8. Sistema di eccezione: un modo per propagare errori che spesso è meglio del codice di ritorno. In effetti, il codice di ritorno è utile per errori logici specifici del dominio, poiché l'applicazione deve gestirlo. Le eccezioni vengono utilizzate per errori "difficili", cose che rendono il seguente codice semplicemente errato. Permette di rilevare errori più alti nello stack di chiamate, se possibile, reagire a tale eccezione (registrando o correggendo lo stato) e con RAII, se ben utilizzato, non rende l'intero programma sbagliato - se fatto bene, di nuovo.
  9. La libreria standard: C ha il suo, ma è tutto "dinamico". La libreria standard C ++ è quasi (non flussi IO) costituita da modelli (contenitori e algoritmi) che consente di generare codice solo per ciò che si utilizza. Meglio: poiché il compilatore deve generare codice, saprà molto sul contesto e applicherà in modo accattivante molte ottimizzazioni senza dover richiedere al programmatore di offuscare il suo codice, grazie a modelli e altre cose.
  10. const-correctness: il modo migliore per assicurarti di non modificare le variabili che non dovresti. Permette di specificare l'accesso in sola lettura alle variabili. E viene controllato solo al momento della compilazione, quindi non ci sono costi di runtime.

31

Il C ++ è stato inventato per gestire complessità che C non poteva gestire. Ad esempio, un problema comune con C era che potevi "esaurire i nomi per le variabili" (da non prendere alla lettera ovviamente) perché non c'erano incapsulamenti, spazi dei nomi ecc.

Inoltre, C non ha eccezioni, quindi la gestione degli errori è molto soggetta a errori, poiché dipende dall'utente della biblioteca controllare sempre i valori di ritorno di funcs, mentre con le eccezioni, lo sviluppatore della libreria lancia semplicemente un'eccezione che garantisce che il flusso del programma verrà interrotto.

Il C ++ aiuta avendo gli oggetti init del costruttore che vengono chiamati automaticamente dal compilatore. A differenza delle strutture C che devono essere inizializzate dal programmatore (quindi un'altra area soggetta a errori).

Infine, ci sono molti altri vantaggi propagandati da OOP, come il riutilizzo degli oggetti e i concetti di programmazione generica, come modelli e generici che consentono di riutilizzare il codice sorgente, ecc.

E molte altre cose che richiederebbero troppo tempo per elencarle qui.


Mi piace che tu scriva del costruttore C ++ contro le strutture C, e che sia soggetto a errori. Sono d'accordo. Ma non mi piace il modo Java di utilizzare questo in JavaBeans, che utilizza sempre un costruttore vuoto e quindi imposta i campi membro con setter. Dal mio punto di vista, è soggetto a errori come le strutture C. Preferirei impostare i miei oggetti Java solo con il costruttore. Vedi la mia domanda su StackOverflow al riguardo.
Jonas,

Hai un punto lì, ma il focus della mia risposta qui era C vs. C ++.
Jas,

1
Oh, dai, chi ti impedisce di usare OOP con C? Puoi riutilizzare gli oggetti e fare qualsiasi cosa, anche le eccezioni. C'è anche un libro a riguardo, chiamato programmazione OOP in C.

2
@Vlad, nessuno di ciò di cui stai parlando era un'opzione 25 anni fa.
Jas,

4
È possibile eseguire OOP in quasi tutti i linguaggi di programmazione ancora in uso, ma ciò non significa che il linguaggio sia stato progettato per questo. Prendi Lua per esempio. Mentre tecnicamente consente OOP, sembra che ci siano circa cinquanta diversi modi di farlo, una causa di molto mal di testa.
Tyjkenn,

15

In generale, tutto ciò che esiste in C è supportato in C ++. Ovviamente il contrario è assolutamente falso.

In parole semplici, C ++ è orientato agli oggetti (quindi, per esempio, hai delle classi), C no.

C ++ ha un tipo booleano C89 no.

Sono lingue diverse. Condividono solo la maggior parte della sintassi.


4
C99 ha un tipo booleano (chiamato _Bool, con boolcome alias).
Jerry Coffin,

1
Questo non è strettamente vero. Ad esempio, C99 ha il long longtipo di dati che non è (ancora) parte di ISO C ++.
Chinmay Kanchi,

11
Err ... C ++ non è solo orientato agli oggetti: puoi usare paradigmi orientati agli oggetti con C ++ perché il linguaggio fornisce funzionalità per questo, ma fornisce anche funzionalità per altri paradigmi. Dovresti menzionarlo, è davvero importante, cambia tutto. Se così non fosse, saremmo tutti
passati

4
Esistono molti costrutti in C che non funzionano in C ++.

1
@klez: sì - ma è ancora sbagliato. Mentre ANSI aveva originariamente sviluppato C89 (che non aveva un tipo booleano), il nuovo sviluppo è ora eseguito da ISO e ANSI accetta lo standard ISO, quindi l'attuale standard ANSI C è identico all'attuale standard ISO C (che ha un tipo booleano).
Jerry Coffin,

8

C99 ha alcune funzionalità che non esistono (almeno nella stessa forma) in C ++ (ad esempio, membri di array flessibili, array a lunghezza variabile, ecc.)

C99 ha anche aggiunto molto alla libreria che non è presente nello standard C ++ 98/03; la maggior parte di questo è stata aggiunta a C ++ 11.

In termini di orientamento di base, C sostanzialmente supporta la programmazione procedurale strutturata. C ++ supporta questo oltre alla programmazione orientata agli oggetti, alla programmazione generica e alla metaprogrammazione (esecuzione di calcoli arbitrari in fase di compilazione). Con C ++ 11, aggiunge alcuni bit e pezzi che potrebbero almeno essere confusi con il supporto della programmazione funzionale (ad esempio, espressioni lambda). C ++ 14 ne ha aggiunti alcuni altri, ma la maggior parte di essi è davvero più comoda rispetto a qualsiasi tipo di grande cambiamento nell'orientamento.


1

Personalmente, penso che i modelli siano la caratteristica più significativa che C ++ aggiunge a C.


1
Ehm, che ne dici di classi con eredità? Questo è davvero un duro lavoro in C, mentre molti modelli possono essere eseguiti con macro preprocessore.
JBR Wilkinson,

4
Le macro del preprocessore non sono sicure per il tipo; è pura sostituzione testuale, che rende anche più difficile il debug. Per far funzionare le classi di base e l'eredità non è molto lavoro in C. + devi creare il tuo modello di metaoggetto invece di essere bloccato con qualunque cosa il designer del linguaggio abbia scelto per te. Vedi, ad esempio, questo articolo: arxiv.org/abs/1003.2547
zvrba

2
Il mio voto sarebbe distruttore per la caratteristica più significativa che C ++ ha su C (anche rispetto ai costruttori a causa delle loro incredibili capacità di pulizia).
Thomas Eding,

@zvrba #define GENERATE_INTERFACE(T) T T##_func(T x);; (tipo) overload / template sicuri in C. Concordo con Thomas sul fatto che i distruttori sono una caratteristica molto più importante che manca a C. Ma i distruttori spesso nascondono un codice importante. I namespace (scope) sono secondo me i più importanti.
YoYoYonnY,
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.