Los punteros y la POO (o por qué hay que aprender C)

Quizá un título más apropiado sería ¿qué hace falta para ser un buen programador? 

En el blog de Eugenio Estrada hay un post muy interesante, sobre todo por los comentarios que ha generado. Entre esos comentarios hay opiniones enfrentadas sobre un tema que últimamente levanta ampollas. Si todo el mundo está programando utilizando orientación a objetos, ¿por qué debería la gente aprender C – o Pascal – si luego no lo va a utilizar?

Creo que aprender C (a partir de ahora, cada vez que hable de C, hablo realmente de un lenguaje en el que se puedan utlizar punteros, y que sea estructurado, como puede ser también Pascal) es algo muy necesario para luego entrar de lleno en la orientación a objetos. Y Joel Spolsky también piensa así 😉

El artículo de Joel Spolsky trata acerca de lo que él busca cuando entrevista a gente para formar parte de su plantilla. Es decir, cuenta un poco qué es lo que hace falta para ser un buen desarrollador (según su opinión, que se acerca bastante a la mía). Y para ser un buen desarrollador, sólo hacen falta dos cosas, que son las que busca:

  • Ser inteligente, y
  • Terminar las cosas que se empiezan

Para ayudarle a comprobar el primer punto, en sus entrevistas normalmente suele pedir a los entrevistados que utilizando papel y lápiz hagan un pequeño programa en C con algún algoritmo que requiera el uso de punteros, o de recursión. Y voy a intentar traducir de su artículo el por qué hace eso:

>>15 años de experiencia entrevistando programadores me han convencido de que los mejores programadores tienen una aptitud para manejar varios niveles de abstracción simultáneamente. En programación, esto quiere decir que no tienen problemas con la recursión (en la que tienen que mantener en la cabeza varios niveles de la pila de llamadas a la vez), o en implementar algoritmos complejos basados en punteros (donde la dirección de un objeto es una especie de representación abstracta del objeto).

>>Me he dado cuenta de que entender punteros en C no es una habilidad, sino una aptitud. En el primer año de universidad suele haber unos 200 chavales al principio del semestre, y todos ellos escribieron juegos de aventuras complejos en BASIC para sus PCs cuando tenían 4 años. Pasan un rato divertido aprendiendo C o Pascal en la universidad, hasta que un día el profesor explica los punteros, y de repente no lo entienden. Ya no entienden nada a partir de ese punto. El 90% de los alumnos dejan la clase y se convierten en licenciados en Política, y luego les cuentan a sus amigos que no había los suficientes miembros del sexo apropiado que estuvieran cañón en sus clases de Programación (recordad que la Uni en los USA es diferente, los primeros años son comunes a las especialidades), y que por eso cambiaron de especialidad. Por alguna razón, la mayoría de la gente parece ser que nace sin la parte del cerebro que entiende los punteros. Los punteros requieren una forma compleja de pensar usando una indirección doble que ciertas personas simplemente no pueden hacer, y esa forma de pensar es crucial para poder hacer una programación buena. Muchos de los "script jocks" (no sé cómo traducir esto) empezaron a programar copiando código JavaScript en sus páginas web, y luego aprendieron Perl sin haber aprendido punteros, y no son capaces de producir código con la calidad que necesitas.

Después de leer este artículo (en una versión más antigua), empecé a aplicar esa pequeña prueba en las entrevistas técnicas que tenía que hacer en la empresa en la que trabajaba. Normalmente les pedía a los candidatos que implementasen una función (o un método, ya que yo les dejaba elegir el lenguaje que querían utilizar) que diese la vuelta a una lista enlazada.

  • Muchos de los candidatos (con algún año de experiencia a sus espaldas) se lanzaban a escribir el código directamente, sin ni siquiera hacer un pequeño esquema con la lista enlazada, para hacerse una idea de este puntero que va aquí tiene que ir allí, etc. – picar sin pensar? malo, malo… 
  • Otros directamente no sabían lo que era una lista enlazada, y cuando se lo explicabas, se quedaban perplejos (en ese momento me preguntaba en qué universidad habían estudiado, y si las horas de estructuras de datos las pasaba fumando canutos o jugando al mus).
  • Pero una de las cosas que pude ver es que la mayoría de la gente que elegía hacerlo en Java, VB.NET o C# tenía un serio problema con los constructores de los objetos. Se liaban a rellenar objetos y enlazarlos entre sí. La mayoría de las veces estaban rellenando el mismo objeto una y otra vez, enlazándolo consigo mismo. No eran capaces de entender que lo que manejaban son referencias a objetos.

Sólo uno de los que decidió utilizar C# me sorprendió poniendo: return list.Reverse(); Qué crack 😉 

Un ejemplo de lo que se podría hacer sabiendo utilizar punteros (desde C# y sin usar código unsafe) se puede ver en los comentarios de este artículo de CodeProject.

Hay otra razón de peso para aprender a programar en C antes que en .NET (y ahora hablo únicamente de C). .NET al final es un wrapper construido sobre una API (sea Win32, o sobre las librerías estándar de C en el proyecto Mono). Ese wrapper puede tener bugs (y alguno tiene). Y cuando algo no funciona como es debido en ese wrapper, si no tienes los recursos suficientes para implementar una solución alternativa, lo llevas claro (bueno, más bien oscuro). Interop te puede ayudar, pero no hace milagros. Y si has programado en C para Win32, puedes saber por ejemplo lo que es el bucle de mensajes, y trastear con el WndProc de los controles de .NET. Sí, es raro, y puede que no te vaya a hacer falta… Pero si lo sabes, lo puedes utilizar. Si no… Pues no.

Algunas otras razones hay, como por ejemplo el tener presente siempre la utilización de los recursos (como en C tienes que pedirlos y liberarlos explícitamente, eso siempre ayuda), ya que ciertos recursos son limitados (conexiones a la base de datos, objetos de GDI…) y el no liberarlos correctamente puede hacer que una aplicación se arrastre, o directamente no funcione.

Y si nos vamos a los extremos… Al final el ordenador lo que hace es mover memoria de aquí para allá… 😛

Por último, si quieres ser un buen desarrollador… (esto me fastidia, pero es así) hay que saber inglés. Y muy bien. Aunque gracias a Geeks cada vez hará menos falta.

En fin… ¿Qué opináis vosotros sobre este tema?

26 comentarios en “Los punteros y la POO (o por qué hay que aprender C)”

  1. Estoy de acuerdo, creo que la manipulación de punteros y su comprensión completa, no sólo ayuda al programador sino es el primer paso en la comprensión de cualquier ordenador en sí.

    Muchas veces ese conocimiento nos permite detectar fallos de forma preventiva y otras poder entender salidas de resultados de forma ininteligibles para el ojo inexperto.

    Aunque estemos en el año 2006, comprender y analizar el significado de un trozo de código que contenga referencias (punteros) considero que es fundamental para alguién cuya meta sea la de programar algo más que no sea en Java y que tenga alguna trascendencia en el tiempo..

  2. Holas!

    Para un puesto de desarrollador, pienso que es un buen filtro.

    Y si no aprendieron a manejar C/C++ en la Universidad, daría mucho que decir, para empezar que ante cosas dífiles simplementa lo hacen por hacer, no le ponen pasión, o no le encuentran pasión.

    Y creo que al final con este post, algunos aprenderán porque los evaluarán a la hora de postular un trabajo, lo ideal es que despierte el interés en ser abstractos para programar. Dominar el código :).

    Saludos,

  3. Al menos en mi caso tiene toda la razón. Yo empecé por mi cuenta a aprender a programar en Pascal y C. Hacía algunas cosillas, pero la llegar a la historia esa de los punteros, algo me fallaba y ya cuando llegados a la POO sencillamente, me perdí. Una lástima, la informática se ha perdido un genio. ;b

  4. saber punteros es la base de todo buen programador, quien no sabe este tema diría que realmente no sabe de programación.

    muchas veces usamos punteros y no sabemos que lo estamos usando, alli viene el fundamento del por qué de las cosas…

    hay que programar por pasión y con amor, sino no tiene sentido pelarse más…

  5. Es cierto, la única forma de entender qu hace realmente un lenguaje es saber sobre punteros, en una oportunidad trabaje en un proyecto en .NET donde la API base para comunicarnos a SAP (o por lo menos como lo queríamos hacer) estaba en C ANSI y buenos golpes nos dimos hasta descubir la estructura d memoria que se necesitaba crear, eran structs de structs y punteros por doquier, no sabrás los golpes al inicio q dimos hasta que me acostumbre a punteros otra vez, tanot que cuando volvía al código C# ya pensaba en q alocacion estará haciendo esto, porque mejor hago el objeto así, así bajo la cantidad de bytes alocados, y etc…
    Fue muy aleccionador esa experiencia

  6. Pues yo voy a romper una lanza en favor de los que en absoluto pensamos que C (y mucho menos C++) sea indispensable para ser un BUEN programador. Posiblemente sí sea necesario si quieres ser un GURU, un DIOS… vamos, el Chuck Norris de la programación. Pero vamos, que para el común de los mortales (los que por suerte o por desgracia nos dedicamos a hacer “aburridas” aplicaciones de gestión, y no a desarrollar juegos u otros tipos de programas -léase tratamiento de imágenes etc- donde si no eres un hacha de los punteros además de un hacha de doble filo de las matemáticas y la física no te comes un torrao) desde los tiempos del Pascal o el Clipper de toda la vida no nos han hecho falta los punteros (y mucho menos C) para crear una buena aplicación. O mejor dicho, lo más cerca que hemos llegado a estar de C y los punteros ha sido cuando hemos tenido que hacer llamadas a la API de Win32 y hemos querido saber que Pascal mete y saca los parámetros de la función en un orden, y C lo hace en el orden inverso (como curiosidad, el modificador ‘pascal’ de las funciones en C es una extensión de Apple según tengo entendido). Pero hasta ahí. No nos ha interesado la, por lo visto, apasionante diferencia entre hacer un incremento de variable utilizando v++ o ++v, ni muchas otras “pijadas” que sí, que tendrán mucha utilidad, pero en ámbitos muy concretos.

    Y en cuanto a la recursividad… por Dios, parece que sólo sepáis hacer algoritmos recursivos los “C-eros”, pero vamos yo sólo recuerdo un lenguaje en el que teóricamente no era posible implementar recursividad, y era en el BASIC del Spectrum… y aún así lo dudo.

    Saludos

  7. Hombre Pablo…

    Los hay aún peores, que consideran que el LISP es el sumum de la programación (hay una historia curiosa sobre eso en Xooglers, creo), simplemente porque la diferencia entre datos y código no existe explícitamente.

    Pero para programar aplicaciones de gestión de las de toda la vida hay dos caminos. Hacer una más y hacer la mejor. Está claro que cada uno ha de elegir su camino… 😉

    Y pensar que saber algorítmica y estructura de datos sólo hace falta para los que se dedican a hacer juegos es un error garrafal. A ver cómo ibas a manejar una base de datos de una aplicación aburrida (como puede ser la de las publicaciones de un periódico) por la fuerza bruta. Por muy buenas consultas SQL que puedas hacer, cuando procesas miles de registros el elegir un buen algoritmo marca mucha diferencia, y eso no es saber si pones ++i o i++… y no me vale el argumento de que hay que poner más potencia de hardware.

    Porque, mal que nos pese, para tratar una colección de datos no siempre nos vale usar un foreach. 😛

    P.D.: En Pascal se pueden usar punteros…

  8. el comentario anterior lo escribí sin leer el post… ;)…

    ahora leyendo el posto digo: “si no sabes punteros en C, no serás más que un aficionado….”

    si sabes punteros, el mundo binario es tuyo, claro, C es la voz !!!!.

  9. Opino que aunque no sea indispensable, el conocimiento de cómo funcionan los cotarros “a bajo nivel” es muy beneficioso e importante. Un programador que comprenda y maneje el concepto de punteros podrá entender mucho mejor el funcionamiento de lo que está empleando. Creo que el concepto de puntero es básico. Es importante saber C. Y además, puede ser uno de los lenguajes más sencillos de aprender.

  10. El uso de punteros dentro de nuestras app, fue siempre un tema crucial, muxos los utilizan sin saber lo ke utilizan y sion saber su funcionamiento base, siempre es bueno saber como gira la rueda,

  11. Mmmmm La verdad es que yo el ver las cosas con punteros no me fue muy traumatico. De hecho cuando empecé a ver las cosas que antes habia hecho a las bravas con punteros, le vi mas logica. De todos modos si hay algo claro es que todo programador que se precie tiene que saber manejarse desde mas bajo nivel hasta la ultima abstraccion que se haya hecho en este mundillo, por lo que el articulo lo extendería a que hay que saber manejarse en todo… Incluido ensamblador… Nunca se sabe quien puede necesitar darle vueltas a AL… 😉

  12. Augusto, veo que vamos acercando posturas. Sin embargo…

    – No he dicho que no sea necesaria la algorítmica o las estructuras de datos. Todo lo contrario, ser capaz de implementar buenos algoritmos y comprender bien las estructuras de datos es fundamental. Lo que yo he dicho, es que los punteros son prescindibles, y que C no es en absoluto necesario para desarrollar.

    O dicho de otro modo, si lo prefieres, “C + punteros != algoritmica + estructuras de datos”

    No mezclemos churras con merinas por favor.

    Otra cosa, es que desgraciadamente en el mundo laboral, NADIE va a valorarte que hagas la mejor aplicación. Como mucho obtendrás reconocimiento de tus compañeros, pero no esperes, jamás, obtenerlo de los “capos” de tu empresa. A ellos les da igual que tu aplicación ocupe 50 megas, o 50 KB. Se la trae al fresco que te hayas currado un algoritmo de búsqueda revolucionario que deje en pañales a los que utiliza Google, ellos sólo van a ver que has “perdido” muchas valiosas horas “jugando” (en nuestro idioma: investigando). Ellos quieren la aplicación funcionando, YA.

    La primera vez que te pasa esto, te ries. La segunda vez (cuando has mejorado aun más tu programa) te jode. Y la tercera ya pasas de todo, y de querer hacer “la mejor” te da exactamente igual hacer “una más”.

    Saludos

    PS: Por cierto, LISP estaba muy bien para lo que fue concebido, nada más. Y Cobol, y Fortran, y ADA…

  13. Hola Pablo,

    Llevo 7 años en este negocio (sé que aún no son muchos, y puede que aún conserve la ilusión) y por lo que he podido ver, por lo menos en mi caso, el hecho de hacer las cosas bien suele tener recompensa. Porque muchas veces para hacer las cosas bien no hace falta investigar si tienes buena base… como mucho, recordar.

    Eso sí, es cierto que C + punteros != algorítmica + estructuras de datos.

    Pero en una entrevista de trabajo tienes 20 minutos para decidir si contratar o no. Y lo que he podido ver es que esa pequeña prueba (que además, te digo, yo no obligo a hacerla en C, sino en el lenguaje que elijan – me vale pseudocódigo) sí que me vale para discriminar. Sobre todo porque es muy preferible desde el punto de vista de los gastos que te pueden generar, decir que no a uno bueno que decir que sí a uno mediocre.

    Si dices que sí a uno mediocre, necesitarás a uno bueno para arreglar lo que hace el mediocre, y estarás pagando a dos por hacer el trabajo de uno (y además, tardando más, ya que el que viene a arreglarlo lo tiene que arreglar después).

    Dar la vuelta a una lista enlazada es muy sencillo de hacer en C y con punteros. Si echas un vistazo al artículo, en él explico que los que tiran por Java o por .NET muchas veces (no siempre) tienen problemas con el concepto del objeto, y de ahí que no utilicen los constructores correctamente… Y es una prueba sencilla que implica algo de algorítmica y de estructura de datos.

    Por último: Creo que no has leído todo el post, o no lo hiciste con atención 😉 Porque no digo en ningún momento que la recursividad y los punteros sean cosa de C. Y no soy un DIOS ni un GURU ni un Chuck Norris de la programación 😛

  14. Parece que los comentarios se han quedado encallados en los punteros… en cualquier caso, para punteros el ensamblador :P. En serio, está claro que C (o similar) + punteros [Bien Utilizado] siempre va a tener más rendimiento que usar un lenguaje OO. Pero por otra parte, la mayoría de las estructuras de datos se han implementado y reimplementado miles y miles de veces. Porqué volver a hacerlo va a ser mejor (exceptuando el típico orgullo del programador informático)… sin contar conque probablemente estará mucho más probada (“testada”). Por último, por muy bueno que seas con los punteros, creo que es mucho más difícil encontrar posibles errores.
    En cuanto al resto del artículo concuerdo en que lo principal para ser un buen programador es ser inteligente y terminar las cosas que empiezas y, aunque cada vez menos saber inglés, aunque si para estar a la última.
    Y para acabar, jeje, todo esto es culpa de Augusto, que me lía. No creo que se deba aprender C o .Net uno antes del otro, sino aprender a Programar (con mayúsculas). Al final el lenguaje en si debería dar un poco igual (lenguajes de alto nivel, claro). Eso si que me parece importante, más que saber manejar punteros, que en un mes currando (a ser posible antes de empezar a pagarle, claro) ya controle el lenguaje en si.

  15. Hombre, lo que mas o menos parece que todo el mundo esta de acuerdo es que el conocer como se “manejan” las cosas hace que entiendas mejor el ordenador, no?

    Por cierto, Augusto, yo de pregunta de calentamiento a veces hago una que tambien es un reverse: Darle la vuelta a un arbol binario }:)

  16. Hola phobeo,

    ja ja ja… que risa ….!!! ps tienes la razón hombre, “el fin es entender como se manejan las cosas”… esto es entender el mundo binario…

    salu2.

  17. Bueno este post vino por uno mio y ahora me toca opinar a mi :P, yo no voy a entrar en si te hace mejor programador conocer C o no, para empezar porque no lo sabré hasta que lo conozca.

    Lo que si te hace buen programador es conocer cuanto más, ¡mejor!!

    El poco tiempo que llevo con C, la verda, no he tenido ningún problema con los punteros… puede que no los conozca lo suficiente para no entenderlo 🙂 El caso es que de momento no tengo problemas.

    Pero bueno… Tengo 16 años (hace 2 que entre en las programación), conozco .NET 2.0 (con VB y C#), tanto para Windows como para Web, y por lo que me ha dicho Unai no creo que Compact Framework sea muy diferente.

    ¿Me voy a conformar viendo como .NET evoluciona?¿O empezar con Java (lo dudo porque no me gusta)?

    Pues yo creo que no… Conocer C creo que no solo será un lenguaje que se sume a mis conocimientos sino que también me hará ver la programación con unos ojos diferentes, pero eso… me pasará con C y con otros lenguajes que aprenda en lo mucho que me queda por aprender.

    Saludos

  18. Joder Eugenio… empezaste a los 14 años?? Tú eres de los míos, jejeje 😀 ( http://thenetrix.blogspot.com/2006/10/y-cmo-he-llegado-yo-hasta-aqu.html ) Lo que pasa es que “en mis tiempos” no teníamos las opciones de ahora… aparte por supuesto de que un PC era absolutamente inalcanzable. Así que, para los ordenadores de la época tenías que elegir entre BASIC o assembler. Bueno, algunos privilegiados con sus Amstrad tenían compiladores de Pascal.

    Lo que dice Bruno es quizás lo que yo quería expresar, que si uno sabe Programar, te da igual el lenguaje, porque la gran mayoría de cosas que cambian son simplemente sintácticas (Los que venimos de Delphi tenemos la ventaja de haber trabajado con la antecesora de la .NET Framework -la VCL- desde hace muuchos años; y nos dimos cuenta de que entre Visual Basic .NET y Object Pascal lo único que cambia son los comandos). Y viéndolo desde ese punto de vista, yo sí creo que el programador “nace” y no “se hace”. Es decir, sabemos que hay dos tipos de cerebros, según el hemisferio predominante: el “analítico” y el “creativo”… Pues para ser programador, tu cerebro debe ser preferentemente Analítico (la parte creativa es muy útil, sí, pero si no puedes comprender la base de la programación que es como ya decían la algorítmica -que es algo 100% analítico-, estás perdido). Y sólo en aquellos casos en que la parte Analítica y la Creativa se complementan armoniosamente, podemos saber que esa persona es (o puede llegar a ser) una auténtica bestia de la programación.

    En cuanto a lo de “reinventar la rueda” que también comenta Bruno… pues aunque en principio sea algo que parece inútil, si no hubiese habido nadie que primero le hubiese puesto radios a las ruedas en vez de ser toda entera de madera, y luego le pusieran caucho alrededor, y después cambiasen la madera de las llantas por hierro, y después por aluminio, y le pusieran cámara de aire al recubrimiento de caucho, y… pues vete a saber con qué tipos de ruedas irían hoy los más deslumbrantes Mercedes (desde luego si te lo imaginas la imagen es cómica xDD).

    Saludos

    PS: Madre mía como me enrollo en los posts que escribo 😛

  19. ¿Pueden modificarse las propiedades de una instancia que se pasa como parámetro por valor? ¿Y por referencia?
    ¿Existen los punteros constantes que apuntan a algo variable?
    ¿Existen variables puntero que apuntan a algo constante?

    MiCarro = new Vehículo()
    MiCarro.Carga= “Dos sacos de patatas”

    MiCarro = TuCarro2

    ¿Dónde estará MiCarro? ¿Y mis dos sacos de patatas?

    Preguntas existenciales donde las haya, pero más interesantes son las respuestas. Todo para confirmar que estoy 100% de acuerdo con el autor del post.

  20. Ya te digo…. los pointers (“punteros” dicho en la proxima lengua internacional…) para mi son la revolución de la programación. No tengo ni p**** idea de programacion linear, ni falta q me hace, pero si algo de estructuras y es que es una “lienalidad” con bucles
    que facilitan un proceso repetitivo sin necesidad de etiquetas, de hay la idea de “puntero” q apunta a “algo” … llevo 2 años solo con C , antes empeze por actionscript de flash con sus p*** filosofia de POO y no me salia nada… weno con un poco de analisis de POO y con lo aprendido en C (palos y + palos) hize un texto scroleeado y en 30 min sin analisis, POR ESO SIGO CON C, ES EL PADRE DE LA NUEVA ESCUELA DE LA PROGRAMACION(poo) (ole los wevos de kernigan y ritchie!!!

  21. Lo de la entrevista, “picar código sin pensar, malo, malo” me parece lo más patético que he oído en mi vida. Para alguien con experiencia de años en muchos lenguajes dar la vuelta a una lista es algo tran trivial que no necesita hacer un puto dibujo para que un consultor de mierda crea que es bueno y sigue el puto procedimiento.

  22. @alguien:

    ¿En serio? Haz un pequeño ejercicio: Inténtalo sin dibujar, y sin usar google. En papel. Sin depurar (excepto mentalmente, o usando el papel para hacerlo). Y luego me lo cuentas.

    Normalmente cuando alguien lleva años programando con muchos lenguajes, no tienen que dar vueltas a listas enlazadas todos los días. Si son buenos, usaron una librería que ya lo implementaba. O lo picaron una vez y lo metieron en una librería propia. O lo picaron una vez y lo copipastearon cada vez que lo necesitaban. O directamente lo copipastearon de Google. 🙁

    Te digo una cosa, si alguien no lo dibuja en papel y lo hace perfecto, no hay problema. No es tema de seguir el procedimiento o no. Hay gente que se hace el esquema en la cabeza, e incluso gente que sobre el papel lo que hace es razonar en alto. Lo importante de la entrevista es ver si esa persona es capaz de superar un reto (vé a una entrevista nervioso, y verás si es o no un reto que te hagan una pregunta que no te esperas), e intentar ver cómo piensa.

  23. hola, soy de marin san felipe estado yaracuy venezuela, actualmente estudio informatica, me encanta programar c, me parece un lenguaje potente y a la vez lo veo como una especie de gimnasia cerebral antes de indagar en otros lenguejes tales como php o java, no se nada pero los invito a visitar http://www.conclase.net, alli encontrara material de alto calibre para leer, conocer, practicar y aprender de c para posteriormente usar las nuevas tecnologias del mercado del software, http://www.ignacio_345@hotmail.com, hagan preguntas, probablente te responda rapido todos los dias reviso mi correo, hasta pronto. the webman.. 🙂

  24. AHHHHHHHHHHHHHHHHHHHH,(léase como suspiro) Los he leído con deteción, y de fijo que lo de los punteros es lo suyo. Vine aquí buscando información sobre punteros, pero leyéndolos hasta que me da un susto, por empezar a programar.

    Programar, no es del todo feo, pero, con esto de punteros y recursividad, casi que me devuelvo.

    No sé si los volveré a leer, porque no estoy en mi oficina.

    Pero si quieren escribirme, para ayudarme, lo agradecería

    marsus@gmail.com

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *