it-swarm.it

Quando usare C su C ++ e C ++ su C?

Sono stato introdotto all'Informatica da poco più di un anno e dalla mia esperienza sembra che C e C++ siano entrambi considerati linguaggi "ultraveloci", mentre altri come Python e tali linguaggi di scripting sono di solito considerati un po 'più lenti.

Ma ho anche visto molti casi in cui un progetto software o anche uno piccolo avrebbero interlacciato file in cui un certo numero n di quei file sarebbe stato scritto in C e un certo numero m di quei file sarebbe stato scritto in C++.

(Ho anche notato che i file C++ hanno quasi sempre intestazioni corrispondenti, mentre i file C non sono così tanto). Ma il mio principale punto di indagine è quello di ottenere un senso generale dell'intuizione su quando è appropriato usare C su C++ e quando è meglio usare C++ su C. A parte i fatti che (1) C++ è orientato agli oggetti, mentre C non lo è, e (2) le sintassi sono molto simili, e C++ è stato creato intenzionalmente per assomigliare a C in molti modi, non sono sicuro di quali siano le loro differenze. Mi sembra che siano (quasi) perfettamente intercambiabili in molti settori.

Quindi sarebbe apprezzato se qualcuno potesse chiarire la situazione! Grazie

164
Dark Templar

Scegli C quando

  • hai bisogno di un assemblatore portatile (che in realtà è C) per qualsiasi motivo,
  • la tua piattaforma non fornisce C++ (un compilatore C è molto più facile da implementare),
  • devi interagire con altre lingue che possono interagire solo con C (di solito il minimo comune denominatore su qualsiasi piattaforma) e il tuo codice è costituito da poco più dell'interfaccia, non vale la pena posare un'interfaccia C su codice C++,
  • si hackera in un progetto Open Source (molti dei quali, per vari motivi , attenersi a C),
  • non conosci C++.

In tutti gli altri casi dovresti scegliere C++.

184
sbi

Ci sono alcuni motivi per preferire C. Il principale è che tende a essere più difficile produrre eseguibili veramente minuscoli con C++. Per sistemi molto piccoli, raramente stai scrivendo molto codice e lo spazio extra ROM che sarebbe necessario per C++ piuttosto che C può essere significativo.

Dovrei anche aggiungere, tuttavia, che per davvero piccoli sistemi, C ha problemi esattamente per lo stesso motivo e il linguaggio Assembly è quasi l'unica scelta ragionevole. La gamma di dimensioni del sistema in cui C ha davvero senso è piuttosto piccola e si restringe costantemente (anche se lo ammetto, abbastanza lentamente).

Un altro tempo/motivo per usare C è quello di fornire un insieme di funzioni a cui puoi legare essenzialmente da qualsiasi altra lingua. Puoi puoi scrivere queste funzioni in C++ definendole come extern "C" funzioni, ma limitando tali funzioni a presentare al mondo una "faccia" essenzialmente a C-life - classi, funzioni sovraccariche, modelli, e non è necessario applicare le funzioni membro, ecc. Ciò tuttavia non limita necessariamente lo sviluppo a C: è perfettamente ragionevole utilizzare qualsiasi tipo di funzionalità C++ internamente , purché l'interfaccia esterna sembra C.

Allo stesso tempo, devo dire che le risposte di @ Toll (per un ovvio esempio) hanno cose quasi all'indietro sotto molti aspetti. Il C++ ragionevolmente scritto sarà generalmente almeno veloce quanto C, e spesso almeno un po 'più veloce. La leggibilità è generalmente molto migliore, se non altro perché non sei sepolto in una valanga di tutto il codice anche per gli algoritmi e le strutture di dati più banali, tutta la gestione degli errori, ecc.

I modelli non "risolvono un problema con il sistema di tipi di linguaggio", ma semplicemente aggiungono una serie di funzionalità fondamentali quasi completamente assenti da C e/o C++ senza modelli. Uno degli intenti originali era quello di fornire contenitori sicuri per i tipi, ma in realtà vanno ben oltre - essenzialmente nessuno dei quali C fornisce affatto.

Anche gli strumenti automatizzati sono per lo più un'aringa rossa - mentre è vero che scrivere un parser C è meno lavoro che scrivere un parser C++, la realtà è che alla fine non fa praticamente alcuna differenza. Pochissime persone sono disposte o in grado di scrivere un parser utilizzabile per uno dei due. Come tale, il punto di partenza ragionevole è Clang in entrambi i casi.

In effetti, C e C++ sono abbastanza frequentemente usati insieme sugli stessi progetti, gestiti dalle stesse persone. Ciò consente qualcosa che altrimenti sarebbe piuttosto raro: un studio che confronta direttamente, oggettivamente la manutenibilità del codice scritto nelle due lingue da persone che sono ugualmente competenti nel complesso (cioè, esattamente le stesse persone). Almeno nello studio collegato, una conclusione è stata chiara e inequivocabile: "Abbiamo scoperto che l'uso di C++ anziché C comporta un miglioramento della qualità del software e uno sforzo di manutenzione ridotto ..."

88
Jerry Coffin

Le differenze tra C e C++ sono già state enumerate in dettaglio qui . Mentre a volte le persone possono avere motivi legittimi per scegliere l'uno o l'altro (C++ per OOP o C quando sentono che le funzionalità extra di C++ introducono costi indesiderati, ad esempio), nella mia esperienza di solito arriva solo in base alle preferenze. Che cosa sanno meglio le persone che lavorano su questo file e che le piacciono di più? Credo che questo sia il motivo per la maggior parte del tempo, poiché è vero che questi linguaggi affrontano entrambi le applicazioni critiche per le prestazioni.

(Nota a margine: Dai un'occhiata a Linant Torvads 'rant sul perché preferisce C a C++. Non sono necessariamente d'accordo con i suoi punti, ma ti dà un'idea del perché le persone potrebbero scegliere C su C++. Piuttosto, le persone che sono d'accordo con lui potrebbero scegliere C per questi motivi.)

24
Casey Patton

Il problema principale mancante nelle risposte esistenti (al momento del post) è la scelta.

È semplice. Se, per qualche motivo assolutamente irrazionale, ritieni che le eccezioni non valgano il sovraccarico, allora non devi usarle. Puoi ancora avere modelli, RAII e la libreria Standard e non scrivere mai un singolo "lancio". Lo stesso vale per i modelli. Se, per qualche motivo, ritieni che causino un gonfiore eseguibile irrevocabile (e in realtà importante, che è solo su incorporato), allora sorpresa: puoi usare anche void * e sizeof (T) tutto il giorno. Nulla ti costringe a utilizzare nessuna delle funzionalità di C++ su C.

Ecco perché C++ è un linguaggio intrinsecamente superiore: puoi scegliere le funzionalità che desideri e tornare alla programmazione in stile C quando non ti piace una determinata funzionalità. Pertanto, dato che C++ è tutto ciò che è C e altro, è ovvio che C++ è un linguaggio superiore. Suggerire altrimenti è come provare a suggerire che 4 è maggiore di 5.

13
DeadMG

Cose sul C++ che rendono nervosi i programmatori C

C'è molta magia che sta accadendo sotto il cofano; costruttori, distruttori, metodi virtuali, modelli, ecc., possono rendere il codice C++ molto più semplice e veloce da scrivere rispetto al codice C equivalente, ma più difficile da comprendere e ragionare (a seconda di quanto conosci C++ e le sue convenzioni associate). Qualcosa di semplice come Foo newFoo; può invocare un lotto di codice, a seconda di come è stato il costruttore per la classe Foo (e qualsiasi classe da cui dipende) definito. Questo è anche il motivo per cui la convenzione è di scrivere ++it invece di it++ durante l'iterazione attraverso un contenitore, dal postfisso ++ comporta spesso un'operazione di copia costosa.

A seconda di ciò che stai facendo, può esserci un sovraccarico non banale, specialmente per compiti semplici. Prendi i seguenti due programmi, il primo in C, il secondo in C++:

/* C version */
#include <stdio.h>
int main(void)
{
  char greeting[] = "Hello, world";
  printf("%s\n", greeting);
  return 0;
}
/* end C version */

/* C++ version */
#include <iostream>
#include <string>
int main(void)
{
  std::string greeting("Hello, world");
  std::cout << greeting << std::endl;
  return 0;
}
/* end C++ version */

Comportamento identico, non molta differenza in termini di sorgente, ma sulla scatola di SLES 10 su cui lavoro con gcc 4.1.2, il primo genera un eseguibile di ~ 9kb di dimensioni, mentre il secondo prende 12,5kb (nessuna ottimizzazione ), quasi il 28% più grande. Il tipo C++ string è molto più facile da lavorare con IMO rispetto alla libreria di stringhe C, e i flussi C++ sono molto più flessibili e personalizzabili rispetto ai flussi C, ma per codice davvero morto come questo, essi può non valere le spese generali.

C++ è un linguaggio enorme rispetto a C, con una semantica estremamente complessa. Ci vuole molto più tempo per acquisire padronanza del C++ rispetto al C, il che significa che molte persone che affermano di conoscere il C++ non lo sanno bene come pensano di fare.

Cose su C che rendono nervosi i programmatori C++

C non è un linguaggio di programmazione sicuro per nessun tratto dell'immaginazione; nessun limite di controllo sugli array porta a un sacco di comportamento sfruttabile (sia attraverso la funzione gets ormai morta, sia attraverso scanf con la %s e %[ specificatori di conversione). C++ almeno ti dà contenitori che generano eccezioni se provi ad accedere al di fuori del loro intervallo attualmente definito; tutto ciò che ti dà C è (se sei fortunato) una violazione della segmentazione.

La gestione della memoria in C è molto laboriosa e soggetta a errori, rispetto agli strumenti forniti da C++. Se stai costruendo il tuo contenitore, sei responsabile della corrispondenza di tutte le chiamate malloc e free, assicurandoti che le allocazioni abbiano esito positivo, eseguendo il backup di eventuali allocazioni parziali in caso di errore , ecc. In C++, è sufficiente aggiungere elementi o rimuovere elementi dal contenitore. Se c'è un problema, verrà generata un'eccezione.

Allo stesso modo, la gestione degli errori in C è un dolore nel culo rispetto agli strumenti forniti da C++ (vale a dire, eccezioni). La cosa veramente divertente è quando hai allocato un sacco di memoria e poi hai colpito un muro durante l'elaborazione; come è necessario tornare indietro, è necessario rilasciare quella memoria nel giusto ordine. Con i principi C++ e RAII, questo è (relativamente) facile da fare.

Quindi quando devo usarne uno sopra l'altro?

Se quello che stai scrivendo è una palude semplice, leggilo/confondilo/sbarazzati della sua applicazione, il cui comportamento può essere descritto in modo chiaro in termini di input e output, e le prestazioni sono importanti, quindi preferisci C rispetto a C++. Altrimenti, preferisci C++

9
John Bode

Bjarne Stroustrup mantiene un elenco di applicazioni e società che usano C++; puoi discutere di procedurale vs OOP programmare tutto quello che vuoi, ma non puoi discutere con i risultati del settore negli ultimi 20 anni.

Il C++ è comunemente usato per progetti complessi, multi-uomo, su larga scala in cui persone separate devono lavorare su componenti modularizzati. Naturalmente è possibile creare e mantenere il codice modularizzato in C, ma la natura intrinseca OOP del C++ porta a modularizzazione, testabilità e riutilizzo del codice superiori.

La libreria standard C++ (STL), in sé con solo vettori e mappe, è una ragione sufficiente per usare C++.

C è comunemente usato per i sistemi embedded.

Personalmente userei C solo se c'è qualche libreria che ha solo un'API C.

Direi che il motivo principale per cui sceglierei C su C++, è solo quando dovrei ricorrere a "NASCONDI DEVE ESSERE stabile al 1000%".

Il C++ è ~ 99% C quando osserviamo le prestazioni ed è molto più produttivo. Quindi, anche se in C puoi scrivere un codice che sarà più veloce di C++ (puoi usare un sottoinsieme di C++ senza eccezioni, virtuale, streaming, astrazioni, ecc., Ma fondamentalmente C), il tempo per ottimizzare ogni maledetta cosa mentre STL è testato e lo fa già, ti costerebbe di più del piccolo guadagno in termini di prestazioni che potresti ottenere o sacrificare perché gli algoritmi STL sono stati scritti da gruppi di esperti e probabilmente non sei un esperto in tutto.

D'altro canto il C++ ha un sacco di astrazioni. Quando in determinate circostanze perdono, questo ti mette nei guai. E ci sono poche persone che conoscono il 100% dei gotcha C++, mentre, immagino, ce ne sono molti di più che conoscono tutti i gotcha C, quindi scrivere una soluzione in cui ogni passaggio è pienamente compreso da tutti i membri di una squadra è molto più facile in C.

Esempio: sai quando shared_ptr<smthn> supererà il conteggio dei riferimenti, genererà un'eccezione? Cose come queste non vanno bene quando Shuttle deve rientrare nell'atmosfera, almeno credo.

Inoltre, la gestione delle eccezioni è molto, molto difficile rispetto ai codici di errore. È difficile capire se la classe è al 100% sicura e facile da individuare. Molte persone di alto livello hanno espresso questa opinione.

9
Coder

C è un assembly portatile con una migliore sintassi, che offre al programmatore il pieno controllo di tutto.

Il C++, d'altra parte, fa molta magia funky (funzioni virtuali, sovraccarico, conversione automatica, ecc. Ecc.) Che potrebbe non essere desiderabile quando vuoi assicurarti di:

  • non usare più memoria di quella che vuoi
  • non accedere alle pagine di memoria volenti o nolenti (la vtable può essere ovunque)
  • non invocare accidentalmente troppo codice

E vuoi qualcosa di veramente semplice con cui lavorare, dato che ti concentri sulle prestazioni.

Non ha sorprese, ed è molto prezioso.

Se vuoi (e lo consiglio), leggi Linee guida per la codifica JSF su cosa devi pensare quando scrivi C++ per il controllo dell'avionica militare. Ci sono molte trappole di cui devi essere consapevole, e potrebbero prenderti alla sprovvista. Bjarne faceva parte di quel documento, quindi sa di cosa si tratta.

Inoltre, C si compila come un troll scottato colpito da un fulmine. Il C++, OTOH, è stato probabilmente sponsorizzato dalle stesse persone che hanno investito in società SSD. :)

(Personalmente, preferirei C++, ma non mi piace neanche ...... ;-P)

6
Macke

(dato che hai la stessa familiarità con entrambe le lingue)

Vai con C++ a meno che non ci sia un compilatore C++ per la tua piattaforma. Puoi scrivere il codice C++ senza la parte della lingua che non ti piace (nessuna classe, eccezione, eredità virtuale, qualunque limitazione personale desideri applicare) e poi in futuro, se decidi di volere un po 'di dopo tutto quelle funzionalità, allora puoi usarle facilmente. Nulla in C++ ti impedisce di scrivere codice in stile C.

(dati equivalenti set di strumenti e conoscenza degli sviluppatori) Non c'è motivo di scegliere C su C++ purché la piattaforma disponga di un compilatore C++. Puoi semplicemente limitarti al sottoinsieme della lingua che desideri oggi, lasciando la porta aperta per l'estensione in seguito.

2
anon

Entrambe le lingue sono eccellenti. Penso che un certo numero di poster abbia dettagliato i punti di forza e i vari usi per ciascuno. Aggiungerò semplicemente questo:

Vedo il linguaggio C perfetto in 4 aree: 1) Penso che sia il miglior linguaggio da usare quando apprendi per la prima volta qualsiasi tipo di programmazione [combinato con un po 'di assembly e conoscenza del codice macchina], 2) è ottimo per scrivere driver, 3) incorporato software e 4) software di sistema al livello più basso.

Il C++ è un linguaggio orientato agli oggetti, ma può anche essere procedurale (molto alla maniera di C). Se stai lavorando a progetti su larga scala, software basati su GUI, software di gioco e altri tipi di software graficamente intensivo, allora trovo C++, Java o persino Objective-C la scelta migliore. Tuttavia, ci sono molti programmi da riga di comando o software di sistema in cui potresti trovare C++ buono o migliore di C.

1
Jonathan

Probabilmente C è preferibile a C++ quando viene generato il codice C (ad es. Nelle implementazioni di linguaggi di livello superiore). Ad esempio, ci sono diversi compilatori simili a LISP che emettono codice C (ad es. Chicken , Scheme48 ...), ma non ne conosco nessuno che emetta codice C++ autentico (my - MELT lo strumento emette codice C++, ma non lo chiamerò codice C++ originale, utilizza pochissime funzionalità C++).

Il codice C è anche più facile da provare semi-automaticamente. Analizzatori statici come Frama-C (dove annoti il ​​tuo codice C con commenti ACSL per aiutare la proverante ragione del tuo codice) sono disponibili per C, ma non tanto per C++ 11 completo.

Secondo me manca un punto in questa discussione: in C è più semplice fornire un'interfaccia binaria stabile da una libreria. Sia per l'utilizzo con altre lingue che con C++.

In C++ compilatori diversi usano la manipolazione di nomi diversi, quindi i consumatori di una libreria compilata con un compilatore diverso dalla libreria potrebbero avere problemi ad usarla. Con C l'interfaccia binaria, di solito, è standardizzata per la piattaforma.

So che al giorno d'oggi i compilatori spesso hanno degli switch per produrre cose compatibili con gcc, ma ciò non sempre aiuta.

Lo osservo su Solaris relativamente spesso. La distribuzione e diversi fornitori di software utilizzano in genere Sun Studio poiché, in particolare sui sistemi Sparc, spesso fornisce risultati migliori. I progetti open source di Man sono scritti con codice specifico di gcc. Può essere abbastanza doloroso far lavorare insieme quelli.

0
johannes