martes, 11 de septiembre de 2012

SISTEMAS OPERATIVOS

Un lenguaje de programación es un manera de entender lo que dice y/o hace el ordenador y si entiendes su lenguaje puedes decirle que quieres que haga el ordenador. ¡Recuerda! El ordenador es idiota y solo va ha hacer lo que tú le digas, pero debes de fijarte bien que es lo que le pides hacer. Y el saber como debes de pedirle las cosas, no es tan sencillo como parece, ya que existen lenguajes de programación, como existen lenguajes (idiomas) en el mundo. Aquí encontrarás algunos de los lenguajes más comunes ó más usuales y/o más populares, en algunos casos ejemplos de uso.
Nota: Para algunos lectores es probable que sea la primera vez que vean un código en sí, pero no se espanten, ¡No! es necesario que aprendan algun lenguaje de programación para poder utilizar un SO(excepto casos especiales) sin embargo para información general existe esta pagina que te muestra unos ejemplos para que tengas idea de que algunas personas construyen su mundo con puro código.
De hecho para realizar un SO se necesita de un Lenguaje de Programación.
Al desarrollarse las primeras computadoras electrónicas, se vio la necesidad de programarlas, es decir, de almacenar en memoria la información sobre la tarea que iban a ejecutar. Las primeras se usaban como calculadoras simples; se les indicaban los pasos de cálculo, uno por uno.
John Von Neumann desarrolló el modelo que lleva su nombre, para describir este concepto de "programa almacenado". En este modelo, se tiene una abstracción de la memoria como un conjunto de celdas, que almacenan simplemente números. Estos números pueden representar dos cosas: los datos, sobre los que va a trabajar el programa; o bien, el programa en sí.
¿Cómo es que describimos un programa como números? Se tenía el problema de representar las acciones que iba a realizar la computadora, y que la memoria, al estar compuesta por switches correspondientes al concepto de bit, solamente nos permitía almacenar números binarios.
La solución que se tomó fue la siguiente: a cada acción que sea capaz de realizar nuestra computadora, asociarle un número, que será su código de operación (opcode). Por ejemplo, una calculadora programable simple podría asignar los opcodes:
1 = SUMA, 2 = RESTA, 3 = MULTIPLICA, 4 = DIVIDE.
Supongamos que queremos realizar la operación 5 * 3 + 2, en la calculadora descrita arriba. En memoria, podríamos «escribir» el programa de la siguiente forma:
Localidad Opcode Significado Comentario 0 5 5 En esta localidad, tenemos el primer número de la fórmula 1 3 * En esta localidad, tenemos el opcode que representa la multiplicación. 2 3 3 En esta localidad, tenemos el segundo número de la fórmula 3 1 + En esta localidad, tenemos el opcode que representa la suma. 4 2 2 En esta localidad, tenemos el último número de la fórmula.
Podemos ver que con esta representación, es simple expresar las operaciones de las que es capaz el hardware (en este caso, nuestra calculadora imaginaria), en la memoria.
La descripción y uso de los opcodes es lo que llamamos lenguaje de máquina . Es decir, la lista de códigos que la máquina va a interpretar como instrucciones, describe las capacidades de programación que tenemos de ella; es el lenguaje más primitivo, depende directamente del hardware, y requiere del programador que conozca el funcionamiento de la máquina al más bajo nivel.
los lenguajes más primitivos fueron los lenguajes de máquina. Esto, ya que el hardware se desarrolló antes del software, y además cualquier software finalmente tiene que expresarse en el lenguaje que maneja el hardware.
La programación en esos momentos era sumamente tediosa, pues el programador tenía que "bajarse" al nivel de la máquina y decirle, paso a pasito, cada punto de la tarea que tenía que realizar. Además, debía expresarlo en forma numérica; y por supuesto, este proceso era propenso a errores, con lo que la productividad del programador era muy limitada. Sin embargo, hay que recordar que en estos momentos, simplemente aún no existía alternativa.
El primer gran avance que se dio, como ya se comentó, fue la abstracción dada por el Lenguaje Ensamblador, y con él, el nacimiento de las primeras herramientas automáticas para generar el código máquina. Esto redujo los errores triviales, como podía ser el número que correspondía a una operación, que son sumamente engorrosos y difíciles de detectar, pero fáciles de cometer. Sin embargo, aún aquí es fácil para el programador perderse y cometer errores de lógica, pues debe bajar al nivel de la forma en que trabaja el CPU, y entender bien todo lo que sucede dentro de él.
Con el desarrollo en los 50s y 60s de algoritmos de más elevado nivel, y el aumento de poder del hardware, empezaron a entrar al uso de computadoras científicos de otras ramas; ellos conocían mucho de Física, Química y otras ramas similares, pero no de Computación, y por supuesto, les era sumamente complicado trabajar con lenguaje Ensamblador en vez de fórmulas. Así, nació el concepto de Lenguaje de Alto Nivel, con el primer compilador de FORTRAN (FORmula TRANslation), que, como su nombre indica, inició como un "simple" esfuerzo de traducir un lenguaje de fórmulas, al lenguaje ensamblador y por consiguiente al lenguaje de máquina. A partir de FORTRAN, se han desarrollado innumerables lenguajes, que siguen el mismo concepto: buscar la mayor abstracción posible, y facilitar la vida al programador, aumentando la productividad, encargándose los compiladores o intérpretes de traducir el lenguaje de alto nivel, al lenguaje de computadora.
Hay que notar la existencia de lenguajes que combinan características de los de alto nivel y los de bajo nivel (es decir, Ensamblador). Mi ejemplo favorito es C: contiene estructuras de programación de alto nivel, y la facilidad de usar librerías que también son características de alto nivel; sin embargo, fue diseñado con muy pocas instrucciones, las cuales son sumamente sencillas, fáciles de traducir al lenguaje de la máquina; y requiere de un entendimiento apropiado de cómo funciona la máquina, el uso de la memoria, etcétera. Por ello, muchas personas consideramos a lenguajes como C (que fue diseñado para hacer sistemas operativos), lenguajes de nivel medio.

Java

El lenguaje de programación Java fue diseñado por la compañía Sun Microsystems Inc, con el propósito de crear un lenguaje que pudiera funcionar en redes computacionales heterogéneas (redes de computadoras formadas por más de un tipo de computadora, ya sean PC, Mac, estaciones de trabajo, etc.),y que fuera independiente de la plataforma en la que se vaya a ejecutar. Esto significa que un programa de Java puede ejecutarse en cualquier máquina o plataforma. El lenguaje fue diseñado con las siguientes características en mente:
  • Simple. Elimina la complejidad de los lenguajes como «C» y da paso al contexto de los lenguajes modernos orientados a objetos. Orientado a Objetos. La filosofía de programación orientada a objetos es diferente a la programación convencional.
  • Familiar. Como la mayoría de los programadores están acostumbrados a programar en C o en C++, el sintaxis de Java es muy similar al de estos.
  • Robusto. El sistema de Java maneja la memoria de la computadora por ti. No te tienes que preocupar por apuntadores, memoria que no se esté utilizando, etc. Java realiza todo esto sin necesidad de que uno se lo indique.
  • Seguro. El sistema de Java tiene ciertas políticas que evitan se puedan codificar virus con este lenguaje. Existen muchas restricciones, especialmente para los applets, que limitan lo que se puede y no puede hacer con los recursos críticos de una computadora.
  • Portable. Como el código compilado de Java (conocido como byte code) es interpretado, un programa compilado de Java puede ser utilizado por cualquier computadora que tenga implementado el interprete de Java.
  • Independiente a la arquitectura. Al compilar un programa en Java, el código resultante un tipo de código binario conocido como byte code. Este códido es interpretado por diferentes computadoras de igual manera, solamente hay que implementar un intérprete para cada plataforma. De esa manera Java logra ser un lenguaje que no depende de una arquitectura computacional definida.
  • Multithreaded. Un lenguaje que soporta multiples threads es un lenguaje que puede ejecutar diferentes líneas de código al mismo tiempo.
  • Interpretado. Java corre en máquina virtual, por lo tanto es interpretado.
  • Dinámico. Java no requiere que compiles todas las clases de un programa para que este funcione. Si realizas una modificación a una clase Java se encarga de realizar un Dynamic Bynding o un Dynamic Loading para encontrar las clases.
Java puede funcionar como una aplicación sola o como un "applet", que es un pequeño programa hecho en Java. Los applets de Java se pueden "pegar" a una página de Web (HTML), y con esto puedes tener un programa que cualquier persona que tenga un browser compatible podrá usar.
Nota:Diferencia entre Java y CGI La diferencia es esencialmente simple, un CGI se ejecuta en el servidor mientras que un programa en Java se ejecuta en la máquina del usuario.
Java funciona de la siguiente manera: El compilador de Java deja el programa en un Pseudo-código (no es código maquinal) y luego el intérprete de Java ejecuta el programa (lo que se conoce como el "Java Virtual Machine"). Por eso Java es multiplataforma, existe un intérprete para cada máquina diferente. Nota: El código maquinal es el código binario que la computadora entiende y puede ejecutar.
Para entender bien cómo funciona un applet de Java vean el siguiente ejemplo:
  1. Existe un código de Java en un servidor de Web (los códigos de Java se caracterizan por tener la extensión *.class).
  2. Una persona en Internet, con un navegador compatible con Java, realiza una conexión al servidor.
  3. El servidor envía el documento HTML y el código en Java (*.class).
  4. En la computadora del usuario remoto llegan ambos, y la Máquina Virtual de Java, que está en el browser, transforma el código Java en un código que entienda la máquina local y se ejecuta el programa dentro de la página de Web.
  5. Si el usuario realiza otra conexión a otro URL o se sale del browser, el programa se deja de ejecutar y en la computadora no queda rastro de el.

Ejemplo de tutorial de Java

En Java hay tres tipos de comentarios:
// comentarios para una sola línea
/* comentarios de una o

más líneas

*/
/** comentario de documentación, de una o más líneas

*/
Los dos primeros tipos de comentarios son los que todo programador conoce y se utilizan del mismo modo. Los comentarios de documentación, colocados inmediatamente antes de una declaración (de variable o función), indican que ese comentario ha de ser colocado en la documentación que se genera automáticamente cuando se utiliza la herramienta de Java, javadoc. Dichos comentarios sirven como descripción del elemento declarado permitiendo generar una documentación de nuestras clases escrita al mismo tiempo que se genera el código.
En este tipo de comentario para documentación, se permite la introducción de algunos tokens o palabras clave, que harán que la información que les sigue aparezca de forma diferente al resto en la documentación.

Identificadores

Los identificadores nombran variables, funciones, clases y objetos; cualquier cosa que el programador necesite identificar o usar.
En Java, un identificador comienza con una letra, un subrayado (_) o un símbolo de dólar ($). Los siguientes caracteres pueden ser letras o dígitos. Se distinguen las mayúsculas de las minúsculas y no hay longitud máxima.
Serían identificadores válidos:
identificador
nombre_usuario
Nombre_Usuario
_variable_del_sistema
$transaccion
y su uso sería, por ejemplo:
int contador_principal;
char _lista_de_ficheros;
float $cantidad_en_Ptas;

Unix

Ejemplo de Unix

No todo el «árbol» de directorios está compuesto por directorios de usuario. Existen muchos de ellos que son de uso general o del propio sistema y con los que habrá que familiarizarse. Los más importantes son:
/
El raíz, del que "cuelgan" todos.
/bin y /usr/bin
Contienen comandos UNIX ejecutables.
/etc
Es quizá el directorio más importante. Contiene ficheros de datos y configuración del sistema, el fichero de password, configuración de terminales, red, etc (de ahí su nombre).
/dev
Ficheros de dispositivos E/S.
/usr/man
Manual
/tmp
Directorio para arreglos temporales. TODOS los usuarios pueden leer y escribir en él.

C++

C es un lenguaje de programación diseñado por Dennis Ritchie, de los Laboratorios Bell, y
se instaló en un PDP-11 en 1972; se diseñó para ser el lenguaje de los Sistemas Operativos
UNIX1. A su vez, UNIX es un Sistema Operativo desarrollado por Ken Thompson, quién
utilizó el lenguaje ensamblador y un lenguaje llamado B para producir las versiones originales de UNIX, en 1970. C se inventó para superar las limitaciones de B.
C es un lenguaje maduro de propósitos generales que se desarrolló a partir de estas raíces;
su definición aparece en 1978 en el apéndice ``C Reference Manual del libro The C
Programming Language, de Brian W. Kernighan y Dennis M. Ritchie (Englewood Cliffs,
Nueva Jersey, Prentice-Hall 1978), pero el estándar recomendable más reciente apareció en
junio de 1983, en el documento de los Laboratorios Bell titulado The C Programming
Language-Reference Manual, escrito por Dennis M. Ritchie

Un programa en C

Generalizando, un programa en C consta de tres secciones. La primera sección es donde van todos los ``headers. Estos ``headers son comúnmente los ``#define y los ``#include. Como segunda sección se tienen las ``funciones. Al igual que Pascal, en C todas las funciones que se van a ocupar en el programa deben ir antes que la función principal (main()). Declarando las funciones a ocupar al principio del programa, se logra que la función principal esté antes que el resto de las funciones. Ahora, solo se habla de funciones ya que en C no existen los procedimientos.
Y como última sección se tiene a la función principal, llamada main. Cuando se ejecuta el programa, lo primero que se ejecuta es esta función, y de ahí sigue el resto del programa.
Los símbolos { y } indican ``begin y ``end respectivamente. Si en una función o en un ciclo while, por ejemplo, su contenido es de solamente una línea, no es necesario usar ``llaves ({ }), en caso contrario es obligación usarlos.

Ejemplo de un programa en C

/*Programa ejemplo que despliega el contenido de "ROL" en pantalla*/
  1. include <stdio.h>
  1. define ROL "9274002-1"
despliega_rol() {
printf("Mi rol es : \%s\n", ROL);
}
void main() {
despliega_rol();
}
/* Fin programa */

Pascal

Pascal es un lenguaje de programación de alto nivel de propósito general; esto es, se puede utilizar para escribir programas para fines científicos y comerciales.
El lenguaje de programación Pascal fue desarrollado por el profesor Niklaus (Nicolás) Wirth en Zurich, Suiza, al final de los años 1960s y principios de los 70s. Wirth diseñó este lenguaje para que fuese un buen primer lenguaje de programación para personas comenzando a aprender a programar. Pascal tiene un número relativamente pequeño de conceptos para aprender y dominar. Su diseño facilita escribir programas usando un estilo que está generalmente aceptado como práctica estándar de programación buena. Otra de las metas del diseño de Wirth era la implementación fácil. Él diseñó un lenguaje para el cual fuese fácil escribir un compilador para un nuevo tipo de computadora.
program Sorting;

{ 

Este programa lee un natural y una secuencia de N caracteres de la entrada estandar; construye un indice para ordenarlos de menor a mayor e imprime en la salida la secuencia ordenada.

}

uses CRT;

Const Max = 10;

Espacio = ' ';

Enter = chr (13);

type Indice = 1..Max;

Cantidad= 0..Max;

SecOfChar = record

elems : array [Indice] of char;

ult : Cantidad;

end;

SecOfInd = record

elems : array [Indice] of Indice;

ult : Cantidad;

end;

Natural = 0..MaxInt;

function PosMin (idx: SecOfInd; i: Indice; s: SecOfChar): Cantidad;

{ Devuelve la posición en el indice idx del menor caracter en s, para

las posiciones >= i. }

var j: Indice;

pm: Cantidad;

begin

if i > idx.ult then

pm := 0

else begin 

pm := i;

for j := i+1 to idx.ult do

if s.elems[idx.elems[j]] < s.elems[idx.elems[pm]] then

pm := j;

end;

PosMin := pm;

end;

procedure Swap (var idx: SecOfInd; i,j: Indice);

{ Intercambia las posiciones i j en idx. }

var tmp: Indice;

begin

if (i<=idx.ult) and (j<=idx.ult) then begin

tmp := idx.elems[i];

idx.elems[i] := idx.elems[j];

idx.elems[j] := tmp;

end;

end;

procedure InicInds (var idx: SecOfInd; cant: Indice);

{ Construye la secuencia de indices 1,2,3,...,n. Sera el indice

inicial para el ordenamiento de una secuencia de caracteres

c1,c2,...,cn. }

var n: Natural;

begin

n := cant;

idx.ult := n;

while n > 0 do begin

idx.elems [n] := n;

n := n-1;

end;

end;

procedure InicSecChar (var s: SecOfChar);

{ Devuelve la secuencia vacia. }

begin

s.ult := 0;

end;

function Llena (s: SecOfChar): Boolean;

begin

Llena := s.ult = Max;

end;

{ PRE: not Llena(s) }

procedure InsCar (var s: SecOfChar; c: char);

{ Inserta el caracter c en la secuencia s }

begin

s.ult := s.ult + 1;

s.elems [s.ult] := c;

end;

procedure IndSelSort (s: SecOfChar; var ind: SecOfInd);

{ Construye el indice que ordena la secuencia s. Ordena el indice

inicial 1,2, ..., n por el metodo de selection sort }

var i: Indice;

begin

InicInds (ind, s.ult);

for i := 1 to ind.ult-1 do begin

Swap (ind, i, PosMin (ind, i, s));

end

end;

procedure WriteSorted (idx: SecOfInd; s: SecOfChar);

{ Imprime en la salida estandar la secuencia s ordenada segun el

indice idx }

var i: Indice;

begin

write ('Ordenado: ');

for i := 1 to idx.ult do

write (s.elems[idx.elems[i]],' ');

writeln;

end;

procedure LeerCar (var c: char; var ok: boolean; sep: Char);

{ Lee de la entrada estandar un caracter seguido del caracter sep }

var c1, c2: char;

begin

c := ReadKey; write (c);

c1 := ReadKey; write (c1);

ok := c1 = sep;

end;

procedure LeerSecOfChar (var s: SecOfChar; cant: Natural; var ok: Boolean);

{ Construye una secuencia de cant caracteres provistos por el

procedimeinto LeerCar. Si cant > Max trunca. }

var bien: Boolean;

i: Natural;

ch, sep: Char;

begin

writeln ('Ingrese ',cant, ' caracteres separados por blancos. Enter para terminar ');

write (' > ');

InicSecChar (s);

i := 1;

ok := true;

sep := Espacio;

while ok and (i <= cant) and not Llena (s) do begin

if i = cant then sep := Enter;

LeerCar (ch, bien, sep);

i := i+1;

ok := ok and bien;

if ok then

InsCar (s, ch);

end;

end;

procedure LeerCant (var n: Natural);

{ Lee de la entrada estandar un natural <= Max }

begin

repeat

writeln ('Ingrese cantidad de caracteres (<=',Max,')');

write (' > ');

readln (n);

until n <= Max;

end;

procedure Continuar (var seguir: Boolean);

var car: Char;

begin

writeln;

writeln ('Otro ? (s/n)');

write (' > ');

car := ReadKey;

writeln (car);

seguir := car in ['s','S'];

end;

var cant: Natural;

cars: SecOfChar;

inds: SecOfInd;

seguir, ok: boolean;

begin

repeat

ClrScr;

LeerCant (cant);

LeerSecOfChar (cars, cant, ok);

if ok then begin

IndSelSort (cars, inds);

writeln;

WriteSorted (inds, cars);

end

else begin

writeln;

writeln ('Error en los datos');

end;

Continuar (seguir);

until not seguir;

end.

QBasic

QBasic es un lenguaje de alto nivel, el cual consiste en instrucciones que los humanos pueden relacionar y entender. El compilador de Qbasic se encarga de traducir el mismo a lenguaje de máquina.
Un programa es una secuencia de instrucciones. El proceso de ejecutar esas instrucciones se llama correr el programa. Los programas contienen las funciones de entrada, procesamiento y salida. La persona que resuelve problemas mediante escribir programas en la computadora se conoce como programador. Después de analizar el problema y desarrollar un plan para solucionarlo, escribe y prueba el programa que instruye a la computadora como llevar a cabo el plan. El procedimiento que realiza el programador se define como "problem solving". Pero es necesario especificar que un programador y un usuario no son lo mismo. Un usuario es cualquier persona que use el programa.

Ejemplo de QBasic

Ejemplo para hacer una calculadora:
DIM total AS DOUBLE
DIM number AS DOUBLE
DIM secondNumber AS DOUBLE
DIM more AS STRING
DIM moreNumbers AS STRING
DIM operation AS STRING

total = 0

more = "y"

moreNumbers = "c"

CLS

WHILE more = "y"

INPUT "Enter the first number"; number

total = number

WHILE moreNumbers = "c"

COLOR 14

PRINT "The total is:"; total

COLOR 7

PRINT "Select an operation"

COLOR 2

PRINT "(+)"

COLOR 5

PRINT "(-)"

COLOR 1

PRINT "(x)"

COLOR 4

INPUT "(/)"; operation

COLOR 7

CLS

IF operation = "+" THEN

REM where we do additions

PRINT "Enter the number to Add to"; total

INPUT secondNumber

total = secondNumber + total

COLOR 14

PRINT "The total is now:"; total

COLOR 7

ELSE

IF operation = "-" THEN

REM subtraction

PRINT "Enter the number to Subtract from"; total

INPUT secondNumber

total = total - secondNumber

COLOR 14

PRINT "The total is now:"; total

COLOR 7

ELSE

IF operation = "x" THEN

REM multiplication

PRINT "Enter the number to Multiply"; total; "by"

INPUT secondNumber

total = secondNumber * total
REM * is the multiplication sign in programs

COLOR 14

PRINT "The total is now:"; total

COLOR 7

ELSE

IF operation = "/" THEN

REM division

PRINT "Enter the number to Divide"; total; "by"

INPUT secondNumber

IF secondNumber = 0 THEN

COLOR 4

PRINT "You cannot divide by zero"

COLOR 7

ELSE

total = total / secondNumber
REM / is the division sign in programs

END IF

COLOR 14

PRINT "The total is now:"; total

COLOR 7

ELSE

PRINT "you must select an operation"

END IF

END IF

END IF

END IF

INPUT "Do you wish to continue (c) or start with new numbers

(n)";moreNumbers

CLS

WEND

COLOR 14

PRINT "The grand total is:"; total

COLOR 7

INPUT "Do you wish to make more calculations (y - n)"; more

moreNumbers = "c"
REM if we don't put "moreNumbers" back to y, it will always
REM come back to "Do you wish to make more calculations" and never REM ask

for numbers again

REM (try it)

total = 0
REM if we don't reset the total to 0, it will just
REM keep on adding to the total

WEND 

END

Linux

Linux es una implementación del sistema operativo UNIX (uno más de entre los numerosos clónicos del histórico Unix), pero con la originalidad de ser gratuito y a la vez muy potente, que sale muy bien parado (no pocas veces victorioso) al compararlo con las versiones comerciales para sistemas de mayor envergadura y por tanto teóricamente superiores. Comenzó como proyecto personal del –entonces estudiante- Linus Torvalds, quien tomó como punto de partida otro viejo conocido, el Minix de Andy. S. Tanenbaum (profesor de sistemas operativos que creó su propio sistema operativo Unix en PCs XT para usarlo en su docencia). Actualmente Linus lo sigue desarrollando, pero a estas alturas el principal autor es la red Internet, desde donde una gigantesca familia de programadores y usuarios aportan diariamente su tiempo aumentando sus prestaciones y dando información y soporte técnico mútuo. La versión original -y aun predominante- comenzó para PCs compatibles (Intel 386 y superiores), existiendo también en desarrollo versiones para prácticamente todo tipo de plataformas, entre otras:
De todas ellas la más reciente en este momento es la versión para PowerMac <http://www.mklinux.org> (el PowerPC de Apple) basada en el microkernel Mach 3.0 y de la que ya hay una distribución para desarrolladores avalada directamente por Apple y OSF pero conservando el espíritu (gratuito, de libre distribución, etc) de la version original. Un servidor la acaba de probar hace unos días y se ha llevado una grata sorpresa (aún tendrá muuuchos fallos, pero para ser una primerísima versión y el poco tiempo que lleva en marcha, ha avanzado más de lo que me esperaba).

Ejemplo de Linux

Compilar el Kernel
Dado que un diskette sólo almacena 1.44 Megabytes (1440 Kilobytes) de datos, no puedes el mismo kernel que utilizas al diskette. Primero debes conseguir los fuentes del núcleo y descomprimirlos en /usr/src/linux. Luego ejecuta la siguiente orden desde el directorio
/usr/src/linux:
make config
Configura solamente aquello que realmente necesites. Yo, personalmente, sólo configuro el soporte para "ext2", soporte para la disquetera (floppy disk), y soporte para "PPP". Tus elecciones pueden se diferentes en función de lo que decidas incluir. Ahora introduce el siguiente comando:
make dep; make clean; make zImage
¡make zImage es muy importante! Comprime el kernel definitivo. Después de que termine la compilación, deberás buscar el nuevo núcleo en /usr/src/linux/arch/i386/boot bajo el
nombre de zImage.
El sistema de ficheros: No es solamente un conjunto de ficheros
Ahora hemos de crear el sistema de ficheros (en inglés: filesystem, fs) para el diskette. En vez de copiar los ficheros tal cual directamente al diskette, los comprimiremos antes de copiarlos. Esto nos hará un poco más difícil la faena de modificar todo permanentemente. Primero tecleamos el siguiente
comando:
dd if=/dev/zero of=[DEVICE] bs=1k count=3000
Donde [DEVICE] es "lugar" en el disco duro donde vas a guardar el sistema de ficheros descomprimido. Luego, introduce el siguiente comando y pulsa ENTER, sustituyendo [DEVICE] por el directorio en tu disco duro donde estás guardando el sistema de ficheros descomprimido:
mke2fs -m 0 [DEVICE]
Si make2fs te pregunta si realmente quieres hacer esto (Do you really want to do this?), acepta tecleando "y" (yes).
Después tenemos que montar este sistema de ficheros que hemos creado. Para ello, el núcleo que utilices tiene que permitir "montar ficheros", en otras palabras, ha de tener habilitada la posibilidad de "loopback devices". Para ello has de compilar el núcleo de tu máquina (no el núcleo que hemos creado, sino el de tu propia máquina) con la opción:
Loopback device support (CONFIG_BLK_DEV_LOOP) [M/n/y/?]
bien como módulo (M) o en el mismo núcleo (Y). Si lo compilas como módulo (lo más recomendable) luego tienes que insertar el módulo modprobe loop !No olvides rearrancar la máquina si has tenido que recompilar el núcleo!
mount -t ext2 DEVICE /mnt
Si se queja la orden mount puedes intentar con la siguiente orden:
mount -o loop -t ext2 DEVICE /mnt
Ahora debes copiar todos los ficheros que necesites en el nuevo sistema de ficheros. Primero, ponte en el directorio /mnt, (cd /mnt), y crea los siguientes directorios:
/dev
/pro
/etc
/bin
/lib
/mnt
/usr
Ahora crearemos el directorio /dev tecleando lo siguiente:
cp -dpR /dev /mnt/dev
Si se te acaban los i-nodos del diskette, puedes ir a /mnt/dev y borrar los archivos de dispositivo que no necesites. Cuando acabes de copiar los ficheros necesarios para /dev, ves a /etc. Para estar seguro copia todos los ficheros de /etc a /mnt/etc:
cp -dpR /etc /mnt/etc
Luego copia todo del directorio /lib en /mnt:
cp -dpR /lib /mnt/lib
Para el directorio /bin, copia sólo aquello que creas que necesitas en /mnt/bin.
Copiar todo a tu diskette
Ahora hemos de copiar todo en el/los diskette/s. Para hacer esto, debemos comprimir ahora el sistema de ficheros tecleando las siguientes ordenes:
cd /

umount /mnt

dd if=[DEVICE] bs=1k | gzip -9 > rootfs.gz
Ahora es importante comprobar el tamaño del núcleo. Ponte en /usr/src/linux/arch/i386/boot y teclea "ls -l". Luego divide el tamaño del núcleo entre 1024.
Por ejemplo, si el tamaño es de 250000 bytes, entonces son 245 KB. En adelante, reemplaza [ROOTBEGIN] en las ordenes que aparezca por el número total de kilobytes que has calculado. Ahora copia el kernel al diskette usando el siguiente comando:
dd if=zImage of=/dev/fd0
Este comando grabará el kernel en el diskette. Luego introduce el siguiente comando para que el kernel pueda encontrar la raíz del sistema de ficheros en el diskette.
rdev /dev/fd0 /dev/fd0
Ahora tendrás que hacer un pequeño cálculo en hexadecimal. Suma 4000 al equivalente en hexadecimal de [ROOTBEGIN] (que en nuestro ejemplo es F5). Convierte el resultado a decimal y teclea el siguiente comando, sustituyendo 16629 con el resultado que tú has obtenido:
rdev -r /dev/fd0 16629
Finalmente, teclea lo siguiente para copiar el sistema de ficheros al diskette:
dd if=/rootfs.gz of=/dev/fd0 bs=1k seek=[ROOTBEGIN]
El sistema de ficheros raíz será copiado al diskette justo después del kernel. ¡Ya lo tienes! Para el segundo diskette, el proceso es más fácil. Copia los ficheros que quieras en el diskette. No obstante, para poder usar los ficheros que hay en el segundo disco, tendrás que entrar lo siguiente después de arrancar con el diskette:
mount /dev/fd0 /usr

Ensamblador

Cuando abstraemos los opcodes y los sustituimos por una palabra que sea una clave de su significado, a la cual comúnmente se le conoce como mnemónico, tenemos el concepto de Lenguaje Ensamblador. Así, podemos definir simplemente al Lenguaje Ensamblador de la siguiente forma:
Lenguaje Ensamblador es la primera abstracción del Lenguaje de Máquina, consistente en asociar a los opcodes palabras clave que faciliten su uso por parte del programador
Como se puede ver, el Lenguaje Ensamblador es directamente traducible al Lenguaje de Máquina, y viceversa; simplemente, es una abstracción que facilita su uso para los seres humanos. Por otro lado, la computadora no entiende directamente al Lenguaje Ensamblador; es necesario traducirle a Lenguaje de Máquina. Originalmente, este proceso se hacía a mano, usando para ello hojas donde se escribían tablas de programa similares al ejemplo de la calculadora que vimos arriba . Pero, al ser tan directa la traducción, pronto aparecieron los programas Ensambladores, que son traductores que convierten el código fuente (en Lenguaje Ensamblador) a código objeto (es decir, a Lenguaje de Máquina).
Una característica que hay que resaltar, es que al depender estos lenguajes del hardware, hay un distinto Lenguaje de Máquina (y, por consiguiente, un distinto Lenguaje Ensamblador) para cada CPU. Por ejemplo, podemos mencionar tres lenguajes completamente diferentes, que sin embargo vienen de la aplicación de los conceptos anteriores:
1.Lenguaje Ensamblador de la familia Intel 80x86 2.Lenguaje Ensamblador de la familia Motorola 68000 3.Lenguaje Ensamblador del procesador POWER, usado en las IBM RS/6000.
Tenemos 3 fabricantes distintos, compitiendo entre sí y cada uno aplicando conceptos distintos en la manufactura de sus procesadores, su arquitectura y programación; todos estos aspectos, influyen en que el lenguaje de máquina y ensamblador cambie bastante.

Ventajas y desventajas del Lenguaje Ensamblador

Una vez que hemos visto la evolución de los lenguajes, cabe preguntarse: ¿En estos tiempos «modernos», para qué quiero el Lenguaje Ensamblador?
El proceso de evolución trajo consigo algunas desventajas, que ahora veremos como las ventajas de usar el Lenguaje Ensamblador, respecto a un lenguaje de alto nivel:
  1. Velocidad.
  2. Eficiencia de tamaño.
  3. Flexibilidad.
Por otro lado, al ser un lenguaje más primitivo, el Ensamblador tiene ciertas desventajas respecto a los lenguajes de alto nivel:
  1. Tiempo de programación.
  2. Programas fuente grandes.
  3. Peligro de afectar recursos inesperadamente.
  4. Falta de portabilidad.

Velocidad

El proceso de traducción que realizan los intérpretes, implica un proceso de cómputo adicional al que el programador quiere realizar. Por ello, nos encontraremos con que un intérprete es siempre más lento que realizar la misma acción en Lenguaje Ensamblador, simplemente porque tiene el costo adicional de estar traduciendo el programa, cada vez que lo ejecutamos.
De ahí nacieron los compiladores, que son mucho más rápidos que los intérpretes, pues hacen la traducción una vez y dejan el código objeto, que ya es Lenguaje de Máquina, y se puede ejecutar muy rápidamente. Aunque el proceso de traducción es más complejo y costoso que el de ensamblar un programa, normalmente podemos despreciarlo, contra las ventajas de codificar el programa más rápidamente.
Sin embargo, la mayor parte de las veces, el código generado por un compilador es menos eficiente que el código equivalente que un programador escribiría. La razón es que el compilador no tiene tanta inteligencia, y requiere ser capaz de crear código genérico, que sirva tanto para un programa como para otro; en cambio, un programador humano puede aprovechar las características específicas del problema, reduciendo la generalidad pero al mismo tiempo, no desperdicia ninguna instrucción, no hace ningún proceso que no sea necesario.
Para darnos una idea, en una PC, y suponiendo que todos son buenos programadores, un programa para ordenar una lista tardará cerca de 20 veces más en Visual Basic (un intérprete), y 2 veces más en C (un compilador), que el equivalente en Ensamblador.
Por ello, cuando es crítica la velocidad del programa, Ensamblador se vuelve un candidato lógico como lenguaje.
Ahora bien, esto no es un absoluto; un programa bien hecho en C puede ser muchas veces más rápido que un programa mal hecho en Ensamblador; sigue siendo sumamente importante la elección apropiada de algoritmos y estructuras de datos. Por ello, se recomienda buscar optimizar primero estos aspectos, en el lenguaje que se desee, y solamente usar Ensamblador cuando se requiere más optimización y no se puede lograr por estos medios.

Tamaño

Por las mismas razones que vimos en el aspecto de velocidad, los compiladores e intérpretes generan más código máquina del necesario; por ello, el programa ejecutable crece. Así, cuando es importante reducir el tamaño del ejecutable, mejorando el uso de la memoria y teniendo también beneficios en velocidad, puede convenir usar el lenguaje Ensamblador. Entre los programas que es crítico el uso mínimo de memoria, tenemos a los virus y manejadores de dispositivos (drivers). Muchos de ellos, por supuesto, están escritos en lenguaje Ensamblador.

Flexibilidad

Las razones anteriores son cuestión de grado: podemos hacer las cosas en otro lenguaje, pero queremos hacerlas más eficientemente. Pero todos los lenguajes de alto nivel tienen limitantes en el control; al hacer abstracciones, limitan su propia capacidad. Es decir, existen tareas que la máquina puede hacer, pero que un lenguaje de alto nivel no permite. Por ejemplo, en Visual Basic no es posible cambiar la resolución del monitor a medio programa; es una limitante, impuesta por la abstracción del GUI Windows. En cambio, en ensamblador es sumamente sencillo, pues tenemos el acceso directo al hardware del monitor.
Resumiendo, la flexibilidad consiste en reconocer el hecho de que
Todo lo que puede hacerse con una máquina, puede hacerse en el lenguaje ensamblador de esta máquina; los lenguajes de alto nivel tienen en una u otra forma limitantes para explotar al máximo los recursos de la máquina.

Tiempo de programación

Al ser de bajo nivel, el Lenguaje Ensamblador requiere más instrucciones para realizar el mismo proceso, en comparación con un lenguaje de alto nivel. Por otro lado, requiere de más cuidado por parte del programador, pues es propenso a que los errores de lógica se reflejen más fuertemente en la ejecución.
Por todo esto, es más lento el desarrollo de programas comparables en Lenguaje Ensamblador que en un lenguaje de alto nivel, pues el programador goza de una menor abstracción.
Programas fuente grandes
Por las mismas razones que aumenta el tiempo, crecen los programas fuentes; simplemente, requerimos más instrucciones primitivas para describir procesos equivalentes. Esto es una desventaja porque dificulta el mantenimiento de los programas, y nuevamente reduce la productividad de los programadores.
Peligro de afectar recursos inesperadamente
Tenemos la ventaja de que todo lo que se puede hacer en la máquina, se puede hacer con el Lenguaje Ensamblador (flexibilidad). El problema es que todo error que podamos cometer, o todo riesgo que podamos tener, podemos tenerlo también en este Lenguaje. Dicho de otra forma, tener mucho poder es útil pero también es peligroso.
En la vida práctica, afortunadamente no ocurre mucho; sin embargo, al programar en este lenguaje verán que es mucho más común que la máquina se «cuelgue», «bloquee» o «se le vaya el avión»; y que se reinicialice. ¿Por qué? porque con este lenguaje es perfectamente posible (y sencillo) realizar secuencias de instrucciones inválidas, que normalmente no aparecen al usar un lenguaje de alto nivel.
En ciertos casos extremos, puede llegarse a sobreescribir información del CMOS de la máquina (no he visto efectos más riesgosos); pero, si no la conservamos, esto puede causar que dejemos de "ver" el disco duro, junto con toda su información.

Falta de portabilidad

Como ya se mencionó, existe un lenguaje ensamblador para cada máquina; por ello, evidentemente no es una selección apropiada de lenguaje cuando deseamos codificar en una máquina y luego llevar los programas a otros sistemas operativos o modelos de computadoras. Si bien esto es un problema general a todos los lenguajes, es mucho más notorio en ensamblador: yo puedo reutilizar un 90% o más del código que desarrollo en «C», en una PC, al llevarlo a una RS/6000 con UNIX, y lo mismo si después lo llevo a una Macintosh, siempre y cuando esté bien hecho y siga los estándares de «C», y los principios de la programación estructurada. En cambio, si escribimos el programa en Ensamblador de la PC, por bien que lo desarrollemos y muchos estándares que sigamos, tendremos prácticamente que reescribir el 100% del código al llevarlo a UNIX, y otra vez lo mismo al llevarlo a Mac.

INTRODUCCION A LA PROGRAMACION

Introducción

Este libro esta hecho para personas que no tienen nociones sobre programación, para orientarlas en el tema y encaminarlas a los conceptos básicos de la programación y al desarrollo de programas utilizando algunos lenguajes de programación.

Programación

Se llama Programación a la implementación de un algoritmo en un determinado lenguaje de programación, para realizar un programa.
Algoritmo es una secuencia no ambigua, finita y ordenada de instrucciones que han de seguirse para resolver un problema.
Programa (Software en inglés) es una secuencia de instrucciones que una computadora puede interpretar y ejecutar.
El proceso de creación de software es materia de la ingeniería del software, una de las ramas propias de la Ingeniería Informática.
Según Niklaus Wirth un programa está formado por algoritmos y estructura de datos.
Se han propuesto diversas técnicas de programación, cuyo objetivo es mejorar tanto el proceso de creación de software como su mantenimiento. Entre ellas se pueden mencionar las programaciones lineal, estructurada, modular y orientada a objetos.

Lenguajes de Programación

Lenguaje de programación es el idioma utilizado para controlar el comportamiento de una máquina, particularmente una computadora. Consiste en un conjunto de símbolos y reglas sintácticas y semánticas que definen su estructura y el significado de sus elementos y expresiones.
Hay muchos lenguajes de programación, pero para programar no es necesario conocer todos los lenguajes, es igual que cuando hablamos, podemos comunicarnos en español aunque no sepamos alemán. Aunque la palabra deberia ser idioma ya que lenguaje realmente abarca todos los idiomas pero en computación equivocadamente se usa el término lenguaje cuando el término correcto es idiomas de programación.
En la actualidad los lenguajes de programación estan escritos para ser compresibles por el ser humano, a este código se le llama código fuente, pero no es comprendido por la máquina ya que esta solo maneja el lenguaje binario.
La compilación es el proceso de traducir un programa en código fuente a programa en código objeto (que usa el lenguaje binario), el programa encargado de compilar se llama compilador. La mayoria de software de programación trae su propio compilador.

Tipos de lenguajes de programación

Los lenguajes de programación se clasifican en varios tipos, los hay por nivel, y por la forma como se ejecutan.
Por nivel: Hay lenguajes de programación de alto nivel y lenguajes de bajo nivel. Los lenguajes de alto nivel permiten que con pocas palabras se logre hacer lo mismo que se logra con un lenguaje de bajo nivel.
Ejemplos de lenguajes de alto nivel: C++, Python, Java Ejemplos de lenguaje de bajo nivel: assembler
Por la forma como se ejecutan Hay lenguajes compilados e interpretados.
Los lenguajes compilados necesitan de un programa especial que lea el código fuente y cree un archivo binario ejecutable para una plataforma específica. Ejm: C++, Pascal.
Los lenguajes interpretados necesitan de un programa que traduzca en directo el código fuente escrito a instrucciones de la plataforma en la que se ejecutan. Ejm: Python, Visual Basic Script.
Los primeros son más rápidos, mientras que los segundos son más lentos, esto debido a que al compilar un programa las ordenes son más entendibles para la computadora, mientras que al interpretarlo la máquina primero debe leer el código y convertir al paso las instrucciones a instrucciones de máquina entendibles para ella.

Entorno de Desarrollo Integrado

Entorno de Desarrollo Integrado (en inglés Integrated Development Environment 'IDE'): Es un programa compuesto por un conjunto de herramientas para un programador. Estos IDE son programas que sirven para programar, ya sea en un lenguaje de programación o en varios lenguajes. Los IDE que permiten crear programas en muchos lenguajes de programación permiten usar un solo programa para trabajar en varios lenguajes de programación, es decir no limitan al programador.

TECNICAS BASICAS DE PROGRAMACION

La programación estructurada sigue tres reglas: la secuencia, la iteración y la decisión. La primera de ellas indica que las instrucciones del código se leerán de principio a fin; la segunda indica que, según cierta condición, un número de instrucciones podrían repetirse un numero determinado de veces, y la tercera indica que según unas ciertas condiciones se ejecutarán o no un conjunto de instrucciones. En el siguiente algoritmo para limpiar platos se aprecian estas tres características. La indentación de las instrucciones indican cuáles son englobadas y cuáles no por sus predecesoras.
  mientras haya platos
     coger plato
     mientras haya suciedad
        echar jabon
        pasar el estropajo por el plato
     si plato es azul
        ponerlo con los azules
En código no estructurado, quedaría algo más lioso.
  1 coger plato
  2 echar jabon
  3 pasar el estropajo por el plato
  4 si hay suciedad ir a la instrucción 2
  5 si el plato no es azul ir a la instrucción 7
  6 ponerlo con los azules
  7 si hay más platos ir a la instrucción 1

En programas más grandes, esto es muchísimo más lioso.
Ahora conocemos la ejecución de los algoritmos. Sin embargo, un programa se compone tanto de algoritmos como de una estructura de datos sobre los que operar.

Antes de empezar un programa

Estructura de un programa

En la programación estructurada hay un inicio y un fin perfectamente bien definido de acuerdo al diagrama de flujo que se planteó al concebir la idea del programa.
Un programa bien estructurado debería tener algún subprograma que capture cualquier error dentro del programa principal o de cualquier subprograma dentro de la aplicación de tal modo que el subprograma que captura los errores genere un registro de datos que describa el error generado y/o en qué subprograma se generó el error para posteriormente corregirlo. Para facilitar la corrección de estos errores se hace uso de los comentarios agregados en el código fuente.

Variables y constantes

Como hemos visto, el ordenador sigue una serie de instrucciones. Pero esas instrucciones tienen que operar sobre una serie de datos. El ordenador típico sólo procesa una instrucción a la vez, por lo que necesita 'espacios de memoria' donde guardar o depositar, a modo de cajones, por usar un símil conocido, los diversos datos con los que trabaja. Aquí es donde entran en juego las variables y constantes.
En los inicios, con el ensamblador, se podía decir al ordenador, por ejemplo: 'Ejecuta la instrucción de esa posición de memoria' o también 'En esa posición de memoria está guardada mi edad, imprímela por pantalla'. Todo esto se deriva del hecho de que los programas también son datos. Esta ambigüedad presenta numerosos inconvenientes cuando se producen errores, como el lector se imaginará fácilmente: de ahí que, a medida que los lenguajes promocionan hacia niveles superiores, se impida el tratamiento indistinto de los datos. A partir de entonces, un programa tiene que decirle al sistema operativo los cajones que necesita y éste se los proporciona independientemente de cuáles sean.
Quizás suene más complicado de lo que es. Un ejemplo: Queremos sumar dos números. Nuestro programa tendrá que tener tres cajones: Uno para cada número y otro para el resultado. Cada cajón tiene un nombre en vez de una posición de memoria, de manera que sólo hay que nombrarlo:
  Necesito cajones A, B y Resultado
  Lee un número y guárdalo en A
  Lee un número y guárdalo en B
  Suma A y B y guárdalo en Resultado
  Imprime el contenido de Resultado
He aquí nuestro programa. Como cabe pensar, un procesador no tiene la instrucción "Imprime por pantalla"; esto es una llamada a otra porción de código que, gracias a la abstracción, nosotros no hemos escrito, o hemos escrito una sóla vez; a partir de lo cual podemos imprimir todo el texto que queramos en la pantalla.
Las posiciones de memoria A y B son Variables. Si queremos leerlas o escribirlas, podemos hacerlo. Típicamente, existirán datos que no pensamos modificar; no querremos que el usuario tenga que introducirlos cada vez, pues son de naturaleza más constante que otros (como puede ser el valor Pi para calcular el perímetro o área de un círculo). Para evitar modificarlos por error, podemos pedir al sistema variables especiales, que no puedan ser reescritas. Son las Constantes. Un ejemplo:
  Comentario: Este programa calcula el área de un círculo
  Constante PI = 3'14159265
  Variable R
  Variable Resultado
  Leer número y guardar en R
  Calcular PI * (R * R) y guardar en Resultado
  Imprimir Resultado

El uso de variables y constantes se asemeja al uso que se les da en el álgebra o en otras ramas matemáticas.
Nótese también la clara separación entre estructuras de datos y algoritmos. Según los lenguajes, esto puede ser o no obligatorio, pero es recomendable en aras de una mayor claridad del trabajo.

Comentarios

El útil concepto del comentario: son líneas de texto que el compilador o el intérprete no consideran como parte del código, con lo cual no están sujetas a restricciones de sintaxis y sirven para aclarar partes de código en posteriores lecturas y, en general, para anotar cualquier cosa que el programador considere oportuno.
Uno como programador debe tener como prioridad documentar nuestro código fuente ya que al momento de depurar nos ahorrará mucho tiempo de analisis para su corrección o estudio.
Los programadores profesionales tienen la buena costumbre de documentar sus programas con encabezados de texto(encabezados de comentarios) en donde describen la función que va a realizar dicho programa, la fecha de creación, el nombre del autor y en algunos casos las fechas de revisión y el nombre del revisor.
Por lo general algunos programas requieren hacer uso de llamadas a subprogramas dentro de una misma aplicación por lo que cada subprograma debería estar documentado, describiendo la función que realizan cada uno de estos subprogramas dentro de la aplicación.

Estructuras de datos y de control

Estructuras de control

Las estructuras de control pueden dividirse en dos: Estructuras de control Condicional y Estructuras de control Repetitivo.
Las estructuras de control condicional son las que incluyen alternativas de seleccion con base al resultado de una operación booleana, como por ejemplo, una comparación (A=B). Según la expresión sea cierta o falsa, se ejecutará un trozo de código u otro. Es el caso de la sentencia IF THEN ELSE de Pascal o Basic:
  IF A=0 THEN
       PRINT "A vale 0"
  ELSE
       PRINT "A no vale 0"
Otra sentencia de control son las de tipo SWITCH CASE. En este tipo de sentencias se especifica la variable a comparar y una lista de valores con lo que comparar. Aquel que sea el verdadero, se ejecutará:
   SWITCH A
       CASE 0:
           PRINT "A vale 0"
       CASE 1:
           PRINT "A vale 1"
Otras herramientas imprescindibles del control de la ejecución de nuestro código son los BUCLES o CICLOS. Consisten en un método que permite repetir un trozo de código varias veces.
Hay básicamente dos tipos:
- Bucle FOR:
El bucle FOR consiste en una sentencia que engloba un grupo de instrucciones y tiene una variable cuyo valor se va modificando en cada vuelta. En general se utiliza cuando sabemos cuántas veces tenemos que repetir el código.
    FOR A=0 TO 9   Especificamos en este caso que A variará desde 0 hasta 9, con lo que repetiremos el bucle 10 veces. 
        PRINT "Estamos en el bucle"      
    NEXT A          Con esto cerramos el bucle e indicamos el final del bloque de instrucciones que se repiten
- Bucle WHILE:
El bucle WHILE consiste en un bucle en el que el código se repite mientras se cumpla alguna condición booleana (es decir, una expresión que dé como resultado verdadero o falso). Hay variaciones, como el REPEAT...UNTIL, que se diferencia en el momento de comprobar si se hace verdadera o no la condición.
    WHILE A<>(B*2) DO            Aquí especificamos la expresión que evaluamos y aquí se comprueba
        A=A+1                    Incrementamos el valor de A mientras sea distinto a B*2
    DONE                         Como en el FOR, necesitamos especificar donde acaba el bucle y el código.

Estructuras de datos

creo a como entero
creo b como entero
creo suma como entero
a=2
b=1
suma = a + b
imprimir suma

Estructura de una aplicación. Cualquier programa que se realice debe llevar una estructura para disminuir la tarea de depuración ya que esta labor lleva más tiempo del estimado.
Si eres principiante en el área de programación debes definir el programa a realizar, documentar cada uno de los pasos que realizas en tu programa, debes de considerar algún metodo de captura de errores, etc.
En este subcapítulo abarcaremos el cómo estructurar una aplicación para mejorar o disminuir el tiempo en depuración, así como localizar más rápidamente los errores.
Puedes buscar en Internet el concepto "pseudocódigo", que no es más que la escritura de un algoritmo en un lenguaje más cercano al natural. Es decir, la orden en lenguaje Javascript que repetiría el proceso de quitar suciedad añadiendo agua y jabón mientras se frota sería la siguiente:
function frotar(cuanto){
  var veces = 0;
  for (veces = 0; suciedad < 0, veces < cuanto ; veces++){
    suciedad = suciedad - (agua + jabón);
  }
}
Mientras que el algoritmo o pseudocódigo quedaría así:
función frotar (cuantas veces lo hago)
  variable veces que llevo = 0
  repetir (desde que vecesquellevo = 0 mientras la suciedad < 0 ó vecesquellevo < cuantasveceslohago; aumentar vecesquellevo de una en una)
    suciedad = suciedad - (agua + jabón)
  fin repetir
fin función
En primer lugar, es muy recomendable hacer un esquema sobre el papel con toda clase de datos que se vayan a utilizar. Por ejemplo, si queremos hacer un programa para controlar una empresa dedicada al alquiler de coches, podríamos necesitar:
  • Matrícula del coche
  • Marca del coche
  • Modelo del coche
  • Color del coche
  • Estado del coche (si está alquilado, en reparación o disponible)
  • Situación del coche (en qué lugar del garaje o en qué localidad está)
  • Kilometraje del coche
  • Precio por hora del coche

La programación estructurada sigue tres reglas: la secuencia, la iteración y la decisión. La primera de ellas indica que las instrucciones del código se leerán de principio a fin; la segunda indica que, según cierta condición, un número de instrucciones podrían repetirse un numero determinado de veces, y la tercera indica que según unas ciertas condiciones se ejecutarán o no un conjunto de instrucciones. En el siguiente algoritmo para limpiar platos se aprecian estas tres características. La indentación de las instrucciones indican cuáles son englobadas y cuáles no por sus predecesoras.
  mientras haya platos
     coger plato
     mientras haya suciedad
        echar jabon
        pasar el estropajo por el plato
     si plato es azul
        ponerlo con los azules
En código no estructurado, quedaría algo más lioso.
  1 coger plato
  2 echar jabon
  3 pasar el estropajo por el plato
  4 si hay suciedad ir a la instrucción 2
  5 si el plato no es azul ir a la instrucción 7
  6 ponerlo con los azules
  7 si hay más platos ir a la instrucción 1

En programas más grandes, esto es muchísimo más lioso.
Ahora conocemos la ejecución de los algoritmos. Sin embargo, un programa se compone tanto de algoritmos como de una estructura de datos sobre los que operar.

Antes de empezar un programa

Estructura de un programa

En la programación estructurada hay un inicio y un fin perfectamente bien definido de acuerdo al diagrama de flujo que se planteó al concebir la idea del programa.
Un programa bien estructurado debería tener algún subprograma que capture cualquier error dentro del programa principal o de cualquier subprograma dentro de la aplicación de tal modo que el subprograma que captura los errores genere un registro de datos que describa el error generado y/o en qué subprograma se generó el error para posteriormente corregirlo. Para facilitar la corrección de estos errores se hace uso de los comentarios agregados en el código fuente.

Variables y constantes

Como hemos visto, el ordenador sigue una serie de instrucciones. Pero esas instrucciones tienen que operar sobre una serie de datos. El ordenador típico sólo procesa una instrucción a la vez, por lo que necesita 'espacios de memoria' donde guardar o depositar, a modo de cajones, por usar un símil conocido, los diversos datos con los que trabaja. Aquí es donde entran en juego las variables y constantes.
En los inicios, con el ensamblador, se podía decir al ordenador, por ejemplo: 'Ejecuta la instrucción de esa posición de memoria' o también 'En esa posición de memoria está guardada mi edad, imprímela por pantalla'. Todo esto se deriva del hecho de que los programas también son datos. Esta ambigüedad presenta numerosos inconvenientes cuando se producen errores, como el lector se imaginará fácilmente: de ahí que, a medida que los lenguajes promocionan hacia niveles superiores, se impida el tratamiento indistinto de los datos. A partir de entonces, un programa tiene que decirle al sistema operativo los cajones que necesita y éste se los proporciona independientemente de cuáles sean.
Quizás suene más complicado de lo que es. Un ejemplo: Queremos sumar dos números. Nuestro programa tendrá que tener tres cajones: Uno para cada número y otro para el resultado. Cada cajón tiene un nombre en vez de una posición de memoria, de manera que sólo hay que nombrarlo:
  Necesito cajones A, B y Resultado
  Lee un número y guárdalo en A
  Lee un número y guárdalo en B
  Suma A y B y guárdalo en Resultado
  Imprime el contenido de Resultado
He aquí nuestro programa. Como cabe pensar, un procesador no tiene la instrucción "Imprime por pantalla"; esto es una llamada a otra porción de código que, gracias a la abstracción, nosotros no hemos escrito, o hemos escrito una sóla vez; a partir de lo cual podemos imprimir todo el texto que queramos en la pantalla.
Las posiciones de memoria A y B son Variables. Si queremos leerlas o escribirlas, podemos hacerlo. Típicamente, existirán datos que no pensamos modificar; no querremos que el usuario tenga que introducirlos cada vez, pues son de naturaleza más constante que otros (como puede ser el valor Pi para calcular el perímetro o área de un círculo). Para evitar modificarlos por error, podemos pedir al sistema variables especiales, que no puedan ser reescritas. Son las Constantes. Un ejemplo:
  Comentario: Este programa calcula el área de un círculo
  Constante PI = 3'14159265
  Variable R
  Variable Resultado
  Leer número y guardar en R
  Calcular PI * (R * R) y guardar en Resultado
  Imprimir Resultado

El uso de variables y constantes se asemeja al uso que se les da en el álgebra o en otras ramas matemáticas.
Nótese también la clara separación entre estructuras de datos y algoritmos. Según los lenguajes, esto puede ser o no obligatorio, pero es recomendable en aras de una mayor claridad del trabajo.

Comentarios

El útil concepto del comentario: son líneas de texto que el compilador o el intérprete no consideran como parte del código, con lo cual no están sujetas a restricciones de sintaxis y sirven para aclarar partes de código en posteriores lecturas y, en general, para anotar cualquier cosa que el programador considere oportuno.
Uno como programador debe tener como prioridad documentar nuestro código fuente ya que al momento de depurar nos ahorrará mucho tiempo de analisis para su corrección o estudio.
Los programadores profesionales tienen la buena costumbre de documentar sus programas con encabezados de texto(encabezados de comentarios) en donde describen la función que va a realizar dicho programa, la fecha de creación, el nombre del autor y en algunos casos las fechas de revisión y el nombre del revisor.
Por lo general algunos programas requieren hacer uso de llamadas a subprogramas dentro de una misma aplicación por lo que cada subprograma debería estar documentado, describiendo la función que realizan cada uno de estos subprogramas dentro de la aplicación.

Estructuras de datos y de control

Estructuras de control

Las estructuras de control pueden dividirse en dos: Estructuras de control Condicional y Estructuras de control Repetitivo.
Las estructuras de control condicional son las que incluyen alternativas de seleccion con base al resultado de una operación booleana, como por ejemplo, una comparación (A=B). Según la expresión sea cierta o falsa, se ejecutará un trozo de código u otro. Es el caso de la sentencia IF THEN ELSE de Pascal o Basic:
  IF A=0 THEN
       PRINT "A vale 0"
  ELSE
       PRINT "A no vale 0"
Otra sentencia de control son las de tipo SWITCH CASE. En este tipo de sentencias se especifica la variable a comparar y una lista de valores con lo que comparar. Aquel que sea el verdadero, se ejecutará:
   SWITCH A
       CASE 0:
           PRINT "A vale 0"
       CASE 1:
           PRINT "A vale 1"
Otras herramientas imprescindibles del control de la ejecución de nuestro código son los BUCLES o CICLOS. Consisten en un método que permite repetir un trozo de código varias veces.
Hay básicamente dos tipos:
- Bucle FOR:
El bucle FOR consiste en una sentencia que engloba un grupo de instrucciones y tiene una variable cuyo valor se va modificando en cada vuelta. En general se utiliza cuando sabemos cuántas veces tenemos que repetir el código.
    FOR A=0 TO 9   Especificamos en este caso que A variará desde 0 hasta 9, con lo que repetiremos el bucle 10 veces. 
        PRINT "Estamos en el bucle"      
    NEXT A          Con esto cerramos el bucle e indicamos el final del bloque de instrucciones que se repiten
- Bucle WHILE:
El bucle WHILE consiste en un bucle en el que el código se repite mientras se cumpla alguna condición booleana (es decir, una expresión que dé como resultado verdadero o falso). Hay variaciones, como el REPEAT...UNTIL, que se diferencia en el momento de comprobar si se hace verdadera o no la condición.
    WHILE A<>(B*2) DO            Aquí especificamos la expresión que evaluamos y aquí se comprueba
        A=A+1                    Incrementamos el valor de A mientras sea distinto a B*2
    DONE                         Como en el FOR, necesitamos especificar donde acaba el bucle y el código.

Estructuras de datos

creo a como entero
creo b como entero
creo suma como entero
a=2
b=1
suma = a + b
imprimir suma

Estructura de una aplicación. Cualquier programa que se realice debe llevar una estructura para disminuir la tarea de depuración ya que esta labor lleva más tiempo del estimado.
Si eres principiante en el área de programación debes definir el programa a realizar, documentar cada uno de los pasos que realizas en tu programa, debes de considerar algún metodo de captura de errores, etc.
En este subcapítulo abarcaremos el cómo estructurar una aplicación para mejorar o disminuir el tiempo en depuración, así como localizar más rápidamente los errores.
Puedes buscar en Internet el concepto "pseudocódigo", que no es más que la escritura de un algoritmo en un lenguaje más cercano al natural. Es decir, la orden en lenguaje Javascript que repetiría el proceso de quitar suciedad añadiendo agua y jabón mientras se frota sería la siguiente:
function frotar(cuanto){
  var veces = 0;
  for (veces = 0; suciedad < 0, veces < cuanto ; veces++){
    suciedad = suciedad - (agua + jabón);
  }
}
Mientras que el algoritmo o pseudocódigo quedaría así:
función frotar (cuantas veces lo hago)
  variable veces que llevo = 0
  repetir (desde que vecesquellevo = 0 mientras la suciedad < 0 ó vecesquellevo < cuantasveceslohago; aumentar vecesquellevo de una en una)
    suciedad = suciedad - (agua + jabón)
  fin repetir
fin función
En primer lugar, es muy recomendable hacer un esquema sobre el papel con toda clase de datos que se vayan a utilizar. Por ejemplo, si queremos hacer un programa para controlar una empresa dedicada al alquiler de coches, podríamos necesitar:
  • Matrícula del coche
  • Marca del coche
  • Modelo del coche
  • Color del coche
  • Estado del coche (si está alquilado, en reparación o disponible)
  • Situación del coche (en qué lugar del garaje o en qué localidad está)
  • Kilometraje del coche
  • Precio por hora del coche
por un lado, y:
  • Nombre del cliente
  • Apellidos del cliente
  • Dirección del cliente
  • DNI del cliente
  • Permiso de conducir del cliente
  • Número de cuenta del cliente
... etc. por otro.

jueves, 16 de agosto de 2012

DIAGRAMAS DE FLUJO Y SU SIMBOLOGÍA

El diagrama de flujo es la representación gráfica del algoritmo o proceso. Se utiliza en disciplinas como la programación, la economía, los procesos industriales y la psicología cognitiva. Estos diagramas utilizan símbolos con significados bien definidos que representan los pasos del algoritmo, y representan el flujo de ejecución mediante flechas que conectan los puntos de inicio y de fin de proceso.

Características

Un diagrama de flujo siempre tiene un único punto de inicio y un único punto de término.
Las siguientes son acciones previas a la realización del diagrama de flujo:
  • Identificar las ideas principales a ser incluidas en el diagrama de flujo. Deben estar presentes el dueño o responsable del proceso, los dueños o responsables del proceso anterior y posterior y de otros procesos interrelacionados, otras partes interesadas.
  • Definir qué se espera obtener del diagrama de flujo.
  • Identificar quién lo empleará y cómo.
  • Establecer el nivel de detalle requerido.
  • Determinar los límites del proceso a describir.
Los pasos a seguir para construir el diagrama de flujo son:
  • Establecer el alcance del proceso a describir. De esta manera quedará fijado el comienzo y el final del diagrama. Frecuentemente el comienzo es la salida del proceso previo y el final la entrada al proceso siguiente.
  • Identificar y listar las principales actividades/subprocesos que están incluidos en el proceso a describir y su orden cronológico.
  • Si el nivel de detalle definido incluye actividades menores, listarlas también.
  • Identificar y listar los puntos de decisión.
  • Construir el diagrama respetando la secuencia cronológica y asignando los correspondientes símbolos.
  • Asignar un título al diagrama y verificar que esté completo y describa con exactitud el proceso elegido.

Ventajas de los diagramas de flujo

  • Favorecen la comprensión del proceso al mostrarlo como un dibujo. El cerebro humano reconoce muy fácilmente los dibujos. Un buen diagrama de flujo reemplaza varias páginas de texto.
  • Permiten identificar los problemas y las oportunidades de mejora del proceso. Se identifican los pasos, los flujos de los re-procesos, los conflictos de autoridad, las responsabilidades, los cuellos de botella, y los puntos de decisión.
  • Muestran las interfaces cliente-proveedor y las transacciones que en ellas se realizan, facilitando a los empleados el análisis de las mismas.
  • Son una excelente herramienta para capacitar a los nuevos empleados y también a los que desarrollan la tarea, cuando se realizan mejoras en el proceso.
  • Al igual que el pseudocódigo, el diagrama de flujo con fines de análisis de algoritmos de programación puede ser ejecutado en un ordenador, con un Ide como Free DFD.

Tipos de diagramas de flujo

  • Formato vertical: En él, el flujo o la secuencia de las operaciones, va de arriba hacia abajo. Es una lista ordenada de las operaciones de un proceso con toda la información que se considere necesaria, según su propósito.
  • Formato horizontal: En él, el flujo o la secuencia de las operaciones, va de izquierda a derecha.
  • Formato panorámico: El proceso entero está representado en una sola carta y puede apreciarse de una sola mirada mucho más rápido que leyendo el texto, lo que facilita su comprensión, aún para personas no familiarizadas. Registra no solo en línea vertical, sino también horizontal, distintas acciones simultáneas y la participación de más de un puesto o departamento que el formato vertical no registra.
  • Formato Arquitectónico: Describe el itinerario de ruta de una forma o persona sobre el plano arquitectónico del área de trabajo. El primero de los flujogramas es eminentemente descriptivo, mientras que los utilizados son fundamentalmente representativos.

Simbología y significado

  • Óvalo o Elipse: Inicio y término (Abre y/o cierra el diagrama).
  • Rectángulo: Actividad (Representa la ejecución de una o más actividades o procedimientos).
  • Rombo: Decisión (Formula una pregunta o cuestión).
  • Círculo: Conector (Representa el enlace de actividades con otra dentro de un procedimiento).
  • Triángulo boca abajo: Archivo definitivo (Guarda un documento en forma permanente).
  • Triángulo boca arriba: Archivo temporal (Proporciona un tiempo para el almacenamiento del documento)
  • SIMBOLOGÍA DE LOS DIAGRAMAS DE FLUJO

    Las diversas organizaciones usan distintos símbolos, pero el comité sobre computadoras y procesadores de información de la Asociación Norteamericana de Normas ha hecho un gran esfuerzo para normalizar los símbolos de los diagramas de flujo. Esa normalización permite comprender cualquier diagrama de flujo que use los símbolos recomendados.
    Cada símbolo normal de diagrama de flujo tiene un significado especial.
    Expresa Inicio o Fin de un Programa.
    Expresa operación algebraica o de
    asignación.
    Expresa condiciones y asociaciones alternativas de una decisión lógica.

    Expresa condición y acciones alternativas de una decisión numérica.
    Entrada / Salida: Representa cualquier tipo de Fuente de entrada y salida
    Entrada: Lectura de datos por tarjeta perforadas.
    Conector dentro de página.
    Representa resultado mediante un reporte impreso
    Conector fuera de página.
    Expresa operación cíclica repetitiva.
    Expresa proceso de llamada a una subalterna.
    Representa datos grabados en una cinta magnética.
    Almacenamiento en línea Disco Magnético.

    REGLAS PARA ESTRUCTURAR UN DIAGRAMA DE FLUJO

  • El sentido de un diagrama de flujo generalmente es de arriba hacia abajo.
  • Es un símbolo solo puede entrar una flecha de flujo si varias líneas se dirigen al mismo símbolo, se deben unir en una sola flecha.
  • Las líneas de flujo no deben cruzarse, para evitar los cruces se utilizan los conectores.
  • De un símbolo excepto el de decisión, solo puede salir una línea de flujo.
  • Los símbolos Terminal, Conector dentro de página y conector fuera de página solo pueden estar conectados al diagrama por una sola flecha, ya que por su naturaleza es imposible que tenga una entrada y una de salida.
  • Los émbolos de decisión tendrán siempre una sola flecha de entrada y dos o tres flechas de salida según la cantidad de alternativas que se presentan.
Un diagrama de flujo debe estar complemente cerrado, teniendo una continuidad de principio a fin, no pueden quedar flechas en el aire ni símbolos sin conexión al diagrama pues el flujo seria interrumpido.+

REGLAS PARA LA CREACIÓN DE DIAGRAMAS

  1. Los diagramas de flujo deben escribirse de arriba hacia abajo y/o de Izquierda a derecha.
  2. Los símbolos se unen con líneas, las cuales tienen en la punta una flecha que indica su dirección que fluye la información procesos, se deben utilizar solamente líneas de flujo horizontal o vertical (nunca diagonales).
  3. Se debe evitar el cruce de líneas, para lo cual se quisiera separar el flujo del diagrama a un sitio distinto, se pudiera realizar utilizando los conectores, se debe tener en cuenta que solo se van a utilizar conectores cuando sean estrictamente necesario.
  4. No deben quedar líneas de flujo sin conectar.
  5. Todo texto escrito dentro de un símbolo debe ser legible, preciso, evitando el uso de muchas palabras.
  6. Todos los símbolos pueden tener mas de una línea de entrada, a excepto del símbolo final.
  7. Solo los símbolos de decisión pueden y deben tener mas de una línea de flujo de salida.
  8. EXPLICACIÓN DEL DIAGRAMA DE FLUJO

  9. El primer bloque indica el inicio del diagrama de flujo.
  • El segundo bloque, es un símbolo de procesos.
En este bloque se asume que las variables suman y N ha sido declarada previamente y las inicializa en o para comenzar al conteo y la suma de valores.
  • Tercer bloque, es también un símbolo de procesos.
En este paso se incrementa en 1 la variable N(N=N+1), por lo que en la primera pasada esta valdrá 1, ya que estaba inicializada en 0.
  • Cuarto bloque, es exactamente lo mismo que el anterior.
Pero en este, ya se agrega el valor de N a la variable que contendrá la suma (en el primer caso contendrá 1, ya que N=1).

VENTAJAS DEL ENFOQUE DE FLUJOS DE DATOS

El enfoque de flujo de datos tiene cuatro ventajas principales sobre la explicación narrativa de la forma en que se mueven los datos a trabes del sistema .Las ventajas son.
  1. Libertad para realizar en forma muy temprana la implementación de técnicas de sistema.
  2. Una mayor comprensión de las interrelaciones de los sistemas y subsistemas.
  3. Comunicación del conocimiento del sistema actual a los usuarios por medio de diagramas de flujo de datos.
  4. Análisis de un sistema propuesto para determinar si han sido definidas los datos y procesos necesarios.

SÍMBOLOS USADOS EN EL DIAGRAMA DE FLUJO DE DATOS

SIGNIFICADO DE LOS SÍMBOLOS DE FLUJO
El cuadrado doble es representado y usado para una actividad externa (otro departamento, un negocio, una persona, o una maquina) que puedan enviar datos y recibirlas del sistema. La entidad externa es llamada una fuente de destino de datos y es considerada externa al estudio, cada entidad externa es etiquetada con un nombre adecuado. La flecha muestra el movimiento de datos de un punto a otro , esta señalada hacia suceden simultáneamente pueden ser representadas simplemente mediante el uso de flechas paralelas, debido a que una flecha representada datos acerca de una persona lugar o casa, también :Debe ser descrita con un nombre.
Un rectángulo con esquinas redondeadas es usado para mostrar la aparición de un proceso de transformación. Los procesos siempre denotan un cambio o transformación de los datos.

USO DE DIAGRAMAS DE FLUJO DE DATOS

Los diagramas de flujo de datos son útiles a lo largo del proceso de análisis y diseños, .Existen compromisos para decidir que tanto deben ser explotados de los flujos de datos. Se desperdiciara tiempo y se sacrificara complusibilidad si los diagramas de flujo de datos son exclusivamente complejos. Por otro lado, si los diagramas de flujo de datos están muy poco explotados, pueden ocurrir errores u omisiones que pueden eventualmente afectar el sistema que esta en desarrollo. Por ultimo, recuerde que los diagramas del sistema de flujo pueden ser usados para documentar niveles altos o bajos del análisis y para ayudar a sustentar la lógica subyacente en los flujos de datos de la organización.
CARACTERÍSTICAS DE LOS DIAGRAMAS DE FLUJO DE DATOS
  • Muestran que debe hacer el sistema sin referencias.
  • Son diagramas explícitos y comprensibles.
  • Dan la posibilidad de representan el sistema a diferentes niveles de complejidad, desde lo mas global a lo mas detallado solo requieren de 4 símbolos.
  • Son fácil de mantenimiento, pues los cambios afectan solo algunos de sus elementos y no al todo.
¿CUÁLES SO LAS VENTAJAS DE LOS DIAGRAMAS DE FLUJO DE DATOS?
  • Fácil lectura, con esto se constituye en un instrumento de mucha versatilidad.
  • Facilitan la interacción Usuario-Analista.
¿CUÁLES SON LAS LIMITACIONES DE LOS DIAGRAMAS DE FLUJO DE DATOS?
  • No permite recoger el comportamiento de sistema que deben responder a eventos en tiempos acotados. Para ello se usa el diagrama de transición de Estados.
  • No permite dar cuenta de la de las relaciones entre los datos que se precisan almacenar .Para ello se usan el diagrama Entidad-Relación.
  • No permite reflejar situaciones en las cuales es preciso dejar de manifiesto la necesaria concurrencia de dos o más flujo de datos para un subproceso pueda iniciar efectivamente su tarea. Para ello se utiliza la especificación de procesos.
  • No permite recoger el contenido de los flujos de datos ni el contenido de los archivos .Para ello se utiliza el diccionario de datos.

CONCLUSIÓN

Muchas personas consideran a un algoritmo y a un diagrama de flujo de datos como herramienta de gran importancia para la programación de computadora y están en lo cierto para la resolución de problemas mediante algoritmos y diagramas de flujo se ha convertido hoy en día en un instrumento efectivo para el desarrollo de habilidades y destrezas lógicas de y creativas del pensamiento humano.
Hoy diferentes formas de resolver un problema, esto es debido a la forma de razonar del ser humano, al igual que cada algoritmo, o diagrama de flujo de datos elaborado.
El término lógica define la exposición de leyes, modos y formas aplicadas al razonamiento. El ser humano aplica la lógica para la resolución de problemas de diferentes tipos.
Algunos instructores del área de computación no hace mucho hincapié sobre el desarrollo de algoritmo y diagramas de flujo de datos.
  1.  

INTRODUCCION A LOS TIPOS DE DATOS



Una definición muy simple:
El tipo de un dato es el conjunto de valores que puede tomar durante el programa. Si se le intenta dar un valor fuera del conjunto se producirá un error.
La asignación de tipos a los datos tiene dos objetivos principales:
  • Por un lado, detectar errores en las operaciones
  • Por el otro, determinar cómo ejecutar estas operaciones
De Pascal se dice que es un lenguaje fuertemente tipeado. Esto quiere decir que todos los datos deben de tener un tipo declarado explícitamente, y además que existen ciertas restricciones en las expresiones en cuanto a los tipos de datos que en ellas intervienen.
Una ventaja de los lenguajes fuertemente tipeados es que se gasta mucho menos esfuerzo en depurar (corregir) los programas gracias a la gran cantidad de errores que detecta el compilador.
Los tipos de datos, como casi todos los objetos de Pascal, se pueden declarar. La declaración de tipos ya se comentó en el tema correspondiente a la estructura de un programa.

Volver al inicio de la página
Pasar al siguiente apartado sobre las clasificaciones










Clasificaciones en los tipos de datos
En Pascal existen gran variedad y cantidad de tipos de datos. Pero en este tutorial sólo se trataran los básicos para que puedas ir construyendo tus primeros programas.
Existen muchas clasificaciones para los tipos de datos, y dependiendo de la fuente que mires, te mostrarán una u otra. A continuacón tienes una de las posibles clasificaciones.:

Que un tipo de datos sea estático quiere decir que el tamaño que ocupa en memoria no puede variar durante la ejecución del programa. Es decir, una vez declarada una variable de un tipo determinado, a ésta se le asigna un trozo de memoria fijo, y este trozo no se podrá aumentar ni disminuír.

Los punteros quizás sean el concepto más complejo a la hora de aprender un lenguaje de programación, sobre todo si es el primero que aprendes. Debido a esto, no lo trataremos. Además, lenguajes que están muy de moda (por ejemplo Java) no permiten al programador trabajar con punteros.

Los tipos simples más básicos son: entero, lógico, carácter y real. Y la mayoría de los lenguajes de programación los soportan, no como ocurre con los estructurados que pueden variar de un lenguaje a otro.

Las colecciones de elementos que aparecen al hablar de tipos estructurados son muy variadas: tenemos colecciones ordenadas que se representan mediante el tipo array, colecciones sin orden mediante el tipo conjunto, e incluso colecciones que contienen otros tipos, son los llamados registros.

Dentro de los tipos simples ordinales, los más importantes son:

Tipos no-ordinales

Simplificando, podríamos reducir los tipos simples no-ordinales al tipo
real. Este tipo nos sirve para declarar variables que pueden tomar valores dentro del conjunto de los números reales.
A diferencia de los tipos ordinales, los no-ordinales no se pueden contar. No se puede establecer una relación uno a uno entre ellos y los número naturales. Dicho de otra forma, para que un conjunto se considere ordinal se tiene que poder calcular la posición, el anterior elemento y el siguiente de un elemento cualquiera del conjunto.¿Cuál es el sucesor de 5.12? Será 5.13, o 5.120, o 5.121, ...


Volver al inicio de la página
Pasar al siguiente apartado sobre los tipos básicos










Los tipos básicos que nos interesan
Después de ver una de las posibles clasificaciones para los tipos de datos, pasemos a ver los que nos interesan: los tipos simples. Realmente de los tipos simples veremos los más básicos, que son: integer, boolean, char y real. Además, también hablaremos un poco de las cadenas de caracteres, los llamados strings.
nota: a continuación sólo se comentará qué es cada tipo, no se explicará su declaración, esto puedes verlo si vas a la sección correspondiente.

El tipo integer (entero)
Como ya habrás leído el tipo de datos entero es un tipo simple, y dentro de estos, es ordinal. Al declarar una variable de tipo entero, estás creando una variable numérica que puede tomar valores positivos o negativos, y sin parte decimal.
Este tipo de variables, puedes utilizarlas en asignaciones, comparaciones, expresiones aritméticas, etc. Algunos de los papeles más comunes que desarrollan son:
  • Controlar un bucle
  • Usarlas como contador, incrementando su valor cuando sucede algo
  • Realizar operaciones enteras, es decir, sin parte decimal
  • Y muchas más...
A continuación tienes un ejemplo en el que aparecen dos variables enteras. Como puedes ver, en el ejemplo se muestran las dos maneras de declarar una variable de tipo entero: 
type
      tContador = integer;
   var
      i : tContador;
      n : integer;

   begin
      n := 10; (* asignamos valor al maximo *)
      i := 1;  (* asignamos valor al contador *)
  
      while (i <= n) do begin
        writeln('El valor de i es ',i);
        i := i + 1
      end
   end. 

El tipo boolean (lógico)
El tipo de datos lógico es el que te permite usar variables que disponen sólo de dos posibles valores: cierto o falso. Debido a esto, su utilidad salta a la vista, y no es otra que variables de chequeo. Nos sirven para mantener el estado de un objeto mediante dos valores:
  • si/no
  • cierto/falso
  • funciona/no funciona
  • on/off
  • etc.
Para aclararlo, veamos un ejemplo:
type
      tLogico = boolean;
   var
      llueve   : tLogico;   (* si llueve o no *)
      paraguas : boolean;   (* si encuentro o no el paraguas *)

   begin
      (* aqui se determinarian los valores de "llueve" y "paraguas" *)
     
      if llueve and (not paraguas) then        
         writeln('Me quedo en casita')
      else
         writeln('Me voy a dar un paseo')
   end.   

El tipo real (real)
Como ya has visto, Pascal soporta el conjunto entero de números. Pero no es el único, también te permite trabajar con números pertenecientes al conjunto real.
El tipo de datos real es el que se corresponde con los números reales. Este es un tipo importante para los cálculos. Por ejemplo en los estadísticos, ya que se caracterizan por tratar fundamentalmente con valores decimales.
nota: Aunque pueda que estés acostumbrado a escribir con coma los decimales, te advierto que en Pascal y en todos los lenguajes de programación se escribe con un punto. Por ejemplo: 3.1416
A continuación tienes un ejemplo en el que se utiliza el tipo real. En el puedes ver las dos formas de declarar una variable real, y tambíen el uso de una constante real. Por si tienes curiosidad, el resultado de ejecutar el programa compilado es:
El area para un radio de 3.14 es 63.6174

const
      pi = 3.1416;     
   type
      tArea = real;
   var
      A : tArea;     (* area *)
      R : real;      (* radio *)

   begin
      R := 4.50;
      A := pi * R * R;    (* calculamos el area *)
     
      writeln('El area para un radio de ',R:4:2,' es ',A:8:4)
   end.  


Los tipos char y string (carácter y cadena)
Con el tipo carácter puedes tener objetos que representen una letra, un número, etc. Es decir, puedes usar variables o constantes que representen un valor alfanumérico. Pero ojo, cada variable sólo podrá almacenar un carácter.
Sin embargo, con las cadenas de caracteres (strings) puedes contener en una sóla variable más de un carácter. Por ejemplo, puedes tener en una variable tu nombre.
Veamos cómo se usan ambos tipos en el siguiente ejemplo
   type
      tNombre = string[10];  (* puede almacenar 10 caracteres *)
   var
      nombre    : tNombre;  (* variable para almacenar el nombre *)
      letra_NIF : char;     (* caracter para contener la letra del NIF *)

   begin
      nombre    := 'Beni';
      letra_NIF := 'L';
     
      writeln('Mi nombre es ',nombre,' y mi letra es ',letra_NIF)     
   end.