¿Necesito aprender C?

8

Soy un estudiante de doctorado en Informática Científica y en los últimos meses, pasé una buena cantidad de tiempo aprendiendo Python y C ++ de la manera correcta. Siento que he aprendido bien C ++ y puedo usar Python para hacer lo que quiero si mantengo un buen libro de referencia.

También conozco MATLAB lo suficiente como para crear prototipos de mis ideas y obtener soluciones. (Si estoy demasiado aburrido para codificar Python, que es mi primera opción).

He leído varias veces aquí que uno debe agrupar C y C ++ en un "C / C ++" porque son lenguajes extremadamente diferentes con diferentes motivos y estoy completamente de acuerdo con ese punto de vista.

Aunque no puedo afirmar que "conozco" C ++ ya que siempre estoy aprendiendo, pero creo que entiendo la mayoría de cómo debería usarlo y cómo no debería usarlo. El primer lenguaje que aprendí fue C pero ha pasado mucho tiempo desde la última vez que lo usé. Mi pregunta es esencialmente esta:

Dado que sé MATLAB, C ++ y Python; ¿Debo invertir tiempo en aprender C? ¿Mi conocimiento de los 3 idiomas mencionados será suficiente para que codifique?

Mi investigación se centra más en el lado del álgebra lineal numérica, pero también realizo algunas consultas sobre simulación de eventos discretos / procesos estocásticos. Mi intención es trabajar en la industria (mi asesor me sugirió que aprendiera C ++ para poder seguir siendo empleado, aunque él no tiene preferencias personales de idiomas).

Encuesta
fuente
La diferencia entre Fortran 60 y Fortran 2003 es mayor que entre C99 y C ++ 98. Y entre 77 y 2003 es más o menos lo mismo. Aún así, la gente los llama "simplemente" Fortran.
Misha
1
Debe lanzar todos estos otros idiomas y simplemente aprender Fortran;) Fortran moderno tiene todo lo que necesita para lo que hace.
Nasser
Independientemente del idioma que utilice, asegúrese de documentar cualquier código que deba mantenerse e incluya algunos ejemplos y pruebas automatizadas. Si no estás haciendo eso, entonces realmente no sabes ningún idioma.
cjordan1
@Nasser, excepto si desea trabajar con cualquier marco de código abierto a gran escala. Lammps, dealii, Trilinos, MercuryDPM, todos C ++. Aconsejaría a la gente que aprenda todo menos Fortran, pero al final eso es solo una cuestión de preferencia.
BlaB

Respuestas:

13

Solo abordaré la comparación de C a C ++. Si bien es cierto que cualquier cosa escrita en C se puede portar a C ++ con algunos retoques sintácticos, las comunidades tienen valores diferentes. La comunidad de bibliotecas C, más que casi cualquier otra, valora la estabilidad binaria . La estabilidad binaria es crítica para las bibliotecas de bajo nivel para evitar infligir dolor constante en las capas anteriores, especialmente cuando se usa con un modelo de distribución binaria y bibliotecas compartidas. C es la preferencia abrumadora por tales bibliotecas que solo necesitan funcionar, con la capacidad de enviar nuevas versiones sin volver a compilar las capas anteriores.

Es posible enviar bibliotecas de C ++ que funcionan a este nivel, pero terminará necesitando "escribir C en C ++". Por ejemplo, nunca colocaría una definición de estructura con miembros privados o virtuales en un encabezado público, nunca usaría plantillas en una interfaz pública y nunca tendría una API basada en la herencia de clases que tienen miembros de datos. Estas restricciones son necesarias para contener dependencias con precisión, de modo que pueda modificar su implementación sin cambiar la interfaz binaria. C tiende a ser mucho más fácil de vincular desde diferentes lenguajes, debido a su modelo de objeto más simple y ABI bien definido.

Si está escribiendo código a nivel de aplicación en lugar de a nivel de biblioteca, entonces su interfaz binaria no es importante, por lo que muchas de estas preocupaciones desaparecen. El uso de las características del lenguaje C ++, como la herencia y las plantillas, aún tiende a producir código más estrechamente acoplado, lo que lleva a una compilación más lenta a medida que el proyecto crece. Además de las dependencias de tiempo de compilación más extensas, simplemente compilar código C con un compilador C ++ aumenta significativamente el tiempo de compilación (aproximadamente 2 veces con la mayoría de las cadenas de herramientas).

Si estas inquietudes le interesan, o si planea trabajar en bibliotecas de nivel inferior, puede valer la pena pasar tiempo en C Si le gusta usar las características del lenguaje C ++ y no le molestan demasiado las interfaces binarias y la rigidez de acoplamiento, entonces puede que no sea un buen uso del tiempo. Pero tenga en cuenta a C si estas cosas comienzan a molestarlo en el futuro.

Jed Brown
fuente
Hubo muchas respuestas increíbles, fue difícil elegir una, pero en mi opinión, esta fue la más descriptiva y completa. +1 a todos sin embargo. Disfruté muchísimo leyendo tantas perspectivas. Decidí que seguiré perfeccionando C ++ y aprenderé C según sea necesario.
Investigación
Para completar, es posible que desee agregar el idioma pimpl es una forma en que los codificadores de C ++ pueden construir "firewalls de compilación" para que no tengan que volver a compilar el código de la aplicación después de los cambios de implementación subyacentes.
cjordan1
7

En lugar de "aprender C", te sugiero que estés en un punto en el que hayas realizado suficiente programación y trabajado con suficientes lenguajes de programación en los que deberías concentrarte en mejorar tu técnica de programación y un conocimiento más amplio de la informática. Luego aprenda C si lo necesita para un proyecto en particular.

Los programadores experimentados aprenden rápidamente nuevos lenguajes de programación según sea necesario para proyectos particulares. Pueden hacerlo porque entienden conceptos importantes que se traducen de un idioma a otro; la sintaxis no es un gran problema si dominas esos conceptos de nivel superior. Cuando observa a los estudiantes que intentan aprender su segundo lenguaje de programación, a menudo los verá luchar para comprender algún concepto nuevo que no era parte de su primer idioma. Por ejemplo, los estudiantes que comienzan con Fortran a menudo luchan con punteros en C. Los estudiantes que conocen C a menudo luchan con las características orientadas a objetos de C ++, y así sucesivamente.

Brian Borchers
fuente
6

La respuesta a esta pregunta realmente depende de lo que realmente hagas.

Como informático que hace informática de alto rendimiento , diría que es esencial conocer / comprender la programación en C.

Pero si solo está haciendo cosas en las computadoras, su conocimiento de C ++ debería ser suficiente para ayudarlo.

Más específicamente, si está realmente interesado en aspectos computacionales, es decir, escribir algoritmos que aprovechan al máximo las computadoras modernas, no podrá evitar tener que lidiar con aspectos de bajo nivel como la administración de memoria, diseños de datos, SIMD vectorización, paralelismo a nivel de instrucción, paralelismo de memoria compartida o computación GPU (CUDA y OpenCL se basan en C).

Ahora, la mayoría de estas cosas pueden ser atendidas por compiladores (por ejemplo, para gestión de memoria, diseños de datos, vectorización) y / o abstracciones de nivel superior (por ejemplo, OpenMP, OpenACC, bibliotecas optimizadas). Pero solo hasta cierto punto. Hacer las cosas a mano generalmente implica más trabajo, pero la recompensa puede ser un orden de magnitud en el rendimiento.

Básicamente, cada vez que desee controlar los detalles usted mismo , generalmente termina usando C ya que está "más cerca del metal". La pregunta es, sin embargo, ¿es eso lo que realmente quieres?

Pedro
fuente
1
¿Cómo puedes decir que C ++ está más lejos del metal que C? ¿Qué no puedes hacer en C ++ que puedes hacer en C? ¿Y está diciendo que hay características útiles insignificantes en C ++ para la computación de bajo nivel?
Milind R
@MilindR: De acuerdo, puedes compilar un programa en C con un compilador de C ++, por lo que C ++ puede hacer todo lo que hace C ++. El problema está en las características adicionales que proporciona C ++, por ejemplo, objetos polimórficos, plantillas, tuberías, etc., que no se asignan bien al "metal" real. Si usa alguna de estas características de C ++, pierde el control de lo que su programa está haciendo realmente, instrucción por instrucción. Ese es el punto que estaba tratando de hacer, y por el cual estoy de pie.
Pedro
Estoy de acuerdo con los objetos polimórficos, pero ¿cómo pueden las plantillas llevarlo más lejos del metal? Creo que te estás refiriendo a las jerarquías de herencia aquí. Cualquier cosa que no los use es probable que esté bastante cerca del metal.
Milind R
1
@MilindR: No. Digamos que usa una clase de plantilla para un vector de floato double. Las operaciones reales en esos vectores se implementarán de manera óptima para uno o para el otro, pero nunca para ambos. Las jerarquías de herencia tienen el mismo problema que los objetos polimórficos: si no conoce el tipo exacto en tiempo de compilación, no solo tiene una pequeña sobrecarga en la selección de la función correcta, sino que tampoco puede alinear la función de destino.
Pedro
Para eso es la especialización de plantilla. Acuerde no saber el tipo en tiempo de compilación, lo que resulta en una sobrecarga.
Milind R
4

Hay un poco de copiar y pegar de mi respuesta a esta pregunta , con algunos detalles adicionales.

Trabajo en la industria (fabricante de equipos de topografía y control de máquinas) usando procesadores integrados débiles (piense en procesadores de teléfonos móviles), donde aproximadamente el 50% del ronquido computacional se gasta haciendo cálculos numéricos, principalmente trabajo de fusión de sensores.

Tenemos un matemático trabajando para nosotros que solía trabajar en un grupo de HPC, por lo que este es uno de los lugares extraños donde eventualmente puedes encontrar un trabajo.

En este entorno, donde seguramente tendrá un sistema operativo (por ejemplo, Linux, QNX, WinCE), C ++ es el rey. Utilizamos C solo para el trabajo del núcleo (es decir, los controladores de dispositivo) y para el trabajo profundamente integrado sin un sistema operativo (micros de 8 bits). No usamos C para ningún trabajo numérico. De hecho, ¡no tenemos un compilador FORTRAN para nuestra plataforma!

El alto rendimiento nos importa porque solo tenemos una CPU de 1 vatio para el procesamiento. Si bien no tenemos algunos de los problemas "glamorosos" del paralelismo, debemos ser conscientes de la memoria caché y la memoria, y cada vez más debemos ser conscientes de SIMD (piense en NEON ). Además, a diferencia de HPC, tenemos que ser muy conscientes de la latencia (¡esto es control de la máquina!) Y otros aspectos del sistema operativo como la programación y el cambio de contexto. La asignación de memoria es especialmente desagradable en este entorno, ya que casi con certeza significa un cambio de contexto (== latencia y, en una CPU de 400MHz, costoso en términos de tiempo).

Estos problemas son independientes de la elección del lenguaje, por lo que no estaré de acuerdo con la respuesta de @Pedro de que C es necesario; después de todo, los intrínsecos del compilador para SIMD están disponibles cuando se usa C ++. Sin embargo, sí significa que debe tener mucho cuidado con las características de C ++ que usa y su costo.

Entonces, para completar la respuesta, no, no necesita C. Usamos MATLAB para el trabajo de análisis y python para la secuencia de comandos, por lo que sus dos lenguajes que no sean C ++ son buenas opciones, al menos en mi industria.

Damien
fuente
3

Es bueno conocer C, y en realidad puede implementar muchas de las características OO de C ++ que son relevantes para el cálculo científico en C sin muchos problemas (es muy instructivo echar un vistazo al código fuente de PETSC para ver cómo funcionan). eso).

Dicho esto, no hay una respuesta única para esta pregunta. Hay muchos factores para elegir un idioma, el tiempo de ejecución es uno de ellos. El tiempo que pasas escribiendo, depurando y perfilando código es otro factor importante. Al final, quieres ser lo más productivo posible. Conocer C será excelente si tiene la intención de entrar en el lado de alto rendimiento de la investigación, o si anticipa que su código tardará mucho tiempo en ejecutarse (es decir, el tiempo de ejecución supera su tiempo de flujo de trabajo de codificación). De lo contrario, si conoces C ++ y estas cosas no son un problema, deberías poder entender el código C lo suficientemente bien como para comunicarte con quienes lo usan.

Reid.Atcheson
fuente
2
¿Pero es C realmente más rápido que C ++?
Investigación
2
Los lenguajes de programación no son rápidos o lentos a priori, es el programador el que escribe un buen código que determina su efectividad. La ventaja de C es que es muy simple, y escribir código eficiente en él es mucho más fácil que escribir código eficiente en C ++ o Python (suponiendo que esté haciendo uso completo de las facultades del lenguaje). He visto un código C ++ muy rápido que utiliza todas sus capacidades que requieren rodar su propia administración de memoria y hacer todo tipo de cosas desagradables con la sobrecarga del operador, considere el tiempo que lleva escribir eso en comparación con una versión C equivalente para la misma velocidad.
Reid.Atcheson 01 de
2
@GeoffOxberry Algunos de los paquetes que menciona están realmente escritos para ofrecer flexibilidad (dentro de cierto alcance) mucho más que velocidad. Aquellos escritos para una velocidad absoluta sufren la difícil depuración, el enorme tiempo de compilación y los grandes binarios inherentes al uso de plantillas por mucho más de lo que es realmente necesario para el rendimiento. Por supuesto, puede escribir un paquete "C" en C ++, pero los valores de la comunidad son bastante diferentes.
Jed Brown
1
Además, por "alto rendimiento" no necesariamente quise escribir simplemente código de alto rendimiento. Me refería al lado de la investigación de HPC, a menudo tratando con muchos detalles de nivel inferior. estos pueden oscurecerse usando un estilo de programación C ++. Esto no es necesariamente algo malo, pero depende de cuáles sean tus objetivos.
Reid.Atcheson
1
En otras palabras, si usted es un investigador de HPC, escribir código con otro paquete que resulta ser rápido no es realmente de gran valor en cuanto a investigación. La gente querrá saber por qué su código es más rápido y por qué su enfoque es efectivo, y citar un paquete no es suficiente.
Reid.Atcheson
2

El valor de c, como lo es en estos días, es que te obliga a familiarizarte con el funcionamiento de la computadora en un bajo nivel de abstracción (en comparación con, por ejemplo, python). Ahora, c ++ tiene todas las facilidades de bajo nivel de c y podría funcionar igual de bien, pero se alienta a la mayoría de las personas cuando se inclinan por c ++ para evitar las abstracciones de nivel más bajo y confiar en las de alto nivel (bien probadas y depuradas); cosas como la biblioteca de contenedores, punteros inteligentes, polimorfismo, etc.

Tiene sentido que la mayoría de los programadores pasen la mayor parte de su tiempo jugando en reinos de alta abstracción, porque pueden dedicar más tiempo mental y energía a escribir lo que quieren decir que a manejar los pequeños detalles exigentes de cómo lograrlo.

El costo de esa actitud es el riesgo de que las abstracciones con fugas lo muerdan cuando menos lo espera , pero casi seguramente aumenta la eficiencia general de la programación.

Entonces, si está satisfecho con lo que sabe sobre el funcionamiento de bajo nivel de su computadora, puede posponer con seguridad c, e incluso si no lo está, podría usar un conjunto restringido de c ++ para lograr lo mismo.

dmckee --- gatito ex moderador
fuente
1

Respondí una pregunta similar una vez en Stack Overflow. La respuesta obvia es aprender todo lo que puedas, ¿verdad?

Así que echemos un vistazo al punto de vista negativo. Usted ya es más competente en tres idiomas que consideraría más valiosos que C para la programación científica. En mi trabajo de consultoría escribiendo software científico, he usado MATLAB, Python, FORTRAN y Java. Nunca he tenido la necesidad de usar C o C ++, pero tenga en cuenta que todo mi trabajo ha sido en nuevos proyectos. No recomendaría a un cliente que inicie un proyecto grande en C / C ++, pero recomendaría Java, o incluso Scala, a menos que haya alguna razón convincente para usar C / C ++. Para un proyecto más pequeño, probablemente iría con Python. En su caso, parece que podría tratar con C según sea necesario.

Esperaría que aprender más sobre los dominios en los que trabajará valdrá más la pena que ser un experto en idiomas. Al final, lo que importa es la solución del problema, no la herramienta. La opinión de Knuth sobre la "optimización prematura" también se aplica a la preparación para una carrera.

Glenn
fuente
1

Probablemente no valga la pena.

C ++ y C tienden a ocupar los mismos nichos en la ciencia computacional (quizás los sistemas integrados son una excepción). Solía ​​ser el caso de que los compiladores de C eran mejores (más funciones completas, mejor en optimización) que los compiladores de C ++, pero por lo que entiendo ahora, ese ya no es el caso.

Claro, C es un lenguaje maravilloso (y lo prefiero a C ++), y si tienes el tiempo y el deseo, te recomendaría aprenderlo, pero si tienes poco tiempo, no veo otra razón convincente que no sea "I necesita trabajar en un proyecto que se está escribiendo en C "(e incluso entonces, una gran parte de su conocimiento de C ++ se transferirá).

Geoff Oxberry
fuente
0

Creo que algunos conocimientos de C son útiles, principalmente para aprender cómo compilar cosas con el enlace "C externo" para que pueda incorporar bibliotecas de C / Fortran heredadas (por ejemplo, lapack) en nuevos proyectos de C ++. No invertiría mucho tiempo en aprender las bibliotecas de C heredadas, esas cosas se pueden recoger / buscar en Google según sea necesario, o en ocasiones reemplazarse por una funcionalidad equivalente en C ++ stdlib.

rchilton1980
fuente