Creo que C es un buen lenguaje para aprender los principios detrás de la programación. ¿Qué aprendes a aprender en los idiomas de nivel inferior que están "mágicos" lejos de los de alto nivel, como Ruby?
Creo que C es un buen lenguaje para aprender los principios detrás de la programación. ¿Qué aprendes a aprender en los idiomas de nivel inferior que están "mágicos" lejos de los de alto nivel, como Ruby?
Respuestas:
No hay principios, en el sentido abstracto general de la informática, que estén presentes en C y que tampoco estén presentes en los lenguajes de nivel superior. Toda la informática se reduce a algoritmos, y todos los algoritmos se pueden implementar en cualquier lenguaje que sea Turing completo como C.
La diferencia que C lleva aparte de los lenguajes de nivel superior es similar a la diferencia que el código de máquina lleva aparte de C: La relación de la máquina con el código.
A medida que escribe código en lenguajes de alto nivel, no se preocupa (generalmente) de cómo interactúa su código con la máquina. La máquina virtual que el lenguaje define por sí misma oculta muchos de esos aspectos de la ejecución del código.
En C, la interacción de su programa con la memoria se mantiene a la vanguardia. Es más que simplemente que tiene que administrar su uso del montón, incluye la interacción de su código con la pila y cómo el simple acceso a la memoria de su código afecta el comportamiento y el rendimiento de su código, ni siquiera el orden de los accesos a la memoria. se le puede permitir escapar de su atención, ya que leer la memoria incorrecta en el momento incorrecto puede afectar el rendimiento de manera efectiva.
En los idiomas de nivel superior, estas cosas simplemente no son tan obvias. La memoria se asigna y se desasigna sin su conocimiento y, a veces, sin su solicitud. Muy a menudo, esto simplemente está fuera de su control. El cuándo, el dónde, el cómo y el por qué de la mayoría de las asignaciones de memoria simplemente están ocultos para usted.
Del mismo modo, en la otra dirección, escribir código de máquina o código de ensamblaje trae aún más detalles en primer plano: casi no queda nada fuera de su alcance, y su código debe escribirse consciente de cada asignación, cada recurso, cada pieza de datos que pasa a través de los registros de la CPU: conocimiento que está tan alejado de los lenguajes de alto nivel como para ser arcano.
Sé que C es un buen lenguaje para aprender los principios detrás de la programación.
Estoy en desacuerdo. C carece de muchas funciones para aprender los principios detrás de la programación. Las características de C para crear abstracciones son terribles, y la abstracción es uno de los principios clave detrás de la programación.
Si desea aprender cómo funciona el hardware y, por lo tanto, cierta simpatía mecánica por la máquina, debe aprender el código de la máquina, también conocida como la arquitectura del conjunto de instrucciones, y también estudiar la construcción de la memoria caché de las CPU modernas. Tenga en cuenta que no estoy recomendando lenguaje ensamblador, solo entienda las instrucciones de hardware, para que entienda lo que genera un compilador.
Si desea aprender los principios de programación, use un lenguaje moderno como Java, C # o Swift, o una de las docenas de otros como Rust. Además, estudie los diferentes tipos de paradigmas de programación, incluidos los funcionales.
La mayoría de los lenguajes de programación se describen en términos de máquinas abstractas. Luego, se implementan utilizando conjuntos de herramientas como compiladores, enlazadores, ensambladores, intérpretes, analizadores estáticos, lenguajes intermedios y hardware que producirán colectivamente un resultado que honre al menos todo el comportamiento esperado de la máquina abstracta, según lo observado por un programa .
C no es una excepción a la regla anterior. Se describe en términos de una máquina abstracta que no tiene noción de su hardware real.
Como tal, cuando la gente dice que C te enseña cómo funciona realmente tu computadora, lo que generalmente significan es que C te enseña cómo funciona C. Pero siendo C tan penetrante en la programación de sistemas, es comprensible que mucha gente empiece a confundirlo con la computadora misma. Y personalmente iría tan lejos como para decir que saber cómo funciona C suele ser más importante que saber cómo funciona la computadora.
Pero aún así, C y la computadora son cosas diferentes. El hardware real es realmente complicado, en formas que hacen que la especificación C se lea como un libro infantil. Si está interesado en cómo funciona su hardware, siempre puede buscar un manual y comenzar a escribir código en un ensamblador. O bien, siempre puede comenzar a aprender sobre circuitos digitales para poder diseñar un hardware por su cuenta. (Como mínimo, apreciará lo alto que es el C).
De acuerdo, aprender sobre hardware implica cosas diferentes a C. Pero, ¿puede C enseñar algo más a los programadores de hoy?
Creo que depende
No se apresure a elegir una de estas posibilidades. He estado escribiendo código durante muchos años y todavía no tengo idea de cuál es la respuesta correcta, o si la respuesta correcta es solo una de las dos, o si existe una respuesta correcta sobre este tema.
Estoy un poco inclinado a creer que probablemente deberías aplicar ambas opciones, sin apretarlas en el orden en que las describí. Pero no creo que esto sea realmente un asunto técnico, creo que es principalmente educativo. Cada persona parece aprender de maneras significativamente diferentes.
Si respondiste la pregunta anterior al menos involucrando la segunda opción que propuse, entonces ya tienes algunas respuestas en tu haber: cualquier cosa que se pueda aprender en idiomas de nivel superior se puede aprender mejor reinventando en C o en menos expandido agregando C a la mezcla.
Pero, independientemente de su respuesta, ciertamente hay algunas cosas que puede aprender casi exclusivamente de C (y tal vez un puñado de otros idiomas).
C es históricamente importante. Es un hito que puedes ver y apreciar de dónde venimos y quizás tener un poco más de contexto sobre hacia dónde vamos. Puede apreciar por qué existen ciertas limitaciones y puede apreciar que ciertas limitaciones se han eliminado.
C puede enseñarle a trabajar en entornos inseguros. En otras palabras, puede entrenarlo para vigilar su espalda cuando el idioma (cualquier idioma) no puede o no lo hará por usted, por cualquier motivo. Esto puede convertirlo en un mejor programador incluso en entornos seguros porque producirá menos errores por su cuenta y porque podrá desactivar la seguridad temporalmente para exprimir un poco de velocidad adicional de su programa seguro (por ejemplo, el uso de punteros en C #), en aquellos casos en que la seguridad conlleva un costo de tiempo de ejecución.
C puede enseñarle que cada objeto tiene requisitos de almacenamiento, un diseño de memoria, el hecho de que se puede acceder a la memoria a través de un espacio de direcciones finito, etc. Si bien otros idiomas no necesitan su atención en estos asuntos, hay algunos casos en los que cierta intuición adquirida puede ayudarlo a tomar decisiones más informadas.
C puede enseñarle los detalles de los enlaces y los archivos de objetos y otras complejidades a través de su sistema de compilación. Esto puede darle una comprensión práctica útil sobre cómo un programa compilado de forma nativa a menudo pasa del código fuente a la ejecución.
C puede inclinar su mente para pensar de maneras novedosas a través del concepto de comportamiento indefinido. El comportamiento indefinido es uno de mis conceptos favoritos en el desarrollo de software, porque el estudio de sus implicaciones en los compiladores no clásicos es un ejercicio mental único que no se puede obtener de otros idiomas. Sin embargo, deberá rechazar la prueba y error y comenzar a estudiar el idioma de manera cuidadosa y deliberada antes de poder apreciar completamente este aspecto.
Pero quizás la realización más importante que C puede otorgarle, al ser un lenguaje pequeño, es la idea de que toda la programación se reduce a datos y operaciones . Es posible que desee ver las cosas como clases modulares con jerarquías e interfaces con despacho virtual, o elegantes valores inmutables que se operan utilizando funciones matemáticas puras. Y eso está bien, pero C te recordará que todo es solo operaciones de datos + . Es una mentalidad útil porque le permite derribar bastantes barreras mentales.
La razón por la cual C es bueno para el aprendizaje no es que enseñe ningún principio . Te enseña cómo funcionan las cosas .
C se puede comparar con uno de esos buenos autos antiguos de los años 70 u 80, que fueron diseñados para conducir. Puede separarlos, tornillo por tornillo, y comprender cómo funciona cada parte y cómo funciona junto con las otras partes que puede tomar en sus manos para mirar. Una vez que comprende todas las partes, tiene una idea muy clara de cómo funciona todo.
Los lenguajes modernos son más como un automóvil moderno donde el motor es básicamente una caja negra, demasiado complejo para ser entendido por el propietario promedio del automóvil. Esos autos pueden hacer mucho, diablos, en estos días están aprendiendo activamente a conducir solos. Y con esa complejidad y comodidad, la interfaz de usuario se ha alejado mucho más de lo que realmente está sucediendo en el motor.
Cuando aprende a programar en C, entra en contacto con muchos de los tornillos y tuercas de los que está hecha una computadora. Esto le permite desarrollar una comprensión de la máquina misma. Por ejemplo, le permite comprender por qué no es una buena idea construir una cadena larga como esta:
java.lang.String result = "";
for(int i = 0; i < components.size; i++) {
result = result + components[i];
};
(Espero, esto es Java correcto, no lo he usado en mucho tiempo ...) De este ejemplo de código, no es obvio por qué el ciclo tiene complejidad cuadrática. Pero ese es el caso, y es la razón por la cual este código se detendrá cuando tenga unos pocos millones de componentes pequeños para concatenar. El experimentado programador de C sabe instantáneamente dónde está el problema, y probablemente evitará escribir dicho código en primer lugar.
for(int i = 0; i < strlen(s); i++)
en C, el ciclo también tendrá complejidad cuadrática, y es tan obvio como en su ejemplo de Java ;-)
Hay mejores lenguajes que C para aprender "los principios detrás de la programación", especialmente los principios teóricos, pero C puede ser bueno para aprender algunas cosas prácticas e importantes sobre la artesanía. La respuesta de greyfade es ciertamente correcta, pero en mi humilde opinión, hay más que puedes aprender de C que cómo administrar la memoria por ti mismo. Por ejemplo,
cómo crear programas con un completo manejo de errores en ausencia de excepciones
cómo crear estructura en un programa sin tener ningún soporte de lenguaje para la orientación a objetos
cómo manejar los datos en ausencia de estructuras de datos como listas dinámicas de tamaño considerable, diccionarios o una abstracción de cadena útil
cómo evitar errores comunes como desbordamientos de matriz incluso cuando el compilador o el entorno de tiempo de ejecución no le advierte automáticamente
cómo crear soluciones genéricas sin tener soporte de idiomas para plantillas o genéricos
y ¿mencioné que puede aprender a administrar la memoria usted mismo, por supuesto? ;-)
Además, al aprender C, aprenderá de dónde provienen los puntos en común sintácticos de C ++, Java, C #, Objective C.
En 2005, Joel Spolsky escribió una recomendación para aprender C antes que cualquier otro lenguaje de nivel superior. Sus argumentos son
"Nunca podrás crear código eficiente en idiomas de nivel superior".
"Nunca podrá trabajar en compiladores y sistemas operativos, que son algunos de los mejores trabajos de programación".
"Nunca se te confiará para crear arquitecturas para proyectos a gran escala"
"si no puede explicar por qué while(*s++ = *t++);
copia una cadena, o si eso no es lo más natural del mundo para usted, bueno, está programando en base a la superstición
Por supuesto, lo que escribió seguramente es discutible, pero en mi humilde opinión, muchos de sus argumentos siguen siendo válidos hoy.
Las dos abstracciones básicas de la informática son las máquinas de Turing y el cálculo de Lambda, y C es una forma de experimentar con la visión de la máquina de Turing de la computación: principalmente una sucesión de acciones de bajo nivel de las cuales surge un resultado deseable. Pero debe tener en cuenta que C viene con su propio modelo de cálculo. Por lo tanto, aprender C le enseñará los detalles de bajo nivel de la máquina abstracta C, que se está volviendo bastante diferente de las arquitecturas reales. Una de las primeras cosas que me enseñaron en C fue que nunca traté de burlarme del compilador aplicando trucos "inteligentes", y parece que la tendencia es hacia más y más optimizaciones en los compiladores. Al igual que en otros lenguajes de alto nivel, cuando escribes en C, los compiladores entienden lo que esperas que se haga en la máquina C abstracta y hacen que suceda en el hardware real,
Entonces, lo que quiero decir es que aprender C no necesariamente te dará una buena idea de lo que realmente sucede en el hardware. "C está cerca de la máquina" debe entenderse como "más cercano que la mayoría de los lenguajes de nivel superior". Aprender la arquitectura de software directamente será más gratificante si desea una imagen más precisa de "cómo funciona".
Por otro lado, aprender C puede familiarizarlo con la programación del sistema, los tipos de bajo nivel, los punteros y, en particular, la asignación de memoria. En cuanto a los algoritmos de aprendizaje y la estructura de datos, no existe la ventaja de aprenderlos en C en lugar de en otros lenguajes.
Es una pregunta muy abierta, no puede dar una respuesta concluyente. Puede aprender casi todo en todos los idiomas siempre que comprenda los aspectos internos del marco de idiomas. C te obliga a comprender detalles más bajos porque fue diseñado principalmente para escribir un sistema operativo. Incluso después de tantos años, sigue siendo uno de los lenguajes más utilizados principalmente gracias a los sistemas integrados y los proyectos de código abierto. Entonces, la pregunta es ¿qué quieres aprender? ¿Y en qué dominio?