Perché il C ++ è predominante nei concorsi e nelle competizioni di programmazione? [chiuso]


23

Capisco che C ++ è un linguaggio molto veloce, ma C non è altrettanto veloce o più veloce in alcuni casi?

Quindi potresti dire che C ++ ha OOP, ma la quantità di OOP di cui hai bisogno per la maggior parte dei puzzle di programmazione non è così grande, e secondo me C sarebbe in grado di gestirlo.

Ecco perché lo sto chiedendo : sono molto interessato alla programmazione di concorsi e competizioni e sono abituato a scrivere codice in C su quelli. Tuttavia, ho notato che la stragrande maggioranza delle persone usa C ++ (ad esempio, 17 finalisti su 25 su Google Code Jam 2011 lo hanno usato, mentre nessuno ha usato C), quindi mi chiedo se sono in svantaggio rispetto a C.

A parte l'Object Orientation, cosa rende C ++ un linguaggio più adatto per le competizioni di programmazione? Quali sono le caratteristiche della lingua che dovrei imparare e usare per ottenere risultati migliori nelle competizioni?

Per quanto riguarda lo sfondo, mi considero abbastanza competente in C, ma sto appena iniziando a imparare C ++.

Risposte:


56

Per cominciare, ci saranno sempre alcuni problemi che sono meglio risolti in una lingua piuttosto che in un'altra. Ci saranno sempre lingue che risolvono problemi specifici "migliori" rispetto a qualsiasi altra lingua, per una definizione di "migliore". Tuttavia, un numero molto elevato di problemi ha esigenze molto simili (alcuni I / O, alcuni calcoli) e deve affrontare requisiti simili (ragionevole affidabilità, prestazioni ragionevoli).

Come già sapete in C, per la stragrande maggioranza dei problemi là fuori, dichiaro che C ++ non offre svantaggi significativi e una serie di miglioramenti significativi. Grassetto? Alcune persone sembrano pensarlo, ma è davvero il caso. Cominciamo chiarendo alcuni fraintendimenti C ++ molto comuni:

  • C ++ è più lento di C. Sbagliato! Anche molti programmi C sono programmi C ++ validi e tale programma C dovrebbe essere eseguito a velocità identica se compilato con il compilatore C o il compilatore C ++.

  • Le funzionalità specifiche di C ++ richiedono un sovraccarico. Sbagliato! Il cosiddetto overhead introdotto da alcune funzionalità specifiche di C ++ (come chiamate di funzione virtuali o eccezioni), è paragonabile all'overhead che tu stesso introduresti se implementassi una funzionalità simile in C.

  • C ++ è orientato agli oggetti. Sbagliato! Il linguaggio C ++ contiene alcune estensioni di linguaggio che facilitano la programmazione orientata agli oggetti e la programmazione generica. Il C ++ non forza il design orientato agli oggetti da nessuna parte, ma semplicemente lo consente. C consente anche la programmazione orientata agli oggetti, C ++ rende solo più semplice e meno soggetto a errori.

Quindi, se mi credi, abbiamo stabilito che "C ++ non è significativamente peggiore di C". Diamo un'occhiata a ciò che rende C ++ un C migliore:

  • Digitazione più forte Il sistema di tipi in C ++ è più forte che in C. In questo modo si evitano molti errori di programmazione comuni - insieme alla successiva caratteristica molto importante, il sistema di tipo più forte riesce anche a non essere un inconveniente.

  • Tipi con parametri La parola chiave modello consente al programmatore di scrivere implementazioni generiche (di tipo agnostico) di algoritmi. Dove in C, si potrebbe scrivere un'implementazione di elenco generica con un elemento come:

    struct element_t {
      struct element_t *next, *prev;
      void *element;
     };

Il C ++ permette di scrivere qualcosa del tipo:

template <typename T>
struct element_t {
   element_t<T> *next, *prev;
   T element;
};

L'implementazione C ++ non solo impedisce errori comuni del programmatore (come mettere un elemento di tipo errato nell'elenco), ma consente anche una migliore ottimizzazione da parte del compilatore! Ad esempio, un'implementazione di ordinamento generica è disponibile in C e C ++ -

la routine C è definita come:

void qsort(void *base, size_t nmemb, size_t size,
           int(*compar)(const void *, const void *));

mentre la routine C ++ è definita come

template void sort(RandomAccessIterator first, RandomAccessIterator last);

La differenza è che, ad esempio l'ordinamento di un array di numeri interi, nel caso C richiederebbe una chiamata di funzione per ogni singolo confronto, mentre l'implementazione C ++ consentirebbe al compilatore di incorporare le chiamate di confronto di numeri interi, poiché la routine di ordinamento effettiva è istanziato automaticamente in fase di compilazione dal compilatore, con i tipi corretti inseriti negli argomenti del modello.

  • Una libreria standard più grande C ++ consente il pieno utilizzo della libreria standard C. Questo è molto importante ovviamente, poiché la libreria C standard è una risorsa inestimabile quando si scrivono programmi del mondo reale. Tuttavia, C ++ include la libreria di modelli standard. L'STL contiene una serie di modelli utili, come la routine di ordinamento sopra. Include utili strutture di dati comuni come elenchi, mappe, set, ecc. Come la routine di ordinamento, le altre routine STL e le strutture di dati sono "adattate" alle esigenze specifiche del programmatore - tutto ciò che il programmatore deve fare è compilare il tipi.

Ovviamente, l'STL non è un proiettile d'argento, ma fornisce un grande aiuto molto spesso quando si risolvono problemi generali. Con quale frequenza hai implementato un elenco in C? Quante volte un albero RB sarebbe stato una soluzione migliore se solo tu avessi avuto il tempo di farlo? Con l'STL non è necessario scendere a compromessi del genere: utilizzare l'albero se si adatta meglio, è facile come usare l'elenco.

Ok, quindi ho discusso solo delle parti buone. Ci sono degli aspetti negativi? Certo che ci sono. Tuttavia, il loro numero si sta riducendo di giorno in giorno. Lasciatemi spiegare:

  • Non ci sono buoni compilatori C ++ È stato così per molto tempo. Ma devi ricordare che il linguaggio è stato standardizzato nel 1998 - è un linguaggio complesso, più complesso di C. Il compilatore ha impiegato molto tempo a raggiungere lo standard. Ma al momento della stesura di questo documento, ci sono buoni compilatori disponibili per le piattaforme più utilizzate là fuori; GCC nelle versioni 3.X è generalmente molto buono e funziona su GNU / Linux e la maggior parte delle piattaforme UNIX. Intel ha un buon compilatore per Win32 - è anche abbastanza buono, ma sfortunatamente si basa ancora su MS STL, che è scadente.

  • Le persone non conoscono bene il C ++ Questa non è una lamentela spesso ascoltata, ma è qualcosa che vedo molto. Il C ++ è un linguaggio ampio e complesso, ma era anche un linguaggio molto pubblicizzato, specialmente ai tempi di "OOP risolve la fame, cura l'AIDS e il cancro". Il risultato sembra essere che un sacco di codice C ++ davvero scadente, fondamentalmente un C cattivo con alcune dichiarazioni di classe qua e là, è là fuori e viene utilizzato come materiale di apprendimento. Ciò significa che molte persone credono di sapere che C ++ in realtà scrive codice davvero scadente. È un peccato, ed è un problema, ma penso che sia ingiusto biasimarlo su C ++.

Quindi, gli unici due problemi principali con il C ++ sono i risultati del fatto che il C ++ è un linguaggio giovane. Col tempo svaniranno. E per la maggior parte dei problemi là fuori, se riesci a ottenere buoni programmatori (o apprendere te stesso un buon C ++), i problemi non sono davvero un problema oggi.


8
+1. Risposta molto completa. L'unica cosa che ho un'opinione diversa è che in futuro i principali svantaggi del C ++ svaniranno. Poiché il C ++ deve essere compatibile con le versioni precedenti, non ci sarà quasi nessuna caratteristica del linguaggio rimossa dal C ++, ma ne saranno aggiunte solo nuove (C ++ 11 ne è un esempio perfetto). Ciò renderà il linguaggio ancora più complesso di quanto non sia oggi, che è IMHO il più grande svantaggio del C ++.
Doc Brown,

@DocBrown: dipende da come usi C ++. Se stai lavorando con un sacco di codice precedente, devi capire come funziona e quindi probabilmente hai bisogno di una vasta conoscenza del C ++. Se stai solo scrivendo un nuovo codice (ad esempio in una competizione), puoi limitarti a ciò che intendi utilizzare, evitando molte intrusioni (come, diciamo, auto_ptr<>).
David Thornley,

Ottima risposta, ma penso che "Molti programmi C sono anche validi programmi C ++" non è abbastanza forte in quanto le differenze non cambiano la generazione del codice. Quasi ogni programma C potrebbe essere riscritto come un programma C ++ valido identicamente performante con relativamente poco sforzo.
Gort the Robot,

3

Concorsi del genere non riguardano tanto la velocità del programma quanto la velocità del programmatore. C ++ ha funzionalità di libreria standard, sicurezza dei tipi e aiuto per la gestione della memoria che velocizzano lo sviluppo e il debug, anche se l'eseguibile finisce leggermente più lentamente.


2

Parlando come un precedente finalista di Code Jam, si tratta principalmente delle librerie piuttosto che delle funzionalità del linguaggio. Le soluzioni della concorrenza raramente utilizzano qualsiasi principio di progettazione OOP, ma è probabile che tu veda un tour della maggior parte dei contenitori e degli algoritmi della libreria standard: stringa, vettore, elenco, stack, coda, deque, priority_queue, set, mappa, complesso, coppia, bitset, lower_bound, reverse, sort, find, count, nth_element, min, max, min_element, max_element, unique, next_permutation, ... i concorrenti qualificati avranno familiarità con tutti loro e guadagneranno molto tempo senza dover implementare e eseguirne il debug in C.

Code Jam consente ai concorrenti di inserire il proprio codice e utilizzare librerie di terze parti, quindi in teoria un concorrente potrebbe avere tutto questo pre-implementato in C. Tuttavia, non tutti i concorsi lo consentono, e il sovraccarico di modelli e operatori lo rende molto più leggibile che in C.

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.