¿Por qué predomina C ++ en los concursos y competencias de programación? [cerrado]

23

Entiendo que C ++ es un lenguaje muy rápido, pero ¿no es C igual de rápido o más rápido en algunos casos?

Entonces podría decir que C ++ tiene OOP, pero la cantidad de OOP que necesita para la mayoría de los rompecabezas de programación no es tan grande, y en mi opinión, C podría manejar eso.

He aquí por qué pregunto esto : estoy muy interesado en programar concursos y competiciones, y estoy acostumbrado a codificar en C en esos. Sin embargo, noté que la gran mayoría de las personas usan C ++ (por ejemplo, 17 de los 25 finalistas en Google Code Jam 2011 lo usaron, mientras que nadie usó C), por lo que me pregunto si estoy en desventaja con C.

Además de la Orientación a objetos, ¿qué hace que C ++ sea un lenguaje más adecuado para la programación de competencias? ¿Cuáles son las características del lenguaje que debo aprender y usar para desempeñarme mejor en las competencias?

Para el fondo, me considero bastante competente en C, pero estoy empezando a aprender C ++.

Daniel Scocco
fuente

Respuestas:

56

Para empezar, siempre habrá algunos problemas que se resolverán mejor en un idioma que en otro. Siempre habrá idiomas que resuelvan problemas específicos "mejor" que cualquier otro idioma, para alguna definición de "mejor". Sin embargo, una gran cantidad de problemas tiene necesidades muy similares (algunas E / S, algunos cálculos) y se enfrentan a requisitos similares (confiabilidad razonable, rendimiento razonable).

Como ya sabe C, para la gran mayoría de los problemas existentes, afirmo que C ++ no proporciona inconvenientes significativos y una serie de mejoras significativas. ¿Negrita? Algunas personas parecen pensar que sí, pero es realmente el caso. Comencemos aclarando algunos malentendidos muy comunes de C ++:

  • C ++ es más lento que C. ¡Incorrecto! Muchos programas C también son programas C ++ válidos, y dicho programa C debería ejecutarse a la misma velocidad cuando se compila con el compilador C o el compilador C ++.

  • Las características específicas de C ++ requieren gastos generales. ¡Incorrecto! La denominada sobrecarga introducida por ciertas características específicas de C ++ (como las llamadas a funciones virtuales o excepciones) es comparable a la sobrecarga que usted mismo introduciría si implementa una característica similar en C.

  • C ++ está orientado a objetos. ¡Incorrecto! El lenguaje C ++ contiene algunas extensiones de lenguaje que facilitan la programación orientada a objetos y la programación genérica. C ++ no fuerza el diseño orientado a objetos en ninguna parte, simplemente lo permite. C también permite la programación orientada a objetos, C ++ solo lo hace más simple y menos propenso a errores.

Entonces, si me cree, hemos establecido que "C ++ no es significativamente peor que C". Echemos un vistazo a lo que hace que C ++ sea una mejor C:

  • Tipeo más fuerte El sistema de tipos en C ++ es más fuerte que en C. Esto evita muchos errores de programación comunes; junto con la siguiente característica muy importante, el sistema de tipos más fuertes incluso logra no ser un inconveniente.

  • Tipos parametrizados La palabra clave de plantilla permite al programador escribir implementaciones genéricas (independientes del tipo) de algoritmos. Donde en C, se podría escribir una implementación de lista genérica con un elemento como:

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

C ++ le permite a uno escribir algo como:

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

La implementación de C ++ no solo evita errores comunes del programador (como poner un elemento del tipo incorrecto en la lista), sino que también permite una mejor optimización por parte del compilador. Por ejemplo, una implementación de clasificación genérica está disponible en C y C ++:

la rutina C se define como:

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

mientras que la rutina C ++ se define como

template void sort(RandomAccessIterator first, RandomAccessIterator last);

La diferencia es que, por ejemplo, ordenar una matriz de enteros requeriría, en el caso de C, una llamada de función para cada comparación individual, mientras que la implementación de C ++ permitiría al compilador en línea las llamadas de comparación de enteros, ya que la rutina de clasificación real es El compilador crea instancias automáticamente en tiempo de compilación, con los tipos correctos insertados en los argumentos de la plantilla.

  • Una biblioteca estándar más grande C ++ permite el uso completo de la biblioteca estándar C. Esto es muy importante, por supuesto, ya que la biblioteca estándar C es un recurso invaluable al escribir programas del mundo real. Sin embargo, C ++ incluye la Biblioteca de plantillas estándar. El STL contiene una serie de plantillas útiles, como la rutina de clasificación anterior. Incluye estructuras de datos comunes útiles como listas, mapas, conjuntos, etc. Al igual que la rutina de clasificación, las otras rutinas STL y estructuras de datos están "adaptadas" a las necesidades específicas que tiene el programador; todo lo que el programador tiene que hacer es completar el tipos.

Por supuesto, el STL no es una bala de plata, pero proporciona una gran ayuda muy a menudo al resolver problemas generales. ¿Con qué frecuencia ha implementado una lista en C? ¿Con qué frecuencia un árbol RB habría sido una mejor solución, si solo hubiera tenido tiempo de hacerlo? Con el STL no necesita hacer tales compromisos: use el árbol si le queda mejor, es tan fácil como usar la lista.

Ok, solo he estado discutiendo las partes buenas. ¿Hay alguna desventaja? Por supuesto que los hay. Sin embargo, su número se está reduciendo día a día. Dejame explicar:

  • No hay buenos compiladores de C ++. Ha sido así durante mucho tiempo. Pero debe recordar que el lenguaje se estandarizó en 1998: es un lenguaje complejo, más complejo que C. Los compiladores han tardado mucho tiempo en alcanzar el estándar. Pero a partir de este escrito, hay buenos compiladores disponibles para las plataformas más utilizadas; GCC en las versiones 3.X generalmente son muy buenas, y se ejecuta en GNU / Linux y la mayoría de las plataformas UNIX. Intel tiene un buen compilador para Win32; también es bastante bueno, pero desafortunadamente todavía se basa en MS STL, que no está a la altura.

  • La gente no conoce bien C ++ Esta no es una queja que se escucha con frecuencia, pero es algo que veo mucho. C ++ es un lenguaje grande y complejo, pero también solía ser un lenguaje que se promocionaba mucho, especialmente en los días de "OOP resuelve el hambre, cura el SIDA y el cáncer". El resultado parece ser que una gran cantidad de código C ++ realmente pobre, básicamente C malo con algunas declaraciones de clase aquí y allá, está por ahí y se está utilizando como material de aprendizaje. Esto significa que muchas personas que creen que conocen C ++ en realidad escriben código realmente malo. Eso es una lástima, y ​​es un problema, pero creo que es injusto culpar de esto a C ++.

Por lo tanto, los únicos dos problemas principales con C ++ son los resultados de que C ++ es un lenguaje joven. Con el tiempo se desvanecerán. Y para la mayoría de los problemas, si puede obtener buenos programadores (o aprender un buen C ++ usted mismo), los problemas no son realmente un problema hoy en día.

niko
fuente
8
+1. Muy completa respuesta. Lo único que tengo una opinión diferente es que en el futuro, las principales desventajas de C ++ desaparecerán. Dado que C ++ tiene que ser compatible con versiones anteriores, casi no se eliminarán las funciones de lenguaje de C ++, solo se agregarán nuevas (C ++ 11 es un ejemplo perfecto para esto). Eso hará que el lenguaje sea aún más complejo de lo que es hoy, lo cual es, en mi humilde opinión, el mayor inconveniente de C ++.
Doc Brown
@DocBrown: Eso depende de cómo uses C ++. Si está trabajando con muchos códigos antiguos, debe comprender cómo funciona y, por lo tanto, probablemente necesite un amplio conocimiento de C ++. Si solo está escribiendo un código nuevo (como en una competencia), puede limitarse a lo que va a usar, evitando un montón de información (como, por ejemplo auto_ptr<>).
David Thornley
Gran respuesta, pero creo que "Muchos programas C también son programas C ++ válidos" no es lo suficientemente fuerte ya que las diferencias no cambian la generación de código. Casi todos los programas de C podrían reescribirse como un programa de C ++ válido con un rendimiento idéntico con relativamente poco esfuerzo.
Gort the Robot
3

Concursos como ese no tienen que ver tanto con la velocidad del programa como con la velocidad del programador. C ++ tiene características de biblioteca estándar, seguridad de tipo y ayuda para la administración de memoria que hace que el desarrollo y la depuración sean más rápidos, incluso si el ejecutable termina un poco más lento.

Karl Bielefeldt
fuente
2

Hablando como finalista anterior de Code Jam, se trata principalmente de las bibliotecas en lugar de las características del lenguaje. Las soluciones de competencia rara vez usan principios de diseño de OOP, pero es probable que vea un recorrido por la mayoría de los contenedores y algoritmos de la biblioteca estándar: cadena, vector, lista, pila, cola, deque, prioridad_queda, conjunto, mapa, complejo, par, bitset, lower_bound, reverse, sort, find, count, nth_element, min, max, min_element, max_element, unique, next_permutation, ... los concursantes expertos estarán familiarizados con todos ellos y ganarán mucho tiempo al no tener que implementar y depurarlos en C.

Code Jam permite a los concursantes traer su propio código y usar bibliotecas de terceros, por lo que, en teoría, un concursante podría tener todo esto implementado previamente en C. Sin embargo, no todos los concursos lo permiten, y las plantillas y la sobrecarga del operador hacen que esto sea mucho más legible que en C.

Bruce Merry
fuente