Por que o C ++ é predominante em concursos e competições de programação? [fechadas]

23

Eu entendo que C ++ é uma linguagem muito rápida, mas C não é tão rápido ou mais rápido em alguns casos?

Então você pode dizer que o C ++ tem OOP, mas a quantidade de OOP necessária para a maioria dos quebra-cabeças de programação não é tão grande e, na minha opinião, C seria capaz de lidar com isso.

Aqui está o motivo pelo qual estou perguntando o seguinte : estou muito interessado em programar concursos e competições e estou acostumado a codificar em C nelas. No entanto, notei que a grande maioria das pessoas usa C ++ (por exemplo, 17 dos 25 finalistas no Google Code Jam 2011 o usavam, enquanto ninguém usava C), por isso estou me perguntando se estou em desvantagem em relação a C.

Além da Orientação a Objetos, o que torna o C ++ uma linguagem mais adequada para competições de programação? Quais são os recursos do idioma que devo aprender e usar para ter um melhor desempenho nas competições?

Como pano de fundo, considero-me bastante proficiente em C, mas estou apenas começando a aprender C ++.

Daniel Scocco
fonte

Respostas:

56

Para começar, sempre haverá alguns problemas que são melhor resolvidos em um idioma que em outro. Sempre haverá idiomas que resolvem problemas específicos "melhor" do que qualquer outro idioma, para alguma definição de "melhor". No entanto, um número muito grande de problemas tem necessidades muito semelhantes (algumas E / S, algumas computações) e enfrentam requisitos semelhantes (confiabilidade razoável, desempenho razoável).

Como você já conhece o C, para a grande maioria dos problemas existentes, afirmo que o C ++ não oferece desvantagens significativas e diversas melhorias significativas. Negrito? Algumas pessoas parecem pensar assim, mas é realmente o caso. Vamos começar esclarecendo alguns mal-entendidos muito comuns em C ++:

  • C ++ é mais lento que C. Errado! Muitos programas C também são válidos em C ++ - e esse programa em C deve ser executado em velocidade idêntica quando compilado com o compilador C ou o compilador C ++.

  • Recursos específicos do C ++ exigem sobrecarga. Errado! A chamada sobrecarga introduzida por certos recursos específicos do C ++ (como chamadas de função virtual ou exceções) é comparável à sobrecarga que você mesmo introduziria se implementasse um recurso semelhante em C.

  • C ++ é orientado a objetos. Errado! A linguagem C ++ contém algumas extensões de linguagem que facilitam a programação orientada a objetos e a programação genérica. O C ++ não força o design orientado a objetos em lugar algum - apenas permite. O C também permite programação orientada a objetos, o C ++ apenas a torna mais simples e menos propensa a erros.

Portanto, se você acredita em mim, estabelecemos que "C ++ não é significativamente pior que C". Vamos dar uma olhada no que torna o C ++ um C melhor:

  • Digitação mais forte O sistema de tipos em C ++ é mais forte que em C. Isso evita muitos erros comuns de programação - juntamente com o próximo recurso muito importante, o sistema de tipos mais fortes ainda consegue não ser um inconveniente.

  • Tipos parametrizados A palavra-chave template permite ao programador escrever implementações genéricas (independente do tipo) de algoritmos. Onde em C, pode-se escrever uma implementação de lista genérica com um elemento como:

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

C ++ permite escrever algo como:

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

A implementação do C ++ não apenas evita erros comuns do programador (como colocar um elemento do tipo errado na lista), mas também permite uma melhor otimização pelo compilador! Por exemplo, uma implementação de classificação genérica está disponível em C e C ++ -

a rotina C é definida como:

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

enquanto a rotina C ++ é definida como

template void sort(RandomAccessIterator first, RandomAccessIterator last);

A diferença é que, por exemplo, classificar uma matriz de números inteiros, no caso C exigiria uma chamada de função para todas as comparações, enquanto a implementação C ++ permitiria ao compilador alinhar as chamadas de comparação inteiras, como a rotina de classificação real é instanciado automaticamente no momento da compilação pelo compilador, com os tipos corretos inseridos nos argumentos do modelo.

  • Uma biblioteca padrão maior C ++ permite o uso completo da biblioteca padrão C. Isso é muito importante, é claro, pois a biblioteca padrão C é um recurso inestimável ao escrever programas do mundo real. No entanto, o C ++ inclui a biblioteca de modelos padrão. O STL contém vários modelos úteis, como a rotina de classificação acima. Inclui estruturas de dados comuns úteis, como listas, mapas, conjuntos, etc. Como a rotina de classificação, as outras rotinas e estruturas de dados STL são "adaptadas" às necessidades específicas do programador - tudo o que o programador precisa fazer é preencher o tipos.

Obviamente, o STL não é uma bala de prata - mas fornece uma grande ajuda com muita frequência na solução de problemas gerais. Com que frequência você implementou uma lista em C? Com que frequência uma árvore RB seria uma solução melhor, se você tivesse tempo para fazê-lo? Com o STL, você não precisa fazer tais compromissos - use a árvore se for mais adequado, é tão fácil quanto usar a lista.

Ok, então eu só tenho discutido as partes boas. Existem desvantagens? Claro que existem. No entanto, seu número está diminuindo dia a dia. Deixe-me explicar:

  • Não há bons compiladores C ++. É assim há muito tempo. Mas você deve se lembrar que a linguagem foi padronizada em 1998 - é uma linguagem complexa, mais complexa do que C. Demorou muito tempo para os compiladores alcançarem o padrão. Porém, até o momento em que este artigo foi escrito, existem bons compiladores disponíveis para as plataformas mais usadas; O GCC nas versões 3.X geralmente é muito bom e é executado no GNU / Linux e na maioria das plataformas UNIX. A Intel possui um bom compilador para o Win32 - também é muito bom, mas infelizmente ainda depende do MS STL, que é insignificante.

  • As pessoas não conhecem bem o C ++. Essa não é uma queixa frequentemente ouvida, mas é algo que eu vejo muito. O C ++ é uma linguagem grande e complexa - mas também costumava ser uma linguagem muito badalada, especialmente nos dias de "OOP resolve a fome, cura a AIDS e o câncer". O resultado parece ser que muitos códigos C ++ realmente ruins, C basicamente ruins com algumas declarações de classe aqui e ali, estão por aí e estão sendo usados ​​como material de aprendizado. Isso significa que muitas pessoas que acreditam conhecer C ++ realmente escrevem códigos realmente ruins. Isso é muito ruim e é um problema, mas acho injusto culpar o C ++ por isso.

Portanto, os únicos dois grandes problemas do C ++ são os resultados do C ++ ser uma linguagem jovem. Com o tempo eles desaparecerão. E para a maioria dos problemas existentes, se você pode obter bons programadores (ou aprender C ++ você mesmo), os problemas não são realmente um problema hoje.

niko
fonte
8
+1. Resposta muito completa. A única coisa que tenho uma opinião diferente é que, no futuro, as principais desvantagens do C ++ desaparecerão. Como o C ++ precisa ser compatível com versões anteriores, quase nenhum recurso de linguagem será removido do C ++, apenas os novos são adicionados (o C ++ 11 é um exemplo perfeito disso). Isso tornará a linguagem ainda mais complexa do que é hoje, que é o IMHO a maior desvantagem do C ++.
Doc Brown
@ DocBrown: Isso depende de como você usa C ++. Se você trabalha com muitos códigos antigos, precisa entender como isso funciona e, portanto, provavelmente precisará de um amplo conhecimento de C ++. Se você está apenas escrevendo um novo código (como em uma competição), pode limitar-se apenas ao que vai usar, evitando muita confusão (como, por exemplo, auto_ptr<>).
David Thornley
Ótima resposta, mas acho que "Muitos programas C também são válidos em C ++" não é suficientemente forte, pois as diferenças não alteram a geração de código. Quase todos os programas C poderiam ser reescritos como um programa C ++ válido com desempenho idêntico e com relativamente pouco esforço.
Gort the Robot
3

Concursos como esse não são tanto a velocidade do programa quanto a velocidade do programador. O C ++ possui recursos de biblioteca padrão, segurança de tipo e ajuda no gerenciamento de memória que torna o desenvolvimento e a depuração mais rápidos, mesmo que o executável termine um pouco mais devagar.

Karl Bielefeldt
fonte
2

Falando como finalista anterior do Code Jam, trata-se principalmente das bibliotecas, e não dos recursos da linguagem. As soluções de concorrência raramente usam princípios de design de POO, mas é provável que você veja um tour pela maioria dos contêineres e algoritmos da biblioteca padrão - string, vetor, lista, pilha, fila, deque, priority_queue, set, map, complex, pair, bitset, lower_bound, reverse, sort, find, count, nth_element, min, max, min_element, max_element, unique, next_permutation, ... competidores qualificados estarão familiarizados com todos eles e ganharão muito tempo por não precisar implementar e depure-os em C.

O Code Jam permite que os participantes tragam seu próprio código e usem bibliotecas de terceiros. Portanto, em teoria, um participante pode ter tudo isso pré-implementado em C. No entanto, nem todos os concursos permitem isso, e os modelos e a sobrecarga do operador tornam isso muito mais legível. do que em C.

Bruce Merry
fonte