¿Qué principios se aprenden de C que no se pueden aprender en lenguajes de nivel superior? [cerrado]


11

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?


2
Aprendes la magia, o algo de ella, de todos modos. Como C está "más cerca del metal", aprendes más sobre el metal.
Robert Harvey

1
Nunca entendí completamente el concepto de referencia hasta que encontré C ++.
user6245072

66
C le enseñará qué es realmente un desbordamiento de pila. El camino difícil.
david25272

1
Deseo que los nuevos programadores comiencen por aprender la buena programación Pascal y estructurada. Aprendes a expresarte lógicamente y estructurado.
Doblado

2
Algo que solo C y C ++ te enseñan es que el compilador es tu peor enemigo.
CodesInChaos

Respuestas:


9

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.


66
Nunca he entendido por qué la gente siempre menciona la integridad de Turing en este tipo de discusiones. La integridad de Turing no tiene sentido en este contexto; C no es diferente de otros lenguajes de programación en ese sentido, por lo que no hay nada que aprender sobre la integridad de Turing al cambiar a C. La única vez que la integridad de Turing se vuelve relevante es cuando se discute algo que no es completo de Turing, como CSS o HTML . Demonios, si entrecierras los ojos lo suficiente, incluso esos son completos de Turing . Las preguntas más significativas se centran en la usabilidad.
Robert Harvey

3
@RobertHarvey Mi punto es que mientras un lenguaje tenga un mínimo razonable de capacidad computacional, su "nivel" se vuelve irrelevante desde el punto de vista de los algoritmos, que son las únicas cosas que importan en este contexto.
greyfade

3
Porque estás haciendo un punto que es completamente intrascendente para la pregunta del OP. Los programadores hacen esto todo el tiempo; lanzan la frase "Turing-complete" como si realmente tuviera un uso significativo en términos prácticos. No lo hace, excepto para señalar que no importa.
Robert Harvey

2
<irony> La biología es solo un caso especial de la química, que es un caso especial de la física de partículas. No hay nada que puedas aprender de la biología si conoces la física de partículas. ¿No? </irony>
Florian F

3
Vale la pena señalar que C simplemente requiere que haga explícitas las asignaciones y desasignaciones, pero aún se refieren a una máquina abstracta, al igual que en los lenguajes de "nivel superior": la máquina física (por ejemplo) x86 todavía está fuera del alcance de C. One puede hacer una máquina virtual perfectamente protegida que interpreta el código C pero no tiene control sobre las asignaciones de memoria de la máquina física y aún puede ser una implementación 100% conforme.
Theodoros Chatzigiannakis

13

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.


12
C está bien para crear abstracciones. Puede escribir métodos en C, y puede empaquetar datos como estructuras en C. Se han construido sistemas operativos completos usando C. Lo que C no es bueno es satisfacer la idea "moderna" de todos de qué se supone que debe verse la orientación a objetos me gusta.
Robert Harvey

44
No exactamente. C es un nivel bastante más alto que ASM. Simplemente no esperes usar clases en él, aunque hay formas de hacerlo , si estás dispuesto.
Robert Harvey

44
Sustituya "Brainfuck" por "ensamblador" en su comentario, y aún debería ser cierto. Pero eso no significa que vaya a usar Brainfuck pronto.
Robert Harvey

66
Su argumento sobre las características de C realmente solo tiene mérito si cree que las clases (y la recolección de basura, etc.) son un elemento necesario para enseñar a un nuevo programador (que yo no). Nadie aquí está abogando por tratar de usar las clases en un lenguaje sin clases.
Robert Harvey

55
@Robert, mi argumento es que C es un lenguaje de nivel inferior y, como tal, no es el mejor lenguaje para comprender los principios de programación, lo que también podemos decir sobre ensamblador, y el hecho de que sean lenguajes de nivel inferior no significa de alguna manera están más cerca de los "verdaderos" principios de programación. Estos lenguajes son mejores para comprender cómo funcionan el hardware y los sistemas operativos, y si ese es el interés, recomiendo saltar directamente al nivel más bajo, en el aprendizaje de la arquitectura del conjunto de instrucciones y el lenguaje de máquina. De lo contrario, hay muchos idiomas para elegir.
Erik Eidt

8

C y la máquina (abstracta)

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).

¿Cómo qué se aprende? ¿Y cómo se aprende?

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

  • Hay quienes dirían que puede aprender mejor un concepto trabajando en un entorno que lo ofrezca y lo aliente, a menudo de múltiples maneras.
  • Hay quienes dirían que puede aprender mejor un concepto trabajando en un entorno que no lo ofrece y en el que tiene que construirlo usted mismo.

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.

Exclusivamente en C

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.


5

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.


Concuerdo completamente. C le enseñará mucho sobre cómo funcionan las cosas, lo que ayuda en gran medida a comprender a) por qué se escribieron los lenguajes de nivel superior (por ejemplo, lo que significaban abstraer), yb) cómo funcionan esos lenguajes de nivel superior detrás de escena, que seguro de tener un buen conocimiento. No enseñará principios y puede que no sea tan fácil, pero como resultado, obtendrá un respeto por él, las computadoras y una comprensión más profunda de los idiomas de nivel superior. Lea también Back to Basic de Joel Spolsky: joelonsoftware.com/articles/fog0000000319.html
jleach

1
Su respuesta seguramente está bien, pero si escribe 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 ;-)
Doc Brown

No estoy seguro, pero confiaría en el compilador de Java para optimizar esto :-)
Bruno Schäpper

El experimentado programador de Java también sabe instantáneamente dónde está el problema, y ​​probablemente evitará escribir dicho código en primer lugar. Este problema específico se discute en tutoriales elementales de Java. Así que esto ciertamente no es algo que se pueda aprender de C pero no de Java.
Peter Taylor

@PeterTaylor Si tiene un instructor de Java que conoce su C, sí. Pero dudo que este tipo de conocimiento se mantenga una vez que las personas que conocen C estén muertas. Para el programador C, es la definición misma de lo que es una cadena C, lo que les dice que mi ejemplo de código no puede ser eficiente. Para el programador de Java, es un conocimiento profundo, arcano y poco usado sobre las abstracciones que usan, lo que les dice que eviten este tipo de código. Ok, estoy exagerando un poco aquí, pero te haces una idea: el programador C debe saberlo, el programador Java puede salirse con la suya sin saberlo.
cmaster - reinstalar a monica el

2

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.


1
C es un muy buen lenguaje para aprender antes de aprender esas "cosas de nivel superior que crees que C no admite", porque te ayuda a comprender cómo funcionan realmente esas cosas (y lo caras que son).
Brendan

@Brendan: No estoy seguro si la intención de su comentario es expresar un acuerdo, un desacuerdo o simplemente una nota al margen de mi respuesta.
Doc Brown

Los programas C escritos por profesionales se lanzan con desbordamientos de memoria intermedia y bloqueos duros. Entonces, si bien un programador disciplinado puede elegir aprender estas cosas , el lenguaje C no enseña inherentemente simplemente por el hecho de estar empobrecido. Hay muchas formas malas (y lo que es peor, mezclar múltiples formas inconsistentes) para manejar errores sin excepciones y crear estructuras sin objetos, por ejemplo.
Erik Eidt

@ErikEidt: de hecho, pero especialmente en la ecosfera C existen muchos libros, tutoriales y otro material que tratará estos temas. Por ejemplo, "Writing Solid Code" de Steve Maguire. Por supuesto, si alguien elige la primera edición de K&R para aprender la sintaxis del idioma, probablemente no se convertirá en un mejor programador.
Doc Brown

1

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.


1
Entonces, ¿qué puede enseñarte C que los lenguajes de nivel superior no pueden?
Philip Kendall

2
Creo que la respuesta implícita es: " Nada , al menos no las cosas que los proponentes suelen reclamar". Así es como entiendo la respuesta de todos modos.
Jörg W Mittag

-3

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?

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.