Estoy considerando aprender C.
Pero, ¿por qué las personas usan C (o C ++) si se puede usar 'peligrosamente'?
Por peligroso, quiero decir con punteros y otras cosas similares.
Como la pregunta de desbordamiento de pila ¿ Por qué la función gets es tan peligrosa que no debería usarse? . ¿Por qué los programadores no solo usan Java o Python u otro lenguaje compilado como Visual Basic?
Respuestas:
C es anterior a muchos de los otros idiomas en los que está pensando. Mucho de lo que ahora sabemos sobre cómo hacer que la programación sea "más segura" proviene de la experiencia con lenguajes como C.
Muchos de los lenguajes más seguros que han surgido desde C dependen de un tiempo de ejecución mayor, un conjunto de características más complicado y / o una máquina virtual para lograr sus objetivos. Como resultado, C se ha mantenido como un "mínimo común denominador" entre todos los lenguajes populares / convencionales.
C es un lenguaje mucho más fácil de implementar porque es relativamente pequeño y tiene más probabilidades de funcionar adecuadamente incluso en el entorno más débil, por lo que es más probable que muchos sistemas integrados que necesitan desarrollar sus propios compiladores y otras herramientas puedan proporcionar un compilador funcional para C.
Debido a que C es tan pequeño y tan simple, otros lenguajes de programación tienden a comunicarse entre sí mediante una API tipo C. Esta es probablemente la razón principal por la que C nunca morirá realmente, incluso si la mayoría de nosotros solo interactuamos con él a través de envoltorios.
Muchos de los lenguajes "más seguros" que intentan mejorar en C y C ++ no intentan ser "lenguajes de sistemas" que le brinden un control casi total sobre el uso de memoria y el comportamiento de tiempo de ejecución de su programa. Si bien es cierto que cada vez más aplicaciones simplemente no necesitan ese nivel de control, siempre habrá un pequeño puñado de casos en los que sea necesario (especialmente dentro de las máquinas virtuales y los navegadores que implementan todos estos lenguajes agradables y seguros para el resto de nosotros).
Hoy en día, hay algunos lenguajes de programación de sistemas (Rust, Nim, D, ...) que son más seguros que C o C ++. Tienen los beneficios de la retrospectiva, y se dan cuenta de que la mayoría de las veces, no se necesita un control tan fino, por lo que ofrecen una interfaz generalmente segura con algunos ganchos / modos inseguros a los que uno puede cambiar cuando sea realmente necesario.
Incluso dentro de C, hemos aprendido muchas reglas y pautas que tienden a reducir drásticamente la cantidad de errores insidiosos que aparecen en la práctica. En general, es imposible obtener el estándar para hacer cumplir estas reglas retroactivamente porque eso rompería demasiado código existente, pero es común usar advertencias del compilador, linters y otras herramientas de análisis estático para detectar este tipo de problemas fácilmente prevenibles. El subconjunto de programas de C que pasan estas herramientas con gran éxito ya es mucho más seguro que "solo C", y cualquier programador de C competente en la actualidad utilizará algunos de ellos.
Además, nunca hará que un concurso de Java ofuscado sea tan entretenido como el concurso de C ofuscado .
fuente
Primero, C es un lenguaje de programación de sistemas. Entonces, por ejemplo, si escribe una máquina virtual Java o un intérprete de Python, necesitará un lenguaje de programación de sistemas para escribirlos.
En segundo lugar, C proporciona un rendimiento que los lenguajes como Java y Python no ofrecen. Por lo general, la informática de alto rendimiento en Java y Python utilizará bibliotecas escritas en un lenguaje de alto rendimiento como C para hacer el trabajo pesado.
Tercero, C tiene una huella mucho menor que lenguajes como Java y Python. Esto lo hace utilizable para sistemas integrados, que pueden no tener los recursos necesarios para soportar los grandes entornos de tiempo de ejecución y las demandas de memoria de lenguajes como Java y Python.
Un "lenguaje de programación de sistemas" es un lenguaje adecuado para construir sistemas de resistencia industrial con; tal como están, Java y Python no son lenguajes de programación de sistemas. "Exactamente lo que hace que un lenguaje de programación de sistemas" esté fuera del alcance de esta pregunta, pero un lenguaje de programación de sistemas necesita proporcionar soporte para trabajar con la plataforma subyacente.
Por otro lado (en respuesta a los comentarios), un lenguaje de programación de sistemas no necesita ser autohospedado. Este problema surgió porque la pregunta original se le preguntó "¿por qué la gente usa C", el primer comentario se le preguntó "¿Por qué necesitaría un lenguaje como C" cuando se tiene PyPy, y señaló que PyPy no en el hecho de utilizar C. Por lo tanto, originalmente era relevante para la pregunta, pero desafortunadamente (y de manera confusa) el "autohospedaje" en realidad no es relevante para esta respuesta. Lo siento, lo mencioné.
En resumen, Java y Python no son adecuados para la programación de sistemas no porque sus implementaciones principales se interpreten o porque las implementaciones compiladas de forma nativa no están autohospedadas, sino porque no brindan el soporte necesario para trabajar con la plataforma subyacente.
fuente
Lamento agregar otra respuesta, pero no creo que ninguna de las respuestas existentes aborde directamente su primera oración que indique:
¿Por qué? ¿Desea hacer el tipo de cosas que C se usa habitualmente en la actualidad (por ejemplo, controladores de dispositivos, máquinas virtuales, motores de juegos, bibliotecas de medios, sistemas integrados, núcleos del sistema operativo)?
En caso afirmativo, entonces sí, seguro aprende C o C ++ dependiendo de los que te interesen. ¿Quieres aprenderlo para tener una comprensión más profunda de lo que está haciendo tu lenguaje de alto nivel?
Luego continúas mencionando las preocupaciones de seguridad. No necesariamente necesita una comprensión profunda de C seguro para hacer esto último, de la misma manera que un ejemplo de código en un lenguaje de nivel superior podría darle la esencia sin estar listo para la producción.
Escriba un código C para obtener la esencia. Luego colóquelo nuevamente en el estante. No se preocupe demasiado por la seguridad a menos que quiera escribir el código C de producción .
fuente
Esta es una ENORME pregunta con toneladas de respuestas, pero la versión corta es que cada lenguaje de programación está especializado para diferentes situaciones. Por ejemplo, JavaScript para web, C para cosas de bajo nivel, C # para cualquier cosa de Windows, etc. Es útil saber lo que quiere hacer una vez que conoce la programación para decidir qué lenguaje de programación elegir.
Para abordar su último punto, por qué C / C ++ sobre Java / Python, a menudo se reduce a la velocidad. Hago juegos, y Java / C # recientemente está alcanzando velocidades que son lo suficientemente buenas para que los juegos se ejecuten. Después de todo, si quieres que tu juego se ejecute a 60 cuadros por segundo, y quieres que tu juego haga mucho (el renderizado es particularmente costoso), entonces necesitas que el código se ejecute lo más rápido posible. Python / Java / C # / Muchos otros se ejecutan en "intérpretes", una capa adicional de software que maneja todas las tareas tediosas que C / C ++ no hace, como administrar la memoria y la recolección de basura. Esa sobrecarga adicional ralentiza las cosas, por lo que casi todos los juegos grandes que ves se hicieron (en los últimos 10 años, de todos modos) en C o C ++. Hay excepciones: el motor del juego Unity usa C # * y Minecraft usa Java, pero son la excepción, no la regla. En general,
* Incluso Unity no es todo C #, grandes partes de él son C ++ y solo usas C # para tu código de juego.
EDITAR Para responder a algunos de los comentarios que aparecieron después de publicar esto: Tal vez estaba simplificando demasiado, solo estaba dando una imagen general. Con la programación, la respuesta nunca es simple. Hay intérpretes para C, Javascript puede ejecutarse fuera del navegador y C # puede ejecutarse en casi cualquier cosa gracias a Mono. Diferentes lenguajes de programación están especializados para diferentes dominios, pero algún programador en algún lugar probablemente descubrió cómo ejecutar cualquier lenguaje en cualquier contexto. Como el OP parecía no saber mucha programación (suposición de mi parte, perdón si me equivoco), estaba tratando de mantener mi respuesta simple.
En cuanto a los comentarios acerca de que C # es casi tan rápido como C ++, la palabra clave es casi. Cuando estaba en la universidad, visitamos muchas compañías de juegos, y mi maestro (que nos había estado alentando a alejarnos de C # y pasar a C ++ todo el año) preguntó a los programadores en cada compañía a las que acudíamos sobre por qué C ++ sobre C #, y cada una de ellas. dijo C # es demasiado lento. En general, se ejecuta rápidamente, pero el recolector de basura puede afectar el rendimiento porque no puede controlar cuándo se ejecuta, y tiene el derecho de ignorarlo si no desea ejecutarlo cuando lo recomienda. Si necesita que algo sea de alto rendimiento, no quiere algo tan impredecible como eso.
Para responder a mi comentario de "solo alcanzar velocidades", sí, gran parte de los aumentos de velocidad de C # provienen de un mejor hardware, pero a medida que el .NET framework y el compilador de C # han mejorado, ha habido algunas aceleraciones allí.
Sobre el comentario de "los juegos están escritos en el mismo idioma que el motor", depende. Algunos lo son, pero muchos están escritos en un híbrido de idiomas. Unreal puede hacer UnrealScript y C ++, Unity hace C # Javascript y Boo, muchos otros motores escritos en C o C ++ usan Python o Lua como lenguajes de script. No hay una respuesta simple allí.
Y solo porque me molestó leer "a quién le importa si tu juego se ejecuta a 200 fps o 120 fps", si tu juego se ejecuta a más de 60 fps, probablemente estés perdiendo el tiempo de la CPU, ya que el monitor promedio ni siquiera actualiza eso rápido. Algunos de gama alta y más nuevos lo hacen, pero no es estándar (todavía ...).
Y sobre el comentario de "ignorar décadas de tecnología", todavía estoy en mis primeros 20 años, así que cuando extrapolo hacia atrás, me hago eco de lo que me han dicho los programadores más viejos y más experimentados. Obviamente, eso se disputará en un sitio como este, pero vale la pena considerarlo.
fuente
Es curioso que afirmes que C es inseguro porque "tiene punteros". Lo contrario es cierto: Java y C # tienen prácticamente solo punteros (para tipos no nativos). El error más común en Java es probablemente la excepción de puntero nulo (cf. https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare ). El segundo error más común es probablemente tener referencias ocultas a objetos no utilizados (por ejemplo, los Diálogos cerrados no se eliminan) que, por lo tanto, no se pueden liberar, lo que lleva a programas de larga duración con una huella de memoria cada vez mayor.
Hay dos mecanismos básicos que hacen que C # y Java sean más seguros y más seguros de dos maneras diferentes:
Los recientes punteros inteligentes de C ++ hacen que ese trabajo sea más fácil para los programadores.
El tiempo de ejecución no protege, por ejemplo, contra intentos de desbordamiento del búfer, pero en teoría no permite explotaciones de dichos programas. Con C y C ++, por el contrario, el programador tiene que codificar de forma segura para evitar exploits. Esto generalmente no se logra de inmediato, pero necesita revisiones e iteraciones.
Sin embargo, vale la pena señalar que el tiempo de ejecución elaborado también es un riesgo de seguridad. Me parece que Oracle está actualizando la JVM cada dos semanas debido a problemas de seguridad recientemente descubiertos. Por supuesto, es mucho más difícil verificar la JVM que un solo programa.
La seguridad de un tiempo de ejecución elaborado es, por lo tanto, ambigua y hasta cierto punto engañosa: su programa de C promedio puede, con revisiones e iteraciones, hacerse razonablemente seguro. Su programa Java promedio es tan seguro como la JVM; es decir, en realidad no. Nunca.
El artículo sobre el
gets()
que se vincula refleja las decisiones históricas de la biblioteca que se tomarían de manera diferente hoy, no el lenguaje central.fuente
Como la "seguridad" cuesta velocidad, los idiomas "más seguros" funcionan a una velocidad más lenta.
Pregunta por qué usar un lenguaje "peligroso" como C o C ++, que alguien le escriba un controlador de video o similar en Python o Java, etc. y vea cómo se siente acerca de la "seguridad" :)
En serio, debes estar lo más cerca posible de la memoria central de la máquina para poder manipular píxeles, registros, etc. Java o Python no pueden hacer esto con ningún tipo de velocidad digna de rendimiento ... C y C ++ ambos le permite hacer esto a través de punteros y similares ...
fuente
Además de todo lo anterior, también hay un caso de uso bastante común, que utiliza C como una biblioteca común para otros lenguajes.
Básicamente, casi todos los idiomas tienen una interfaz API para C.
Ejemplo simple, intente crear una aplicación común para Linux / IOS / Android / Windows. Además de todas las herramientas que existen, lo que terminamos fue hacer una biblioteca central en C y luego cambiar la GUI para cada entorno, es decir:
Mis dos centavos,
fuente
Una dificultad fundamental con C es que el nombre se usa para describir varios dialectos con una sintaxis idéntica pero una semántica muy diferente. Algunos dialectos son mucho más seguros que otros.
En C, como fue diseñado originalmente por Dennis Ritchie, las declaraciones de C generalmente se asignarían a las instrucciones de la máquina de manera predecible. Debido a que C podía ejecutarse en procesadores que se comportaban de manera diferente cuando ocurrían cosas como el desbordamiento aritmético firmado, un programador que no sabía cómo se comportaría una máquina en caso de desbordamiento aritmético tampoco sabría qué código C se ejecuta en esa máquina, pero Si se sabe que una máquina se comporta de cierta manera (p. ej., envoltura silenciosa del complemento a dos), las implementaciones en esa máquina normalmente harían lo mismo. Una de las razones por las que C se ganó la reputación de ser rápido fue que, en los casos en que los programadores sabían que el comportamiento natural de una plataforma en escenarios extremos se ajustaba a sus necesidades, no era necesario que el programador o el compilador escribieran código para generar tales escenarios. .
Desafortunadamente, los escritores de compiladores han opinado que, dado que el Estándar no impone requisitos sobre lo que las implementaciones deben hacer en tales casos (laxitud que estaba destinada a permitir implementaciones de hardware que podrían no comportarse de manera predecible), los compiladores deben sentirse libres de generar código que niegue las leyes de tiempo y causalidad.
Considera algo como:
La teoría del compilador hipermoderno (pero de moda) sugeriría que el compilador debería mostrar "¡QUACK!" incondicionalmente, dado que en cualquier caso donde la condición era falsa, el programa terminaría invocando un comportamiento indefinido que realizaba una multiplicación cuyo resultado sería ignorado de todos modos. Dado que el estándar permitiría a un compilador hacer lo que quiera en ese caso, le permite al compilador generar "QUACK!".
Si bien C solía ser más seguro que el lenguaje ensamblador, cuando se usan compiladores hipermodernos, lo contrario es cierto. En lenguaje ensamblador, el desbordamiento de enteros puede hacer que un cálculo produzca resultados sin sentido, pero en la mayoría de las plataformas será el alcance de sus efectos. Si los resultados terminan siendo ignorados de todos modos, el desbordamiento no importará. Sin embargo, en C hipermoderna, incluso lo que normalmente serían formas "benignas" de Comportamiento indefinido (como un desbordamiento de enteros en un cálculo que termina siendo ignorado) puede causar la ejecución arbitraria del programa.
fuente
int arr[5][[5]
, por ejemplo , un intento de accesoarr[0][5]
generará un Comportamiento indefinido. Dicha regla hace posible que un compilador al que se le dé algo comoarr[1][0]=3; arr[0][i]=6; arr[1][0]++;
inferirarr[1][0]
sea igual a 4, sin tener en cuenta el valor dei
.Razones históricas. No suelo escribir código nuevo, principalmente mantengo y extiendo las cosas viejas que han estado funcionando durante décadas. Estoy feliz de que sea C y no Fortran.
Puedo irritarme cuando un estudiante dice: "¿pero por qué haces esta horrible X cuando podrías estar haciendo Y?". Bueno, X es el trabajo que tengo y paga las facturas muy bien. He hecho Y en ocasiones, y fue divertido, pero X es lo que la mayoría de nosotros hacemos.
fuente
¿Qué es "peligroso"?
La afirmación de que C es "peligroso" es un tema de conversación frecuente en las guerras de la llama del lenguaje (con mayor frecuencia en comparación con Java). Sin embargo, la evidencia de esta afirmación no está clara.
C es un lenguaje con un conjunto particular de características. Algunas de estas características pueden permitir ciertos tipos de errores que no están permitidos por otros tipos de lenguajes (el riesgo de la administración de memoria de C generalmente se resalta). Sin embargo, esto no es lo mismo que un argumento de que C es más peligroso que otros lenguajes en general . No conozco a nadie que proporcione evidencia convincente sobre este punto.
Además, "peligroso" depende del contexto: ¿qué está tratando de hacer y qué tipo de riesgos le preocupan?
En muchos contextos, consideraría que C es más "peligroso" que un lenguaje de alto nivel, ya que requiere una implementación más manual de la funcionalidad básica, lo que aumenta el riesgo de errores. Por ejemplo, hacer un procesamiento de texto básico o desarrollar un sitio web en C generalmente sería tonto, porque otros lenguajes tienen características que lo hacen mucho más fácil.
Sin embargo, C y C ++ se usan ampliamente para sistemas de misión crítica, porque un lenguaje más pequeño con un control más directo de hardward se considera "más seguro" en ese contexto. De una muy buena respuesta de desbordamiento de pila :
fuente
Para agregar a las respuestas existentes, está muy bien decir que va a elegir Python o PHP para su proyecto, debido a su relativa seguridad. Pero alguien tiene que implementar esos lenguajes y, cuando lo hagan, probablemente lo harán en C. (O, bueno, algo así).
Por eso es que la gente usa C - para crear las herramientas menos peligrosos que se desea utilizar.
fuente
Permíteme reformular tu pregunta:
Cualquier herramienta interesante se puede usar peligrosamente, incluidos los lenguajes de programación. Usted aprenderá más para que pueda hacer más (y por lo menos peligro de que se crea cuando se utiliza la herramienta). En particular, aprende la herramienta para que pueda hacer lo que esa herramienta es buena (y tal vez reconocer cuándo esa herramienta es la mejor herramienta de las herramientas que conoce).
Por ejemplo, si necesita colocar un agujero cilíndrico de 6 mm de diámetro y 5 cm de profundidad en un bloque de madera, un taladro es una herramienta mucho mejor que un analizador LALR. Si sabe cuáles son estas dos herramientas, sabe cuál es la herramienta correcta. Si ya sabes cómo usar un taladro, ¡voila !, hoyo.
C es solo otra herramienta. Es mejor para algunas tareas que para otras. Las otras respuestas aquí abordan esto. Si aprende algo de C, reconocerá cuándo es la herramienta correcta y cuándo no.
fuente
No hay una razón específica para no aprender C, pero sugeriría C ++. Ofrece mucho de lo que hace C (ya que C ++ es un súper conjunto de C), con una gran cantidad de "extras". Aprender C antes que C ++ es innecesario: son efectivamente lenguajes separados.
Dicho de otra manera, si C fuera un conjunto de herramientas para trabajar la madera, probablemente sería:
Puede construir cualquier cosa con estas herramientas, pero cualquier cosa agradable requiere potencialmente mucho tiempo y habilidad.
C ++ es la colección de herramientas eléctricas en su ferretería local.
Si se apega a las características básicas del lenguaje para comenzar, C ++ tiene relativamente poca curva de aprendizaje adicional.
Porque algunas personas no quieren muebles de IKEA. =)
En serio, aunque muchos lenguajes que son "superiores" a C o C ++ pueden tener cosas que los hacen (potencialmente) "más fáciles" de usar en ciertos aspectos, esto no siempre es algo bueno. Si no le gusta la forma en que se hace algo o no se proporciona una función, es probable que no haya mucho que pueda hacer al respecto. Por otro lado, C y C ++ proporcionan suficientes características de lenguaje de "bajo nivel" (incluidos punteros) para que pueda acceder a muchas cosas de manera bastante directa (especialmente hardware o sistema operativo) o construirlo usted mismo, lo que puede no ser posible en otros idiomas implementados.
Más específicamente, C tiene el siguiente conjunto de características que lo hacen deseable para muchos programadores:
Compatibilidad : C ha existido durante mucho tiempo y todos tienen herramientas y bibliotecas para ello. El lenguaje en sí tampoco es exigente: espera que un procesador ejecute instrucciones y memoria para guardar cosas y eso es todo.
Además, hay algo conocido como una interfaz binaria de aplicación (ABI) . En resumen, es una forma para que los programas se comuniquen a nivel de código de máquina, lo que puede tener ventajas sobre una interfaz de programación de aplicaciones (API) . Si bien otros lenguajes como C ++ pueden tener una ABI, generalmente son menos uniformes (acordados) que los C, por lo que C es un buen lenguaje básico cuando desea utilizar una ABI para comunicarse con otro programa por alguna razón.
Eficiencia (y ocasionalmente esquemas de administración de memoria que no pueden implementarse sin un acceso relativamente directo a la memoria).
El acceso directo a la memoria con punteros presenta muchos trucos ingeniosos (generalmente rápidos) cuando puede poner sus patas sucias en los pequeños y ceros en sus cubículos de memoria directamente y no tener que esperar a que ese viejo maestro entregue los juguetes solo a la hora de jugar y luego recogerlos de nuevo.
En resumen, agregar cosas potencialmente crea un retraso o, de lo contrario, introduce una complejidad no deseada.
Con respecto a los lenguajes con secuencias de comandos y cosas por el estilo, debe trabajar duro para obtener los lenguajes que requieren que los programas secundarios se ejecuten de manera tan eficiente como C (o cualquier lenguaje compilado) de forma nativa. Agregar un intérprete sobre la marcha introduce inherentemente la posibilidad de disminuir la velocidad de ejecución y aumentar el uso de memoria porque está agregando otro programa a la mezcla. La eficiencia de sus programas depende tanto de la eficiencia de este programa secundario como de qué tan bien (mal =) escribió su código de programa original. Sin mencionar que su programa a menudo depende completamente del segundo programa para ejecutarse. ¿Ese segundo programa no existe por alguna razón en un sistema en particular? Código no ir.
De hecho, la introducción de algo "extra" potencialmente ralentiza o complica su código. En los lenguajes "sin punteros de miedo", siempre está esperando que otros fragmentos de código se limpien detrás de usted o que de otra manera descubra formas "seguras" de hacer las cosas, porque su programa todavía está haciendo las mismas operaciones de acceso a la memoria que se podrían hacer con punteros Simplemente no eres el que lo maneja (por lo que no puedes joderlo, genio = P).
Por la respuesta aceptada:
La idea de que, debido a que algo se puede hacer en un idioma, debe hacerse es una tontería. Los idiomas tienen fallas que se arreglan. Por razones de compatibilidad con el código anterior, esta construcción aún se puede utilizar. Pero no hay nada (probable) que obligue a un programador a usar gets () y, de hecho, este comando fue esencialmente reemplazado por alternativas más seguras.
Más aún, el problema con gets () no es un problema de puntero per se. Es un problema con un comando que no necesariamente sabe cómo usar la memoria de manera segura. En un sentido abstracto, se trata de cuestiones de puntero: leer y escribir cosas que no debes. Eso no es un problema con los punteros; Es un problema con la implementación del puntero.
Para aclarar, los punteros no son peligrosos hasta que accidentalmente acceda a una ubicación de memoria que no tenía intención de hacer. Y aun así, eso no garantiza que su computadora se derrita o explote. En la mayoría de los casos, su programa dejará de funcionar (correctamente).
Dicho esto, debido a que los punteros brindan acceso a ubicaciones de memoria y a que los datos y el código ejecutable existen en la memoria juntos, existe un peligro real de corrupción accidental como para que desee administrar la memoria correctamente.
Hasta ese punto, debido a que las operaciones de acceso directo a la memoria a menudo brindan menos beneficios en general de lo que podrían haber sido hace años, incluso los lenguajes no recolectados como C ++ han introducido cosas como punteros inteligentes para ayudar a cerrar la brecha entre la eficiencia y la seguridad de la memoria.
En resumen, hay muy pocas razones para temer al puntero siempre que se use de manera segura. Solo tome una pista de la versión de South Park de Steve "El cazador de cocodrilos" Irwin: no ande metiendo el pulgar en los huecos de los cocodrilos .
fuente
Como siempre, el lenguaje de programación es solo una consecuencia de la resolución de problemas. De hecho, debe aprender no solo C sino muchos lenguajes diferentes (y otras formas de programar una computadora, ya sean herramientas GUI o intérpretes de comandos) para tener una caja de herramientas decente para usar al resolver problemas.
A veces encontrará que un problema se presta bien a algo que está incluido en las bibliotecas predeterminadas de Java, en tal caso, puede elegir Java para aprovechar eso. En otros casos, puede ser que necesite hacer algo en Windows que sea mucho más simple en el tiempo de ejecución de .NET, por lo que puede usar C # o VB. Podría haber una herramienta gráfica o un script de comando que resuelva su problema, luego puede usarlos. Tal vez necesite escribir una aplicación GUI en múltiples plataformas, Java podría ser una opción, dadas las bibliotecas incluidas en el JDK, pero una vez más, una plataforma de destino puede carecer de un JRE, por lo que tal vez elija C y SDL (o similar).
C tiene una posición importante en este conjunto de herramientas, ya que es general, pequeño y rápido y también se compila en código de máquina. También es compatible en todas las plataformas bajo el sol (sin embargo, no sin recompilar).
La conclusión es que debe aprender tantas herramientas, lenguajes y paradigmas como sea posible.
Aléjese de la mentalidad: "Soy un programador X" (X = C, C ++, Java, etc.)
Solo usa "Soy programador".
Un programador resuelve problemas y diseña algoritmos instruyendo a las máquinas para que realicen la carga de trabajo. Fin de la historia. Esto es irrelevante para el lenguaje. Su habilidad más importante es la resolución de problemas y el desglose lógico de problemas estructurados, la habilidad / elección del lenguaje es SIEMPRE secundaria y / o una consecuencia de la naturaleza del problema.
Un camino interesante si está interesado en C es ampliar su conjunto de habilidades con Go. Go es realmente una C mejorada, con recolección de basura e interfaces, así como un buen modelo / canales integrados de subprocesos, que también brindan muchos de los beneficios de C (como la aritmética de punteros y la compilación de código de máquina).
fuente
Depende de lo que pretendas hacer con él. C fue diseñado como un reemplazo para el lenguaje ensamblador y es el lenguaje de alto nivel más cercano al lenguaje máquina. Por lo tanto, tiene unos gastos generales bajos en tamaño y rendimiento, y es adecuado para la programación de sistemas y otras tareas que requieren una pequeña huella y se acercan al hardware subyacente.
fuente
Cuando trabaja a nivel de bits y bytes, de memoria como una recopilación de datos homogénea sin procesar, como a menudo se requeriría para implementar de manera efectiva los asignadores y las estructuras de datos más eficientes, no hay seguridad. La seguridad es predominantemente un concepto fuerte relacionado con el tipo de datos, y un asignador de memoria no funciona con los tipos de datos. Funciona con bits y bytes para agruparse con esos mismos bits y bytes que representan potencialmente un tipo de datos en un momento y otro más adelante.
No importa si usa C ++ en ese caso. Todavía estaría rociando
static_casts
todo el código para emitir desdevoid*
punteros y aún trabajando con bits y bytes y solo lidiando con más problemas relacionados con el respeto del sistema de tipos en este contexto que C, que tiene un sistema de tipos mucho más simple donde eres libre amemcpy
bits y bytes sin preocuparse por demoler el sistema de tipos.De hecho, a menudo es más difícil trabajar en C ++, un lenguaje más seguro en general, en contextos de bits y bytes de tan bajo nivel sin escribir un código aún más peligroso que en C, ya que podría estar arrasando sobre el sistema de tipos de C ++ y haciendo cosas como sobrescribir vptrs y no invocar constructores de copia y destructores en los momentos apropiados. Si se toma el tiempo adecuado para respetar estos tipos y utiliza la ubicación nueva e invoca manualmente a los dtors, etc., se expondrá al mundo del manejo de excepciones en un contexto de nivel demasiado bajo para que RAII sea práctico y logre excepciones. La seguridad en un contexto de tan bajo nivel es muy difícil (tiene que fingir que casi cualquier función puede lanzar y capturar todas las posibilidades y revertir cualquier efecto secundario como una transacción indivisible como si nada sucediera). El código C a menudo puede "
Y sería imposible implementar tales asignadores en idiomas que no le permitan ser "peligrosos" aquí; tendría que apoyarse en los asignadores que proporcionan (implementados muy probablemente en C o C ++) y esperar que sea lo suficientemente bueno para sus propósitos. Y casi siempre hay asignadores y estructuras de datos más eficientes pero menos generales adecuados para sus propósitos específicos pero mucho más estrictamente aplicables ya que están diseñados específicamente para sus propósitos.
La mayoría de las personas no necesitan los gustos de C o C ++, ya que solo pueden llamar al código implementado originalmente en C o C ++ o posiblemente incluso en un ensamblaje ya implementado para ellos. Muchos podrían beneficiarse de innovar a alto nivel, como unir un programa de imágenes que solo usa bibliotecas de funciones de procesamiento de imágenes existentes ya implementadas en C, donde no están innovando tanto en el nivel más bajo de bucle a través de píxeles individuales, pero tal vez ofreciendo una interfaz de usuario muy amigable y un flujo de trabajo nunca antes visto. En ese caso, si el objetivo del software es simplemente hacer llamadas de alto nivel en bibliotecas de bajo nivel ( "procesar esta imagen completa para mí, no para cada píxel, hacer algo" ), podría decirse que podría ser una optimización prematura incluso intentar comenzar a escribir dicha aplicación en C.
Pero si está haciendo algo nuevo en el nivel bajo donde ayuda a acceder a los datos de un nivel bajo como un filtro de imagen nuevo nunca antes visto que sea lo suficientemente rápido como para trabajar en video HD en tiempo real, entonces generalmente debe obtener Un poco peligroso.
Es fácil dar esto por sentado. Recuerdo una publicación de Facebook con alguien señalando cómo es factible crear un videojuego 3D con Python con la implicación de que los lenguajes de bajo nivel se están volviendo obsoletos, y ciertamente era un juego de aspecto decente. Pero Python estaba haciendo llamadas de alto nivel a bibliotecas implementadas en C para hacer todo el trabajo pesado. No puede hacer Unreal Engine 4 simplemente haciendo llamadas de alto nivel a las bibliotecas existentes. Unreal Engine 4 esla biblioteca. Hizo todo tipo de cosas que nunca existieron en otras bibliotecas y motores, desde la iluminación hasta su sistema de planos nodales y cómo puede compilar y ejecutar código sobre la marcha. Si desea innovar en el tipo de bajo nivel de motor / núcleo / núcleo, entonces debe obtener un nivel bajo. Si todos los desarrolladores de juegos cambiaran a idiomas seguros de alto nivel, no habría Unreal Engine 5, 6 o 7. Es probable que las personas sigan usando Unreal Engine 4 décadas después porque no se puede innovar en el nivel requerido para llegar con un motor de próxima generación simplemente haciendo llamadas de alto nivel al viejo.
fuente