Enseñando programación con C++

Anuncio
Enseñando programación con C++: una propuesta didáctica
Jorge Díaz
Universidad de Oriente, Departamento de Computación, Santiago de Cuba 90500, Cuba
jdiaz@csd.uo.edu.cu
Resumen: Se hace un análisis crítico acerca de las características del lenguaje C++ con vistas a su utilización como
lenguaje en una primera asignatura de programación de alto nivel orientada a objetos y se expone una metodología
para impartir tal asignatura, la cual incluye una selección y secuencia de los contenidos que hacen más viable el uso
del lenguaje en la enseñanza de la programación y que ha arrojado resultados superiores en cuanto al aprendizaje de
los estudiantes.
Palabras clave: lenguajes de programación, orientación a objetos, enseñanza de la programación
Abstract: A critical analysis about the characteristics of the programming language C++, regarding its use in a first
course of high level programming, is made. It is exposed a methodology for teaching this course using of a fruitful
way this language.
Key words: programming languages, object oriented, programming teaching.
1. Introducción
Siempre ha resultado un dilema la selección de cuál
debe ser el lenguaje que de entrada usaremos para
enseñar a los estudiantes sus primeros conceptos de
programación, máxime cuando el proceso evolutivo
de la rama es extremadamente rico y rápido.
Diferentes lenguajes se han usado en un primer
curso de programación, podemos citar Pascal, Ada,
Modula, C, C++, C#, Java.
Los criterios de selección no se desligan de las
necesidades de programación del sector industrial,
científico y empresarial, los cuales, en muchos
casos, gravitan en aplicaciones que usan el C/C++
como lenguaje de trabajo, lo cual tiene su influencia
a la hora de decidir cuál será el lenguaje básico de
partida, con vistas a acortar el trayecto entre
aprendizaje y empleo. De hecho, en (Tonella, 2002)
se expresa la conveniencia de adoptar ciertas reglas
que permitan continuar usando el lenguaje C++ en
el desarrollo de sistemas, fundamentalmente donde
la introducción del Java aún no parece adecuada.
Es bien sabido que el lenguaje C++ presenta ciertos
problemas que de entrada no lo hacen aparecer un
buen candidato para comenzar los estudios de la
programación, tal y como se analiza en (Kolling,
1999), aún así es elegido en una parte no
despreciable de cursos universitarios del área
informática.
__________________________________________________________________________________________________________________
Revista de Informática Educativa y Medios Audiovisuales Vol. 3(7), págs. 12-21. 2006
ISSN 1667-8338 © LIE-FI-UBA. liema@fi.uba.ar
12
Enseñando programación con C++: una propuesta didáctica
____________________________________________________________________________________________________________________
Los propósitos de un primer curso de programación
deben concentrarse en ofrecer a los estudiantes:
• Conocimientos
de
los
conceptos
de
programación y un vocabulario para discutirlos;
• Habilidades de análisis y de programación;
• Un marco de referencia para la teoría y
disciplina de la programación.
Debemos asegurarnos que los estudiantes aprenden
a programar, en vez de aprender un lenguaje de
programación.
De otro lado, la mayoría de los textos de
programación prestan en general poca atención a
principios didácticos, presentando los contenidos en
un orden conceptual y prestando poca atención a los
principios metodológicos de solución de problemas
o cuestiones de depuración de los errores, que son
áreas probadamente problemáticas para los novicios
en la programación.
Es por ello que nos proponemos hacer una reflexión
crítica de cómo emplear en lenguaje de
programación C++ dentro de un primer curso de
programación en ambientes donde por cuestiones de
diversa índole se insista o aconseje su empleo y
consecuentemente dar una metodología de
enseñanza en que aún empleando el lenguaje C++
podamos alcanzar los objetivos formativos de
programación para los estudiantes que reciben por
primera vez la asignatura de programación, basada
en el enfoque orientado a objetos, de tal forma que
podamos usar de una manera didáctica y sistémica
los libros de textos del lenguaje existentes.
2. Requerimientos para un primer
lenguaje de programación orientado a
objetos
Presentamos a continuación algunas características
que son deseables en un lenguaje usado en un
primer curso de programación, siguiendo las ideas
de (Kolling, 1999), junto con un análisis crítico de
la característica para el lenguaje C++:
1. Claridad conceptual: Los conceptos del lenguaje
deben ser claros, fáciles de comprender y bien
definidos. Esos conceptos deben ser representados
de la misma manera en que queremos expresarlos
cuando los enseñamos. La implementación del
lenguaje debe reflejar el nivel de abstracción que
queremos usar en nuestros modelos conceptuales.
Un lenguaje de programación proporciona a la vez
un marco conceptual para pensar acerca de los
algoritmos y un medio de expresar esos algoritmos.
El lenguaje debe constituir una ayuda para el
programador incluso antes de la etapa misma de
codificación. Debe proveer un conjunto claro,
sencillo y unificado de conceptos que se puedan
usar como primitivas en el desarrollo de algoritmos.
2. Modelo puro de objetos: El lenguaje debe exhibir
orientación a objetos “pura”, en el sentido de no
poseer estructuras alternativas para construir
objetos, sino sólo la abstracción básica usada para la
programación, en contraposición con lenguajes
híbridos, o sea, lenguajes que soportan la
orientación a objetos junto con otros paradigmas no
orientados a objetos.
3. Seguridad: Los errores deben ser fácilmente
detectables lo más tempranamente posible por el
compilador o el sistema de tiempo de ejecución y
ser reflejados con mensajes que ilustren su causa.
Deben evitarse conceptos conducentes a la escritura
de programas erróneos. Debe tener un sistema de
tipos con chequeo fuertemente estático, evitar
punteros explícitos, hacer chequeos de límites de los
índices de los arreglos y uso de variables no
inicializadas.
4. Alto nivel: El lenguaje no debe contener
información concerniente al bajo nivel de máquina,
como por ejemplo, administración explícita de
almacenamiento dinámico y debe proveer una
colección de basura automática.
5. Modelo sencillo de ejecución y de representación
de los objetos de datos: Debe poseer un modelo de
ejecución bien definido y fácilmente comprensible.
Debe ser transparente al programador el modelo de
memoria adoptado para los objetos de datos que se
manipulan, sean del stack o del heap.
6. Sintaxis legible: El lenguaje debe poseer una
sintaxis consistente y fácilmente legible. Un
programa legible es más fácil de corregir. Las
palabras son más intuitivas, en muchos casos, que
los símbolos para expresar las construcciones del
lenguaje.
7. No ser redundante: El lenguaje debe constar de
pocas construcciones, debe ser claro y evitar
redundancias. Para los principiantes la flexibilidad
que puede aportar la redundancia se convierte a
menudo en confusión, más que en eficiencia.
8. Pocas construcciones: El lenguaje debe ser tan
corto como sea posible, siempre que incluya todas
___________________________________________________________________________________________________________________
Revista de Informática Educativa y Medios Audiovisuales Vol. 3(7), págs. 12-21. 2006
ISSN 1667-8338 © LIE-FI-UBA. liema@fi.uba.ar
13
Enseñando programación con C++: una propuesta didáctica
____________________________________________________________________________________________________________________
las características importantes que desean enseñarse
en un curso de programación para un primer año.
una construcción del lenguaje, como, por ejemplo,
cuando se manipula la aritmética de punteros.
9. Fácil transición a otros lenguajes: El aprendizaje
del lenguaje debe facilitar una fácil transición a
otros lenguajes ampliamente usados, como C/C++.
Modelo puro de objetos: En el lenguaje coexisten
construcciones que facilitan tanto la programación
procedural como la orientada a objetos, pues en
realidad C++ representa un paradigma híbrido entre
ellos.
10. Facilidades de corrección: El lenguaje debe
suministrar recursos para facilitar la corrección del
programa, como prueba de aserciones, pre y
postcondiciones, depuración de errores y
manipulador de excepciones.
11. Ambiente de trabajo amigable: El lenguaje debe
poseer un ambiente de desarrollo de fácil uso, que
permita al estudiante concentrarse en las tareas de
aprender los conceptos de programación en vez del
propio ambiente. La presencia de un ambiente de
programación adecuado puede facilitar el trabajo
con un lenguaje técnicamente débil en comparación
con un lenguaje más fuerte con poco apoyo externo.
Estos ambientes deben contar, al menos con
poderosos medios de edición y desarrollo de
aplicaciones, de una implementación confiable,
eficiente y bien documentada del lenguaje, así como
recursos para una adecuada depuración de los
errores en los programas.
Características como la eficiencia, que es
extremadamente importante para un lenguaje de
programación en un entorno de producción de
software, tienen poca significación en la enseñanza.
Tampoco se considera la flexibilidad del lenguaje
para el desarrollo de aplicaciones en tiempo real
(por ejemplo, con operaciones de manipulación de
bits).
3. Evaluación crítica del C++
El lenguaje C++ viola casi todos los requerimientos
de la lista anterior. Es un lenguaje híbrido que no
presenta los conceptos de una manera clara, posee
un conjunto de construcciones altamente redundante
y un sistema de tipos inseguro. Analizamos para el
lenguaje cada una de las características enunciadas
en el epígrafe 2:
Claridad conceptual: Los propósitos principales en
la creación del C++ fueron mantener una
compatibilidad completa con C y considera la
eficiencia en tiempo y espacio como su meta
principal. De ahí que el lenguaje se vea influenciado
por consideraciones de bajo nivel, que separan el
concepto abstracto de su representación concreta.
En ocasiones es necesario comprender ciertos
detalles de implementación para usar correctamente
Tratar de introducir la orientación a objetos usando
lenguajes híbridos tiene el peligro de que los
estudiantes con experiencias anteriores en
programación en un lenguaje procedural no se
sienten comprometidos con el cambio a un nuevo
estilo.
Seguridad: Una de las críticas más fuertes que se
hacen al C++ es la falta de un sistema de tipos
seguro. La asignación de memoria dinámica
explícita, junto con la falta de colección de basura,
incrementan los riesgos de errores, tales como
referencias nulas o basura.
Alto nivel: C++ incluye algunos constructores de
bajo nivel, entre ellos las operaciones de
manipulación de bits, la aritmética de punteros y la
administración de almacenamiento dinámico
explícito. Tiene un elemento importante a su favor
para la programación de alto nivel, que es el soporte
de genericidad, con un chequeo de los tipos
parametrizados en tiempo de compilación.
Modelo sencillo de representación y ejecución de
objetos de datos: El modelo de objetos de datos de
C++ es uno de los más complejos entre los
lenguajes de programación que soportan orientación
a objetos. Ello está motivado en el hecho de que en
C++ aparecen variables dinámicas (usando
punteros) y no dinámicas (automáticas), lo que
también se refleja en la semántica de algunas
construcciones importantes del lenguaje.
Sintaxis legible: En C++ se favorece el uso de
símbolos en vez de palabras, por ejemplo, empleo
de la llave { en vez de begin, el uso de la misma
palabra clave u operador para diferentes fines, como
la sintaxis de una función abstracta virtual void f() =
0; que emplea el operador de asignación. Todo esto
redunda en una falta de legibilidad de los programas
escritos en el lenguaje.
No redundancia: El hecho de mantener C++ la
compatibilidad con C hace que arrastre ciertos
aspectos redundantes e interacciones de conceptos
que aquejan a este último, lo que incrementa la
complejidad del lenguaje.
___________________________________________________________________________________________________________________
Revista de Informática Educativa y Medios Audiovisuales Vol. 3(7), págs. 12-21. 2006
ISSN 1667-8338 © LIE-FI-UBA. liema@fi.uba.ar
14
Enseñando programación con C++: una propuesta didáctica
____________________________________________________________________________________________________________________
Facilidad de transición a otros lenguajes:
Consideramos que el aprendizaje del lenguaje C++
facilita la comprensión rápida de otros lenguajes de
amplio uso, como el Java. De otro lado, aprender el
lenguaje C++ puede reportar beneficios en el caso
de realización de prácticas profesionales
simultáneas por parte de los estudiantes en el sector
industrial, que aún emplea con frecuencia esquemas
basados en C/C++.
Ayuda a la corrección: No hay en C++ soporte para
pre ni postcondiciones, existiendo una forma de
prueba con aserciones (a través del assert). Posee un
sistema de manipulación de excepciones.
Ambiente de trabajo amigable: Para C++ se han
desarrollado muy buenos ambientes de trabajo, que
incluyen herramientas para el desarrollo de
aplicaciones, tales como Visual C++ y Borland C++
Builder.
4. Estrategia pedagógica en el uso de
C++ para la orientación a objetos en una
primera asignatura de programación
•
Aún cuando un lenguaje híbrido sea una selección
de orden práctica, los estudiantes probablemente se
sentirán algo confundidos en el intervalo de tiempo
en que aprenden los conceptos asociados a objetos.
Tomando en cuenta lo arriba planteado y además el
hecho de que una asignatura de Programación tiene
otras subsiguientes que complementan lo aprendido
en ella, como lo puede hacer una asignatura de
Estructura
de
Datos,
brindamos
algunas
orientaciones metodológicas que pueden ser tenidas
en cuenta al momento de impartir la asignatura de
Programación, a partir de nuestras propias
experiencias (Díaz, 2002) y de recomendaciones,
como las encontradas en (Tonella, 2002) para
definir un subconjunto de C++ que se acerque a las
características de Java. En estas orientaciones
sugerimos un orden en que puede ser impartida la
asignatura.
1.
En lenguajes híbridos para la orientación a objetos,
como lo es el caso de C++, con la coexistencia para
la programación estructurada, es común el uso de
una estrategia pedagógica en la que el concepto de
objeto no se enseñe como el primer concepto de la
programación, sino que algunos otros conceptos,
tales como expresiones e instrucciones del lenguaje
hasta el concepto de tipo de dato abstracto sean
trabajados antes de introducir el concepto de clases
como desarrollo de los tipos de datos abstractos
(TDA).
Este esquema tiene como ventaja que da
continuidad a una forma de aprendizaje que
normalmente traen los estudiantes de la enseñanza
media, basado en el desarrollo de algoritmos y la
programación estructurada. Sin embargo, pueden
señalársele algunas desventajas:
•
Uso simultáneo de tipos de datos básicos y de
tipos de objetos y sus incompatibilidades.
•
Uso de punteros en muchos de los lenguajes
candidatos para ser usados en la enseñanza, con
necesidad de derreferenciación explícita y sin
uso de colectores de basura.
El concepto de tipo de dato abstracto se vuelve
de difícil comprensión, en vez de inmediato y
concreto.
No abandonar a lo largo del curso un estilo de
enseñanza de la programación basada en la
resolución de problemas, o sea, del problema a
la búsqueda de los algoritmos que le brinden
solución y de ahí a la codificación del algoritmo
en un lenguaje de alto nivel.
El estudiante debe quedar convencido, desde
que comienza la asignatura, de que su eficacia
como programador no está precisamente en
dominar la herramienta de programación, cosa
evidentemente necesaria, sino en saber resolver
problemas con la computadora para lo cual se
requiere dominar una metodología de la
programación cuyo eje central es el algoritmo.
2.
Continuando la idea de la primera orientación,
dedicar las primeras semanas de clase al
desarrollo de algoritmos, usando para su
expresión alguna forma de seudocódigo
próxima al lenguaje natural. Cuando se
introduzcan en las características de un
lenguajes de programación y se enuncien sus
principales estructuras de control (secuencia,
alternativa y ciclos) y algunos de sus
principales operadores (aritméticos, asignación,
etc), podemos entonces, adicionalmente,
comenzar a introducirlos en la expresión del
algoritmo usando la forma de codificación
propia del C++.
___________________________________________________________________________________________________________________
Revista de Informática Educativa y Medios Audiovisuales Vol. 3(7), págs. 12-21. 2006
ISSN 1667-8338 © LIE-FI-UBA. liema@fi.uba.ar
15
Enseñando programación con C++: una propuesta didáctica
____________________________________________________________________________________________________________________
3.
Se sugiere usar solamente las operaciones
imprescindibles de estrada/salida, según el
formato de C++, o sea, usando la clase
<iostream>.
Después se puede pasar a estudiar la estructura
del programa en C++, donde se introducen las
declaraciones de constantes, definiciones de
variables, características de algunos tipos
primitivos y se estudian con mayor grado de
formalización sintáctica y semántica los
operadores y las estructuras de control básicas
del lenguaje.
Ya en estos momentos deben dedicarse una
cantidad de clases prácticas en laboratorios de
computadoras, de tal forma que los estudiantes
se familiaricen con el ambiente de trabajo del
lenguaje y puedan correr algunos de los
problemas, cuya expresión algorítmica dio en
clases anteriores.
Es importante además estudian los conceptos de
alcance de identificadores y tiempo de vida de
las variables, así como la definición de espacios
de nombres.
4.
El empleo de los operadores en estas primeras
semanas debe ser lo más próximo al
conocimiento matemático previo del estudiante,
por ejemplo, no sería conveniente usar la
asignación múltiple v = a = b, sino a = b y
después v = a. Tampoco es recomendable usar
formas de composición de operadores que sean
oscuras, tales como
x = (y=5) + (z=4),
siendo mejor emplear
y = 5; z = 4; x = y + z.
Aquí ya hay un espacio para las operaciones de
incremento y decremento, los operadores de
asignación múltiple y compuestos.
Como inmediatamente vamos a proponer el
estudio del concepto de clases, entonces resulta
aconsejable enseñar parámetros con valores por
defecto y sobrecarga de funciones.
Sin embargo, no resulta recomendable enseñar
en este momento las operaciones de
manipulación de bits que ofrece en lenguaje, ni
los moldes (casting).
Tampoco es recomendable usar valores
numéricos como expresiones lógicas para las
condiciones que controlan las instrucciones de
alternativa (if…) o de ciclos. Es sabido que una
expresión aritmética puede ser considerada en
el lenguaje como un caso particular de una
expresión lógica, que se interpreta como
verdadera si es diferente de cero, o falsa si es
cero, interpretación que debe evitarse en estos
primeros momentos que se aprenden las
instrucciones arriba citadas. En vez de escribir
if (a) …..
escribir
if (a != 0)…..
El concepto de función se introduce como es
usual, también desde un punto de vista
algorítmico, en que se definan los parámetros
de entrada, de salida, de entrada/salida y formas
que eventualmente usará la función para
retornar valores que calcula.
El uso del operador & para el traspaso de
parámetro por referencia debe quedar en este
momento a un nivel de definición, para luego
ser explicado el concepto en el capítulo
dedicado a los punteros y las referencias. Se
puede comenzar con el estudio de funciones
recursivas, el cual se puede retomar más
adelante con un mejor aparato conceptual, por
ejemplo, una vez se hayan estudiado estructuras
de datos lineales.
En este momento es mejor evitar impartirles
funciones genéricas (template de funciones) y
funciones con cantidad de parámetros
indeterminada. Debe evitarse también la
declaración global de constantes y variables.
5.
Llega el momento de introducir el concepto de
clase. El punto de partida es la definición de
tipos de datos abstractos que nos ayuden en la
representación de un problema, por ejemplo, la
definición de alguna clase para datos numéricos
(números fraccionarios, números complejos)
donde se implementen algunas operaciones, que
para la clase de los números fraccionarios
puede ser sumar, multiplicar, simplificar, leer,
mostrar, etc.
A partir de ahí definimos sus rasgos distintivos
(en atributos y operaciones necesarias para el
tipo) y presentamos al concepto de clase como
una herramienta eficaz para codificar en el
___________________________________________________________________________________________________________________
Revista de Informática Educativa y Medios Audiovisuales Vol. 3(7), págs. 12-21. 2006
ISSN 1667-8338 © LIE-FI-UBA. liema@fi.uba.ar
16
Enseñando programación con C++: una propuesta didáctica
____________________________________________________________________________________________________________________
punteros y cadenas de caracteres, sin embargo
en la quinta edición ya se introduce un primer
momento del estudio de las clases una vez
dados elementos básicos del lenguaje y antes de
las estructuras de control.
lenguaje de programación la definición de tal
tipo y su empleo en el problema.
Deben ser estudiadas las formas de visibilidad
que implementa C++ para las componentes de
clase, las partes de la clase (interfase e
implementación), constructores simples y
destructor.
6.
Al tratar con this, debe ser a un nivel muy
simple, que nos evite mezclarnos con los
punteros y lograr que en este momento sea
aceptado por definición que *this es el objeto
actual que envía el mensaje en proceso.
Debe explicarse el concepto de estado de un
objeto y a partir de aquí las funciones de acceso
a un objeto (las que retornan el valor del estado
o parte del estado del objeto), su importancia y
porqué comúnmente se les declara como
funciones const. Pueden ser empleados
ejemplos de objetos compuestos.
class Valor
{ private:
float elem[100];
int cant;
..............
};
Deben estudiarse las cadenas de caracteres,
tanto al estilo de C como de C++ (objetos
string).
Cuando se emplea un lenguaje híbrido en la
orientación a objetos para enseñar, como lo es
C++, hay criterios divididos en cuanto a:
•
introducir el concepto de clase en este
punto del programa de la asignatura, en que
otras construcciones de datos propias del
paradigma procedural aún no se han
estudiado,
•
hacer un estudio del lenguaje primeramente
desde
una
óptica
completamente
procedural y luego introducir los conceptos
de clase y otros propios de la orientación a
objetos.
7.
Estudiamos una primera parte del concepto de
herencia. Aquí se introducen el concepto básico
de herencia, los conceptos de clases y
superclases, las formas en que se heredan
atributos y métodos, la visibilidad protected,
todo a través de un ejemplo introductorio.
Se estudian las características de los
constructores y destructores de las clases
derivadas. Recordemos que hasta este punto del
curso las operaciones que estos métodos
realizan son triviales, dado que aún no hemos
trabajado con variables dinámicas.
Se demuestra, en una práctica de laboratorio a
partir del ejemplo de entrada, la importancia de
definir métodos virtuales aquellos que se
redefinen en diferentes niveles de la jerarquía
de clases, denotando además que esta definición
constituye una forma de polimorfismo.
De nuestra propia experiencia, consistente en
emplear el primer enfoque los últimos cursos en
tanto que el segundo enfoque en cursos
anteriores, defendemos el primero, que ha
mostrado una mejor apropiación de los
conceptos de la programación orientada a
objetos.
Ese propio enfoque que escogemos se refleja en
la propia evolución de los textos dedicados a la
enseñanza del lenguaje C++. Si comparamos la
cuarta y la quinta edición del texto de Deitel
“C++ How to Program” (Deitel, 2002), (Deitel,
2005) notamos que hasta la cuarta edición el
primer estudio del concepto de clases se dejaba
hasta después del estudio de los conceptos de
estructuras de control, funciones, arreglos y
A
continuación
se
introducen
tipos
enumerativos y fundamentalmente tipos de
arreglos. Una vez explicados los principales
conceptos sobre arreglos, se introducen las
formas en que los arreglos se operan o
transforman (lecturas, escrituras, cálculos,
búsquedas, etc) construyendo clases en que sus
atributos sean la cantidad real de elementos que
tiene el arreglo y la definición de los elementos
del arreglo, usando el constructor por defecto
de un arreglo, por ejemplo:
8.
Llegamos al momento de introducir los
punteros. Sería deseable no tener que enseñar a
los estudiantes el concepto de puntero en un
primer curso de programación. Esto sería
posible si el lenguaje manipulara sus objetos de
datos de forma dinámica por defecto, lo cual no
es el caso de C++. Siendo entonces
imprescindible el uso de los punteros para
___________________________________________________________________________________________________________________
Revista de Informática Educativa y Medios Audiovisuales Vol. 3(7), págs. 12-21. 2006
ISSN 1667-8338 © LIE-FI-UBA. liema@fi.uba.ar
17
Enseñando programación con C++: una propuesta didáctica
____________________________________________________________________________________________________________________
definir variables dinámicas y todos los
conceptos subsecuentes relacionados, se
recomiendan las siguientes acciones en un
primer momento:
•
Enseñar el concepto de puntero,
fundamentalmente como vía de definir
variables dinámicas, con new y dispose.
•
No enseñar aritmética de punteros.
•
Definir la relación entre punteros y
arreglos, pero insistiendo en el uso del
indizado [] como base del acceso a las
componentes del arreglo.
•
Disciplinar a los estudiantes en el chequeo
del rango de los índices de sus arreglos.
•
Dar
herramientas
didácticas
de
programación para evitar la aparición de
referencias nulas o basura.
•
Hacer un estudio más detallado de los tipos
de cadenas de caracteres definidas a través
de punteros y de la biblioteca <string> de
C++.
•
Crear objetos dinámicos.
•
Explicar qué es el puntero this.
•
Usando la definición de una clase para
manipular arreglos dinámicos, que
incluyan entre otras operaciones la
asignación de un arreglo para otro,
profundizar en la implementación de
constructores y destructores para objetos
con campos dinámicos. Se debe enseñar
además el constructor de copia y su
necesidad.
•
Enseñar los conceptos de listas lineales
(incluyendo colas y pilas) y mostrar
implementaciones
usando
arreglos
definidos dinámicamente o estructuras
enlazadas, en las que emplearán punteros
para en enlace entre cada elemento y su
contiguo.
Retomamos el concepto de herencia, en este
caso para enseñar conceptos relativos a la
definición de tipos-subtipos en una jerarquía y
como esto permite definir objetos polimórficos.
Además se enseña cómo se establece la
compatibilidad entre objetos, punteros a objetos
y parámetros actuales y formales en una
jerarquía de clases.
Considerando el sistema de conocimientos y
habilidades acumulados hasta este punto por el
estudiante en el tema de herencia, es
aconsejable desarrollar ejercicios en que puedan
construir nuevas clases ampliando clases que
han sido desarrolladas en los tópicos anteriores,
bien buscando una nueva especialización o
simplemente para ampliar la funcionalidad de la
clase. Se sugiere evitar en estos momentos el
uso de la herencia selectiva.
Por último se estudian las clases abstractas y las
funciones virtuales puras, a través de un
ejemplo de una jerarquía con una clase base
raíz abstracta, por ejemplo, las figuras en el
plano, como en el ejemplo:
class TFigura
{ protected:
float x, y;
public:
TFigura(float cx=0, float cy=0)
{ x = cx;
y = cy;
}
virtual void Mostrar() = 0;
virtual float Area() = 0;
// otras funciones...................
};
// Clases derivadas
class TCirculo: public TFigura
{ .........
public:
// Funciones concretas Area y Mostrar para
// TCirculo
........
};
.......
class TCuadrado: public TFigura
{ .........
public:
// Funciones concretas Area y Mostrar para
// TCuadrado
........
};
.......
Mostrar como usar la clase con un programa
ejemplo, tal como:
void main()
{ TFigura *p[2];
// da espacio e inicializa un círculo
___________________________________________________________________________________________________________________
Revista de Informática Educativa y Medios Audiovisuales Vol. 3(7), págs. 12-21. 2006
ISSN 1667-8338 © LIE-FI-UBA. liema@fi.uba.ar
18
Enseñando programación con C++: una propuesta didáctica
____________________________________________________________________________________________________________________
typedef double tfun(double);
double SumaCuadrado(tfun &f,int m,int n)
{ double sum=0;
int k;
for (k=m; k<=n; k++)
sum += f(k) * f(k);
return sum;
}
p[0] = new TCirculo(0,0,5);
// da espacio e inicializa un cuadrado
p[1] = new TCuadrado(1,1,4);
for (int i=0; i<2; i++)
{ // Se muestran los datos de la figura adecuada
p[i]->Mostrar();
// Ahora se imprime el área de la figura
cout << "Su área es: " << p[i]->Area()
<<endl;
}
system("PAUSE");
double g(double x)
{ return 1.0 / x;
}
void main()
{ double a, b;
a = SumaCuadrado(g, 1, 5);
b = SumaCuadrado(sin, 0, 4);
cout <<"a= " <<a <<" b= " <<b <<endl;
}
}
donde se muestra un arreglo de objetos polimórficos
con diferentes figuras de la jerarquía.
Por último se les muestra un ejemplo en que puedan
aprender cómo usar la herencia privada para una
clase derivada pueda obviar métodos de su clase
base.
Hasta aquí se han relacionado conceptos básicos de
programación que se pueden encarar en la primera
asignatura destinada a la enseñanza de la
programación. En dependencia del tiempo
disponible para su impartición y de la profundidad
conceptual a la que se quiera llegar en la asignatura,
proponemos seleccionar algunas de las siguientes
temáticas en el orden que se especifica:
a)
Estructuras y uniones, que ahora constituyen
características redundantes en el lenguaje, pero
si los estudiantes tienen a la programación
como objeto de estudio deben conocer estos
tipos.
c)
Formas de polimorfismo operacional
•
Se enseña la forma propia que posee C++ y
la heredada de C. En este momento se
formaliza el estudio de punteros void y su
uso en la compatibilización entre tipos
punteros mediante la coerción.
•
b) Tópicos adicionales sobre punteros:
•
aritmética de punteros,
•
punteros de tipo const y punteros a objetos
dinámicos constantes.
•
Punteros y referencias para las funciones:
aquí lo deseado es poder construir listas de
funciones y también facilitar el traspaso de
funciones como parámetros formales de
funciones. En este último caso sugerimos
usar el traspaso por referencia al estilo de
C++, como en el ejemplo siguiente para
obtener la suma de los cuadrados de una
función f evaluada para valores enteros
entre m y n dados.
Coerción (casting).
#include <iostream.h>
#include <math.h>
Sobrecarga de operadores.
Como sabemos, la sobrecarga de
operadores es un recurso muy cómodo, que
hace permite a los programadores construir
tipos de datos de una forma similar a los
tipos simples predefinidos (int, long, etc.),
dando una interpretación para el tipo de los
operadores predefinidos del lenguaje. Esto
conlleva el estudio de las funciones
operadoras (operator) y el concepto de
función amiga de una clase (friend), uso y
peligros.
Se debe desarrollar alguna clase
previamente estudiada, como la clase de
manipulación de números fraccionarios o
de números complejos u otra afín, usando
las funciones operadoras, mostrando el uso
o necesidad de usar funciones amigas
dentro de clases que implementan
funciones operadoras.
Por otra parte debe reconocerse las
diferencias entre implementar funciones
miembros de una clase y funciones no
miembros amigas de la clase, desarrollando
___________________________________________________________________________________________________________________
Revista de Informática Educativa y Medios Audiovisuales Vol. 3(7), págs. 12-21. 2006
ISSN 1667-8338 © LIE-FI-UBA. liema@fi.uba.ar
19
Enseñando programación con C++: una propuesta didáctica
____________________________________________________________________________________________________________________
algunos ejercicios en que se pida
implementar la misma operación usando
los dos esquemas.
Algunas sobrecargas interesantes que
deben mostrarse, además de los operadores
aritméticos, lógicos clásicos, deben ser la
sobrecarga del operador de asignación =,
en una clase como la de arreglos dinámicos
previamente estudiada. Así mismo se
recomienda enseñar, usando esta propia
clase, la sobrecarga del operador de
indización []. Finalmente pueden ser
mostradas otras sobrecargas de operadores.
•
Funciones y clases genéricas.
Se define el concepto de genericidad y su
importancia práctica y se enseña cómo
definir templates de funciones y de clases
(puede usarse como ejemplo el bien
conocido de la pila genérica). Un estudio
más profundo debe ser dejado a una
asignatura subsiguiente de Estructuras de
Datos, donde pueden explotar además
bibliotecas del tipo STL (Standard
Template Library).
d) El sistema de manipulación de excepciones del
lenguaje. Si se decide estudiar este tema,
debería ser introducido después de transcurrido
el 75% del fondo de tiempo de la asignatura y
no precisamente en sus finales.
4. Conclusiones
Programar es un desafío. La programación requiere
el uso de habilidades de pensamiento abstracto y
muchos estudiantes no han recibido asignaturas que
requieran o les hayan ayudado a desarrollar estas
habilidades en niveles precedentes de enseñanza,
considerando que la asignatura de Programación
debe ser una de las primeras que enfrente un
estudiante de carreras de perfil afín a la
computación. Muchos estudiantes entran a la clase
de programación con escasas habilidades
conceptuales para programar.
En el presente trabajo se ha hecho un análisis
detallado de algunas deficiencias que presenta el
lenguaje C++ al ser considerado como el primer
lenguaje en que los estudiantes que comienzan a
familiarizarse con la programación orientada a
objetos. A partir de tales deficiencias, pero también
considerando algunas de sus bondades, como la
riqueza de elementos conceptuales, presencia de
excelentes ambientes de trabajo y demandas del
sector industrial se brindan un conjunto de
sugerencias que parten de las experiencias
didácticas acumuladas de siete generaciones de
estudiantes que han recibido la asignatura de
Programación en el primer año de la carrera, usando
como lenguaje de programación al C++, además de
experiencias del uso del lenguaje Java en otros
cursos subsiguientes de programación. Estas
sugerencias ofrecen una propuesta de cómo
establecer secuencia de contenidos de la asignatura
y de posibles ejercicios a desarrollar en algunas de
las temáticas.
Todo lo anterior nos reafirma una idea que es de
todos conocida, pero no tan unánimemente aplicada:
el profesor debe enseñar a los estudiantes los
principios de la programación (en este caso
orientada a objetos), lo cual podríamos hacerlo en el
lenguaje que consideremos apropiado. Resulta
primaria una metodología de programación y
subsidiaria de ésta la codificación en un lenguaje de
programación.
Otra idea extremadamente importante es que las
asignaturas de corte matemático que son enseñadas
en el propio año académico que la programación,
como lógica matemática, álgebra y análisis
matemático, pueden influir muy positivamente en el
aprendizaje por parte del estudiante de una buena
metodología de programación, cuestión que algunas
veces también es obviada.
De otro lado los estudiantes no deben abandonar la
universidad sin ser capaces de usar un lenguaje de
amplio uso en el mundo real actual, como en la
actualidad lo continúa siendo C++. En este sentido,
el lenguaje usado en la primera asignatura de
programación debe ser relevante para el dominio de
los lenguajes de más amplio uso científico e
industrial del momento.
Bibliografía
Arnold, K., Gosting, J. (1996) The Java
Programming Language, Addison-Wesley.
Ben-Ari, M. (1998). Constructivism in Computer
Science Education, SIGSCE 98 Atlanta, GA., p.257261, 1998.
Deitel, H., Deitel, P. (2002). C++, How to Program,
4th edition.
Deitel, H., Deitel, P. (2005). C++, How to Program,
5th edition.
Díaz, J. (2002): Introducción a la programación
usando C++. Universidad de Oriente, Cuba.
___________________________________________________________________________________________________________________
Revista de Informática Educativa y Medios Audiovisuales Vol. 3(7), págs. 12-21. 2006
ISSN 1667-8338 © LIE-FI-UBA. liema@fi.uba.ar
20
Enseñando programación con C++: una propuesta didáctica
____________________________________________________________________________________________________________________
Eckel, B. (2003): Thinking in Java, Third Edition.
Prentice Hall.
Kölling, M. (1999). The problem of teaching objectoriented programming. Part I: Environments.
Journal of Object-Oriented Programming, 11(8):
p.8-15.
Stroustrup, B. (1997): The C++ programming
language, Third Edition. Addison-Wesley.
Tonella, P., Potrich, A. (2002). Cjj: a subset of C++
compliant with Java. Science of Computer
Programming, 42, p.229-271.
___________________________________________________________________________________________________________________
Revista de Informática Educativa y Medios Audiovisuales Vol. 3(7), págs. 12-21. 2006
ISSN 1667-8338 © LIE-FI-UBA. liema@fi.uba.ar
21
Descargar