Comenzar a Programar
¿Cómo hacer programas?
La siguiente lista de pasos indica que se debe hacer para hacer un programa de computadora que resuelva un problema específico.
1.- Darse cuenta de que se necesita resolver un problema y que este se puede resolver con ayuda de una computadora.
2.- Identificar las características que debe tener la solución del problema.
3.- Analizar las funciones que debe realizar y la forma en que se integran.
4.- Se diseña el algoritmo de la solución del problema. Seleccionando los sistemas de comunicaciones, cómputo, componentes de software y sus dispositivos de entrada y salida.
5.- Codificar el algoritmo en un lenguaje de alto nivel de programación.
6.- Escribir la codificación en la computadora. El escribir el programa se llama programación.
7.- Compilar el programa.
8.- Corregir el programa.
9.- Mientras aparezcan errores volver al paso 7.
10.- Prueba del programa.
11.- Mientras no termine su ciclo de vida, dar mantenimiento al programa.
Obsérvese que, la lista de pasos anterior, dispuestos de forma sucesiva se parece mucho a un algoritmo, pero éste no lo es porque, hasta ahora no se sabe, si quién este leyendo este capítulo tenga por problema resolver algún problema con un programa, no obstante usa palabras que se ocupan al hacer tanto algoritmos como programas.
Lenguajes de Programación de Alto Nivel
Hasta hace poco el proceso de escritura de un programa y su compilación estaban algo desvinculados aunque se realizaran en una misma herramienta. Primero se escribía y luego se invocaba al compilador. Esto daba por resultado que el programador cometiera ciertos errores en la primera labor y luego debiera corregir al observar el resultado de la compilación. Actualmente hay herramientas que en el mismo instante de escribir el código fuente auxilian al programador, permitiéndole reducir la posibilidad de introducir texto con mal formato y aumentar la velocidad con que se producen programas. A estas herramientas se les conoce como editores de estructura. Aunque son de gran ayuda, no permiten detectar errores de razonamiento; por otro lado, un adecuado uso de este tipo de herramientas posiblemente sea un buen apoyo para la enseñanza de la programación. Cada lenguaje de alto nivel contiene reglas gramaticales, llamadas gramáticas que a su vez, estas gramáticas contienen reglas de sintaxis y de semántica. Y que son parte del programa compilador. Los tres Lenguajes de alto nivel con los que se enseña a programar son actualmente el Pascal, el c y el c++, y estos aunque tienen una versión estándar llamada a.n.s.i. ( américan normativity standard institute ). Las versiones desarrolladas por la firma Borland Inc. Son utilizadas por una gran cantidad de gente en todo el mundo, debido al fácil manejo del editor, siendo el mismo en cada uno y sobre todo por los estándares de edición que presenta. Además de que la velocidad del programa compilador es tan rápida que esta es la verdadera razón por la que se ha preferido los lenguajes Borland. La aparición del primer lenguaje Borland fue el Turbo Pascal, Borland le agregó el prefijo Turbo debido a que a mediados de los años ochenta se utilizaba este término para los objetos que fueran cada vez más rápido; el primer objeto con el prefijo turbo fue debido a un automóvil de firma estadounidense que ahorraba gasolina y aceleraba al doble de la velocidad en la mitad del tiempo estandar para los automóviles a principios de esa década.
Operaciones Elementales de la Programación
Se llaman así por formar parte de un conjunto de elementos y porque también sirven de elementos que forman parte de las operaciones básicas de la programación. Y representan las primeras cuatro operaciones para comenzar a programar.
Operaciones Básicas de la Programación
Se llaman así por ser bases en las que se construyen los programas, comprenden casi a todas las operaciones elementales. Y son: Secuenciación, Decisión e Iteración. La primera es mal llamada secuenciación, debido a que al llegar a México las primeras computadoras, llegaron al Instituto Politécnico Nacional y, probablemente, los ingenieros en Electrónica y Matemáticos que las usaron no sabían mucho inglés y tradujeron sequence como secuenciación y no como sucesión, la secuenciación la podemos conceptualizar como una sucesión de instrucciones lógicas de programación. Los manuales de las primeras computadoras que llegaron a México estaban escritos en inglés y del original se obtiene que para indicar la sucesión se utilizó la palabra "secuence", obviamente un falso cognado. Lo mismo pasa de vez en cuando con la palabra "actually", otro falso cognado, y que significa realmente, a lo que mucha gente considera que es actualmente; esta palabra aparece seguido en la lista de errores del compilador. Otra palabrita dominguera es "library", ésta no significa librería, pues librería es "bookstore", "library" es biblioteca, de modo que cuando se utiliza se refiere a la lista de bibliotecas de procedimientos y funciones disponible en el lenguaje de programación c y c++, solo que debe declararse cada biblioteca en el principio de cada programa.
La secuenciación utiliza a las operaciones elementales Comienza y Termina para indicar el principio y el fín de la sucesión, en otras palabras, una sucesión ( o secuenciación ) está indicada por comienza y por termina, en medio de estas dos palabras se incluye el proceso indicado por las instrucciones.
El cuadro indica, que dentro de él, se encuentra un proceso, mismo que puede ser una sucesión de instrucciones lógicas. Se utiliza así:
{
}
La primera llave indica el comienza y la segunda indica el termina, ambas son instrucciones, mismas que se consideran órdenes dictadas a la computadora. En medio de las llaves se escribe la sucesión de instrucciones lógicas del lenguaje. Cada sucesión de instrucciones lógicas del lenguaje c o c++ forma parte de un proceso, de un procedimiento o de una función.
Veamos tres ejemplos, el primero, cuyo archivo es c2p01.cpp, es un void principal de un programa muy sencillo que limpia la pantalla y después espera una tecla, a modo de pausa, no escribe absolutamente nada:
#include "conio.h";
void main ( void )
{
clrscr ();
getch ();
}
La secuenciación comienza en la primera llave y termina en la segunda llave, las instrucciones lógicas son clrscr ( ); que limpia la pantalla y getch ( ); que aquí funciona como una pausa, obsérvense los paréntesis y el punto y coma que está enseguida, muy importantes en la sintaxis del clear-screen ( clrscr ) y del get-character ( getch ), la biblioteca a la que pertenecen es console-input-output ( conio ). Nótese que la sucesión contiene solamente dos instrucciones. El siguiente ejemplo corresponde al interior de un void que leerá la edad del usuario; se utiliza el void main y el void que lee la edad, se encuentra en c2p02.cpp:
#include "conio.h"
#include "stdio.h"
int edad;
void leeedad ( void )
{
clrscr ( );
printf ( "dame tu edad: " ); scanf ( "%d", &edad );
}
void main ( void )
{
leeedad ( );
}
Existen dos secuenciaciones, la primera incluye tres instrucciones importantes: limpia la pantalla, escribe "dame tu edad" y después lee la edad, y corresponde al void leeedad, la segunda secuenciación corresponde al void main, misma que invoca a leeedad ( ); la biblioteca conio ya se incluye, pero se debe incluir ahora a la biblioteca llamada standard-input-output ( stdio ). El tercer ejemplo es la misma secuenciación que corresponde al void leeedad, se encuentra en c2p03.cpp, pero ésta usa las otras instrucciones para leer y escribir:
void leeedad ( void )
{
clrscr ( );
cout << "dame tu edad: "; cin >> edad );
}
Se puede sustituir el procedimiento anterior por el void leeedad del segundo ejemplo, solo se necesita cambiar la biblioteca input-output-stream ( iostream ) por stdio en la sección de declaraciones de los "include", o bien, se puede dejar stdio y solamente incluir iostream, al final de cuentas, solamente es necesario que se incluya la biblioteca que se necesita. En otras palabras, pueden sobrar bibliotecas, pero no faltar, así que si sobra stdio en el tercer ejemplo, no ocurre nada significativo; todas las variables hasta ahora han sido declaradas como globales.
La siguiente operación básica es la decisión, ésta si está bien traducida, pues ya sería una exageración que desition no se hubiese traducido correctamente. Aunque originalmente se había llamado bifurcación, esto debido a que se hace una bifuración en el flujo del proceso en el algoritmo. Al tener dos opciones o dos caminitos para continuar, y decidir cual caminito tomar depende del valor de verdad de la condición ( 1 si es verdadera o si se cumple, y 0 si es falsa o si no se cumple ), si se cumple se toma el caminito de la derecha, si no se cumple se toma el caminito de la izquierda, después de haber tomado cualquiera de los dos caminitos llegaremos donde convergen los dos nuevamente y continuaremos con el programa.
Obsérvense las dos secuenciaciones, una inmediatamente después del if y de la condición, y la otra secuenciación inmediatamente después del else. Revisemos el ejemplo c2p04.cpp, se lee la edad y se indica si la edad es par o impar.
#include "conio.h"
#include "stdio.h"
int edad;
void leeedad ( void )
{
clrscr ( );
printf ( "\nDame tu edad: " ); scanf ( "%d", &edad );
}
void paroimpar ( void )
{
int a;
int b;
a = edad / 2;
b = a * 2;
if ( edad == b )
{
printf ( "\n%d Es Par", edad );
}
else
{
printf ( "\n%d Es Impar", edad );
}
}
void main ( void )
{
leeedad ( );
paroimpar ( );
getch ( );
}
Hay cinco secuenciaciones: leeedad, paroimpar, main, If y else. Tanto la secuenciación del if como la secuenciación del else están dentro de la secuenciación paroimpar. La decisión que se utiliza está dentro del void paroimpar, esta decisión se hace utilizando la división entera, si la edad es 5, entonces 5 / 2 será igual a 4, si la edad es 6, 6 / 2 será igual a 3. El siguiente ejemplo, dentro del archivo c2p05.cpp, hace algo similar, pero con un algoritmo diferente:
#include
#include "stdio.h"
#include "iostream.h"
int edad;
void leeedad ( void )
{
clrscr ( );
cout << "\nDame tu edad: "; cin >> edad;
}
void paroimpar ( void )
{
int a;
int b;
a = edad % 2;
if ( a == 0 )
{
cout << endl << edad << " Es Par" << endl;
}
else
{
cout << endl << edad << " Es Impar" << endl;
}
}
void main ( void )
{
leeedad ( );
paroimpar ( );
getch ( );
}
La forma en que se resuelve si la edad es par o impar es utilizando la operación módulo, si la edad es 6, 6 mod 2 ( 6 % 2 ), el resultado es igual a 0; si la edad es 7, entonces 7 mod 2 ( 7 % 2 ), el resultado es 1. También se utiliza endl, funciona similar a la señal del cursor "\n", hace salto de linea, la n es de line.
La tercera operación básica es la iteración. Dentro de esta operación podemos encontrar una variedad poco común. Existe la Controlada y la No-Controlada, dentro de la controlada están La Inteligente y La No-Inteligente. Usaremos la Iteración Controlada Inteligente, por ser la de mayor razonamiento lógico. La forma más fácil de identificar a la Iteración Controlada Inteligente es que primero pregunta y luego hace; la Iteración Controlada No Inteligente ( do { } while ( ); ) se identifica como que primero hace y luego pregunta, aunque esta no la incluiremos en este manual; la Iteración No Controlada ( for ( ) { } ) se identifica como que solo hace. Independientemente de cual sea la iteración, esta es la operación básica más difícil de aprender, por lo cual se propone que el alumno ponga mucha atención y practique muchas veces esta operación.
El seudocódigo, para la Iteración Controlada Inteligente es el siguiente:
Inicializa Elemento de Condición;
Mientras ( Condición )
Comienza
Procesa;
Actualiza Elemento de Condición;
Termina
La sintaxis de esta operación es bastante fácil, pero tan difícil de aprender. La palabra iteración proviene de iterar, que significa enciclar ( introducir dentro del ciclo ). Para poder entrar al ciclo de procesamiento de la iteración controlada inteligente se inicializa con lo que se pregunta en la condición, es decir, con el elemento de la condición; si es verdadera se entra al ciclo, una vez dentro del ciclo y después de procesar se actualiza lo que se ha de llevar a la condición; cuando la condición no se cumple se sale del ciclo y de esta forma se termina la iteración.
Como primer ejemplo de la iteración veamos el problema de verificar si la edad que se lee es par o impar varias veces, por cada vez que se desee ejecutar se preguntará si se desea hacerlo, ésta en el archivo c2p06.cpp. Se comenzará Inicializando el Elemento de Condición con la lectura de la respuesta a la pregunta si Desea Comenzar?, si la respuesta es el carácter s, entonces se entra al ciclo, comenzando a leer la edad y después a evaluarla para saber si es par o impar; terminando de evaluarla se lee la pregunta si se Desea Repetir?, si la respuesta es el carácter s, entonces se re-entra al ciclo, si la respuesta es diferente del carácter s, entonces se saldrá del ciclo inmediatamente.
El control Inteligente aquí, consiste en que antes de entrar al ciclo pregunta y luego hace, o bien, se sale. La parte que corresponde al procesamiento es cuando el void main invoca dentro del while a leeedad ( ); y a paroimpar ( );. La parte de Actualización del Elemento de Condición es cuando hace la pregunta si se desea repetir y se vuelve a leer la respuesta. El ciclo terminará entonces cuando la respuesta sea un carácter diferente del carácter s.
Se agrega la biblioteca character-type ( ctype ) para utilizar la función tolower que convierte un caracter en minúscula, si es que estuviese escrito originalmente en mayúscula, esto significa que si introduzco una S tolower la convierte en s, si introduzco una s tolower la deja igual.
#include
#include "stdio.h"
#include "iostream.h"
#include "ctype.h"
char respuesta;
int edad;
void paroimpar ( void )
{
int a;
int b;
a = edad % 2;
if ( a == 0 )
{
cout << endl << edad << " Es Par" << endl;
}
else
{
cout << endl << edad << " Es Impar" << endl;
}
}
void leeedad ( void )
{
clrscr ( );
cout << "\nDame tu edad: "; cin >> edad;
}
void main ( void )
{
cout << endl << "Desea Comenzar ( s / n )?: ";
respuesta = getche ( );
respuesta = tolower ( respuesta );
while ( respuesta == 's' )
{
leeedad ( );
paroimpar ( );
cout << endl << "Desea Repetir ( s / n )?: ";
respuesta = getche ( );
respuesta = tolower ( respuesta );
}
getch ( );
}
Todas las variables son variables globales. Así como también se han omitido los pasos de parámetros para revisarse en el siguiente capítulo. Es muy importante señalar que la forma en que está dispuesto el void main, este está al final después de todas las declaraciones de todos los voids. Más adelante se verá la forma de poner al void main, al principio de la edición y sobretodo antes de declarar los voids. Otra cosa importante que se debe notar es que los voids leeedad y paroimpar, están tal como fueron hechos en c2p04.cpp y en c2p05.cpp, esto significa que este último programa se le agregó el while para poder repetir la ejecución: inicializo preguntando si deseo comenzar, pregunto antes de hacer, como la respuesta fue s, dentro del ciclo proceso con leeedad y paroimpar, actualizo preguntando si deseo repetir. Por favor tener siempre en cuenta estos pasos pues siempre estarán en cada while que utilicemos.