Está en la página 1de 160

Universidad

Alfred Nobel de México


Luis Arturo De La Barrera Banda y Luis
Enrique Real Carvajal

Antología 6° Cuatrimestre en Ingeniería en


Sistemas Computacionales (I.S.C)
Profesora Yohali Corona
Programación 2
1
ÍNDICE

INTRODUCCIÓN ............................................................................................................................................................. 7
¿QUÉ ES LA PROGRAMACIÓN? ............................................................................................................................ 7
¿PARA QUÉ SIRVE LA PROGRAMACIÓN? ......................................................................................................... 7
¿POR QUÉ DEBERÍAS DE APRENDER A PROGRAMAR? ............................................................................... 7
PROGRAMAR TE ENSEÑA A PENSAR ................................................................................................................. 7
FUNCIONES..................................................................................................................................................................... 8
MODIFICADORES DE UNA FUNCIÓN ................................................................................................................... 8
TIPO DE RETORNO DE UN MÉTODO ................................................................................................................... 9
NOMBRE DE LA FUNCIÓN ....................................................................................................................................... 9
ARGUMENTOS O PARÁMETROS DE UNA FUNCIÓN ....................................................................................... 9
EL BLOQUE DE CÓDIGO.......................................................................................................................................... 9
EJEMPLO DE UNA FUNCIÓN .................................................................................................................................. 9
LLAMADAS A FUNCIONES EN PROGRAMACIÓN............................................................................................ 10
COMO PASAR ARGUMENTOS O PARÁMETROS A UNA FUNCIÓN............................................................ 10
DECLARAR MÉTODOS QUE DEVUELVEN UN RESULTADO ........................................................................ 11
DEVOLUCIÓN DE UN VALOR CON RETURN .................................................................................................... 11
RECEPCIÓN DE VALORES DEVUELTOS........................................................................................................... 11
VENTAJAS DEL USO DE FUNCIONES EN PROGRAMACIÓN ....................................................................... 12
FUNCIÓN MAIN EN PROGRAMACIÓN ................................................................................................................ 12
¿ POR QUÉ EL MÉTODO MAIN DEBE ACEPTAR ESTOS ARGUMENTOS? .............................................. 12
ARRAYS ......................................................................................................................................................................... 13
CARACTERÍSTICAS PRINCIPALES DE LOS ARRAYS .................................................................................... 14
DIMENSIONALIDADES DE LOS ARRAYS........................................................................................................... 14
ARRAYS UNIDIMENSIONALES ............................................................................................................................. 15
ARRAYS BIDIMENSIONALES ................................................................................................................................ 15
ARRAYS MULTIDIMENSIONALES ........................................................................................................................ 15
DECLARACIÓN Y ACCESO DE ARRAYS EN VARIOS LENGUAJES ............................................................ 16
ARRAY EN C Y C++ ................................................................................................................................................. 16
ARRAY EN JAVA ....................................................................................................................................................... 17
ARRAY EN JAVASCRIPT ........................................................................................................................................ 18
ARRAY EN PHP ........................................................................................................................................................ 18
VARIABLES INDEFINIDAS...................................................................................................................................... 21
DECLARACIÓN DE VARIABLES EN C ................................................................................................................. 22

2
DISTINTOS TIPOS DE VARIABLES ...................................................................................................................... 22
DECLARACIÓN DE VARIABLE Y ASIGNACIÓN DE VALOR ........................................................................... 22
¿CUÁL ES LA IMPORTANCIA DE LAS DECLARACIONES DE VARIABLES EN LA PROGRAMACIÓN?
...................................................................................................................................................................................... 23
¿CUÁL ES EL PROPÓSITO DE ESPECIFICAR EL TIPO DE DATOS EN UNA DECLARACIÓN DE
VARIABLE? ................................................................................................................................................................ 23
¿CUÁLES SON LOS TIPOS DE DATOS MÁS COMUNES UTILIZADOS EN LAS DECLARACIONES DE
VARIABLES? .............................................................................................................................................................. 23
¿PUEDO MODIFICAR EL TIPO DE DATO DE UNA VARIABLE DESPUÉS DE HABERLA DECLARADO?
...................................................................................................................................................................................... 23
¿ES OBLIGATORIO ASIGNAR UN VALOR INICIAL A UNA VARIABLE EN LA DECLARACIÓN?............ 24
¿QUÉ SUCEDE SI DECLARO UNA VARIABLE CON EL MISMO NOMBRE QUE OTRA YA EXISTENTE
EN EL PROGRAMA? ................................................................................................................................................ 24
ALMACENAMIENTO................................................................................................................................................. 24
CLASIFICACIÓN PRINCIPAL DE ALMACENAMIENTO EN COMPUTADORAS .......................................... 24
DIRECCIONAMIENTO.............................................................................................................................................. 25
REPRESENTACIÓN DE MEMORIA ...................................................................................................................... 25
COLA (DEFINICIÓN) ................................................................................................................................................ 26
INICIALIZACIÓN ........................................................................................................................................................ 27
ASIGNACIÓN Y RECUPERACIÓN DE VALORES DE LOS ELEMENTOS .................................................... 28
EXTENDIENDO LA DIMENSIÓN............................................................................................................................ 29
ESTRUCTURAS ............................................................................................................................................................ 29
CARACTERÍSTICAS Y VENTAJAS ....................................................................................................................... 30
LAS 3 ESTRUCTURAS BÁSICAS .......................................................................................................................... 31
PUNTEROS .................................................................................................................................................................... 32
DECLARANDO PUNTEROS ................................................................................................................................... 33
EXPLICACIÓN ........................................................................................................................................................... 33
¿DIFERENTES DIRECCIONES? ........................................................................................................................... 34
USO EN FUNCIONES .............................................................................................................................................. 35
OPERADORES .......................................................................................................................................................... 35
OPERACIONES ARITMÉTICAS ............................................................................................................................. 35
PUNTEROS CONSTANTES.................................................................................................................................... 36
PUNTEROS GENÉRICOS ....................................................................................................................................... 37
PUNTEROS Y MATRICES ...................................................................................................................................... 38
PUNTEROS A CADENAS DE CARACTERES ..................................................................................................... 39
MATRICES DE PUNTEROS.................................................................................................................................... 39
PUNTEROS A PUNTEROS ..................................................................................................................................... 40
MATRICES DE PUNTEROS A CADENAS DE CARACTERES ........................................................................ 41

3
ASIGNANDO VALORES A PUNTEROS ............................................................................................................... 41
¿CÓMO SE USA UN PUNTERO? .......................................................................................................................... 43
MANEJO DE ARCHIVOS ............................................................................................................................................ 45
FICHEROS ................................................................................................................................................................. 46
FOPEN ........................................................................................................................................................................ 46
FCLOSE ...................................................................................................................................................................... 47
FEOF ........................................................................................................................................................................... 47
REWIND ...................................................................................................................................................................... 48
LECTURA ................................................................................................................................................................... 48
FGETC......................................................................................................................................................................... 48
FGETS ......................................................................................................................................................................... 49
FREAD......................................................................................................................................................................... 51
FSCANF ...................................................................................................................................................................... 51
ESCRITURA ............................................................................................................................................................... 52
FPUTC ......................................................................................................................................................................... 52
FPUTS ......................................................................................................................................................................... 53
FWRITE ....................................................................................................................................................................... 54
FPRINTF ..................................................................................................................................................................... 54
ARCHIVOS Y DIRECTORIOS ................................................................................................................................. 55
PERMISOS DE ARCHIVOS Y DIRECTORIOS .................................................................................................... 56
ARCHIVOS ................................................................................................................................................................. 58
LECTURA DE ARCHIVOS ....................................................................................................................................... 58
ESCRITURA EN ARCHIVOS .................................................................................................................................. 61
ARCHIVOS DE VALORES CON SEPARADORES ............................................................................................. 62
¿DÓNDE DEBERÍA ESTAR TU SITIO WEB EN TU COMPUTADORA? ........................................................ 65
UNA ACOTACIÓN SOBRE LA ENVOLTURA Y EL ESPACIADO .................................................................... 65
¿QUÉ ESTRUCTURA DEBE TENER TU SITIO WEB? ...................................................................................... 66
RUTAS DE ARCHIVO ............................................................................................................................................... 67
PROCESAMIENTO DE TEXTO .............................................................................................................................. 69
SALTOS DE LÍNEA ................................................................................................................................................... 69
REEMPLAZAR SECCIONES DEL STRING ......................................................................................................... 70
SEPARAR Y JUNTAR STRINGS............................................................................................................................ 71
MAYÚSCULAS Y MINÚSCULAS ............................................................................................................................ 73
REVISAR CONTENIDOS DEL STRING ................................................................................................................ 73
ALINEACIÓN DE STRINGS .................................................................................................................................... 74
INTERPOLACIÓN DE STRINGS ............................................................................................................................ 75

4
RESOLUCIÓN DE PROBLEMAS DE ACCESO A ARCHIVOS ......................................................................... 76
RESOLUCIÓN DE PROBLEMAS CON RUTAS DE BÚSQUEDA ( COMMAND NOT FOUND) .................. 76
¿CÓMO DIAGNOSTICAR Y CORREGIR PROBLEMAS DE RUTA DE BÚSQUEDA? ................................. 77
CAMBIO DE PROPIEDADES DE GRUPO Y ARCHIVO .................................................................................... 79
RESOLUCIÓN DE PROBLEMAS DE ACCESO A ARCHIVOS ......................................................................... 79
DETECCIÓN DE PROBLEMAS CON EL ACCESO DE RED ............................................................................ 79
CREACIÓN DE UNIDADES ........................................................................................................................................ 79
SUBPROGRAMAS Y BLOQUES COMPILADOS INDEPENDIENTEMENTE ................................................. 89
¿QUÉ ES SUBPROGRAMACIÓN? ........................................................................................................................ 89
¿CÓMO SE IMPLEMENTAN LOS SUBPROGRAMAS O FUNCIONES?........................................................ 90
API DE JAVASCRIPT ............................................................................................................................................... 90
FUNCIONES............................................................................................................................................................... 91
PARÁMETROS .......................................................................................................................................................... 91
CREACIÓN, MODIFICACIÓN Y BORRADO DE SUBPROGRAMAS............................................................... 93
COMPILADOR E INTÉRPRETE ................................................................................................................................. 93
¿QUÉ ES UN INTÉRPRETE? ................................................................................................................................. 94
¿QUÉ ES UN COMPILADOR?................................................................................................................................ 94
SOLUCIÓN HÍBRIDA DE INTÉRPRETE Y COMPILADOR ............................................................................... 95
PROGRAMACIÓN ESTRUCTURADA ................................................................................................................... 96
¿QUÉ ES LA PROGRAMACIÓN ESTRUCTURADA? ........................................................................................ 96
¿QUÉ HABÍA ANTES DE LA PROGRAMACIÓN ESTRUCTURADA? ............................................................ 96
¿QUÉ APORTÓ LA PROGRAMACIÓN ESTRUCTURADA? ............................................................................. 97
TIPOS DE FUNCIONES ........................................................................................................................................... 98
¿SE USA HOY LA PROGRAMACIÓN ESTRUCTURADA? ............................................................................... 98
¿QUÉ VINO DESPUÉS DE LA PROGRAMACIÓN ESTRUCTURADA? ......................................................... 99
BIBLIOTECA DEL SISTEMA ................................................................................................................................... 99
SISTEMA DE PROGRAMACIÓN O FRAMEWORK .......................................................................................... 100
¿CUÁL ES LA DIFERENCIA ENTONCES? ¿CUÁL USAN LOS PROGRAMADORES? ............................ 100
LA BIBLIOTECA DEL SISTEMA ........................................................................................................................... 100
¿QUÉ SON EXACTAMENTE LAS LIBRERÍAS? ............................................................................................... 101
SINTAXIS PARA DECLARAR LIBRERÍAS EN C++ .......................................................................................... 102
¿CÓMO DECLARAR UNA LIBRERÍA EN C++? ................................................................................................ 103
ACERCA DEL NAMESPACE STD ....................................................................................................................... 104
DISEÑO DE INTERFAZ DE USUARIO ................................................................................................................ 105
IMPORTANCIA DEL DISEÑO CENTRADO EN EL USUARIO ........................................................................ 106
CARACTERÍSTICAS DEL DISEÑO CENTRADO EN EL USUARIO .............................................................. 106

5
EVALUAR LOS RESULTADOS ............................................................................................................................ 107
ETAPAS DEL DISEÑO CENTRADO EN LAS PERSONAS ............................................................................. 108
LOS 6 ELEMENTOS PARA UNA METODOLOGÍA DEL DISEÑO CENTRADO EN EL USUARIO .......... 109
EL MARKETING CENTRADO EN EL USUARIO ............................................................................................... 111
CÓMO APLICAR EL DISEÑO CENTRADO EN EL USUARIO EN TU SITIO WEB ..................................... 112
INTERRUPCIONES DE DOS .................................................................................................................................... 114
FUNCIONAMIENTO DEL MECANISMO DE INTERRUPCIONES .................................................................. 115
MECANISMO Y LÍNEAS DE PETICIÓN DE INTERRUPCIÓN ........................................................................ 116
FUNCIONAMIENTO ................................................................................................................................................ 143
ACTUALIZACIÓN FIRMWARE ............................................................................................................................. 143
OVERCLOCKING .................................................................................................................................................... 144
FIRMWARE EN TARJETAS ADAPTADORAS ................................................................................................... 144
TARJETAS DE VÍDEO............................................................................................................................................ 144
MERCADO DE LOS BIOS ..................................................................................................................................... 145
ALTERNATIVAS Y SUCESORES ........................................................................................................................ 145
CONTENIDOS.......................................................................................................................................................... 146
BIOS .............................................................................................................................................................................. 146
PASOS DE PROCESO DE CARGA DE LA BIOS 6 UA 2.3.1 – BIOS............................................................ 146
TARJETA GRÁFICA................................................................................................................................................ 147
CONFIGURACIÓN DEL BIOS ............................................................................................................................... 153
ACTUALIZACIÓN DEL BIOS 30 UA 2.3.1 – BIOS............................................................................................. 154
CREAR UN CD/DVD CON LA APLICACIÓN ASUS UPDATE AL SUITE II ................................................. 154
CONTROLANDO EL FIRMWARE DEL SISTEMA 32 UA 2.3.1 – BIOS ......................................................... 155
CARACTERÍSTICAS BIOS Y UEFI 33 UA 2.3.1 – BIOS .................................................................................. 155
CARACTERÍSTICAS BIOS Y UEFI 34 UA 2.3.1 – BIOS .................................................................................. 155
SEGURIDAD EN BIOS Y UEFI 36 UA 2.3.1 – BIOS ......................................................................................... 156
SEGURIDAD EN BIOS Y UEFI 37 UA 2.3.1 – BIOS. ........................................................................................ 156
EL RELOJ Y PILA CMOS 38 UA 2.3.1 – BIOS................................................................................................... 157
EL RELOJ Y PILA CMOS 39 UA 2.3.1 – BIOS................................................................................................... 157
EL RELOJ Y PILA CMOS 40 UA 2.3.1 – BIO ..................................................................................................... 157
FABRICANTES DE BIOS 41 UA 2.3.1 – BIOS ................................................................................................... 158
CONCLUSIÓN ............................................................................................................................................................. 159
BIBLIOGRAFÍA ........................................................................................................................................................... 160

6
INTRODUCCIÓN

¿QUÉ ES LA PROGRAMACIÓN?
La programación informática es el arte de indicarle a una computadora lo que tiene que hacer
mediante un conjunto de instrucciones. Es decir, los programadores, escriben las instrucciones en
una especie de lenguaje que al principio puede parecer a los humanos un poco extraño, pero que
las máquinas saben interpretar perfectamente. La computadora lee este código, estas instrucciones,
y las ejecuta en el orden correcto. Es como si la computadora fuese un perro super obediente y
nunca te pone en duda, y hace todo lo que tú digas en el orden que se lo digas.

¿PARA QUÉ SIRVE LA PROGRAMACIÓN?


Con la programación podemos hacer prácticamente cualquier cosa. Por ejemplo, podemos hacer
programas para controlar robots, robots que están cuidando a pacientes en sus casas, robots que
están analizando la superficie de Marte en busca de agua. O coches autónomos, la programación
hace posible que tengamos coches que van solo por ahí sin que se choquen. O en el ámbito médico,
los programas analizan miles de datos ayudando a los médicos a buscar curas a las enfermedades.
Videojuegos, con la programación puede llegar a desarrollar videojuegos. Películas de animación
también se basan en programas creados con la programación, al igual que los grandes efectos
especiales de las películas. Por otro lado, webs y aplicaciones que se usan por millones de personas
diariamente. Y mucho más.

¿POR QUÉ DEBERÍAS DE APRENDER A PROGRAMAR?


Aprender a programar es como el nuevo leer y escribir. ¿Te acuerdas cuando estabas en la escuela,
y estabas aprendiendo como funcionaban las placas tectónicas, o cómo funciona el ciclo del agua?
¿Tú ahora, en tu día a día, utilizas esos conocimientos? Que no digo que este mal aprenderlos, está
muy bien. Pero te voy a decir algo que sí que usas cada día, tu teléfono móvil, y seguramente
muchos otros aparatos electrónicos que posiblemente no tengas ni idea de cómo funcionan. Todo
esto está programado, tiene programación de por medio. El mundo está tirando a una dirección
tecnológica, cada vez usamos más la tecnología, y se vienen grandes áreas que aún no podemos
ni imaginar. Inteligencia Artificial, Machine Learning, Internet de las cosas, se vienen grandes cosas
en un futuro no muy lejano, y el que no sepa programar se va a quedar atrás en todo esto.

PROGRAMAR TE ENSEÑA A PENSAR


Programar te enseña a pensar, aprender a programar te hace más hábil en resolver problemas, la
programación se basa en resolver problemas, y una vez empiezas a aprender a programar, tu
cerebro cambia.

7
FUNCIONES

Una función, desde el punto de vista de la programación, se define como un proceso que recibe
valores de entrada (llamados argumentos) y el cual retorna un valor resultado. Adicionalmente, las
funciones son subprogramas dentro de un programa que se pueden invocar (ejecutar), desde
cualquier parte del programa, es decir, desde otra función, desde la misma función o desde el
programa principal, cuantas veces sea necesario.

Las funciones se usan cuando existen dos o más porciones de algoritmo dentro de un
programa que son iguales o muy similares, por ejemplo, en un algoritmo se puede emplear varias
veces una porción de algoritmo que eleva a una potencia dada un número real. Las funciones,
también llamados métodos, nos permiten dividir el trabajo que hace un programa, en tareas más
pequeñas separadas de la parte principal. Ese es el concepto de función en programación.

Veamos un ejemplo: imagina que desarrollas un programa, y una de las partes hace un cálculo de
un valor. Puede ser algo simple, como una suma o una resta, pero puede ser un cálculo mucho más
complicado, como puede ser la distancia entre dos objetos en un videojuego 3D.

El código que realiza que realiza las tareas del cálculo puede estar en una función. Esta función
puede ser usada de forma independiente en diferentes partes del programa, ya sea en programación
modular o en un lenguaje orientado a objetos como Java. Por lo tanto, puedes invocar la función o
método que calcula el total de una clase, o aplicar el resultado de los cálculos.

Para definir una función, la sintaxis de la declaración es la siguiente:

[Modificadores] tipo_retorno nombre_funcion ([argumentos])


{
bloque_código;
}
MODIFICADORES DE UNA FUNCIÓN

Los modificadores de un método son varias palabras clave , o palabras reservadas de un lenguaje
de programación, que puede modificar la forma en que los métodos son usados. Los modificadores
son opcionales, por eso lo hemos indicado en corchetes [ ]. Ejemplos de modificadores pueden
ser public, private, protected, virtual, static…

8
TIPO DE RETORNO DE UN MÉTODO

El tipo retorno es el tipo de valor devuelto por la función, y puede ser usado en cualquier parte del
programa. Las funciones sólo pueden devolver un valor, ya sea un tipo de datos básico, como puede
ser un número entero o un string, o dependiendo del lenguaje un objeto. Pero no podría devolver
dos números, por ejemplo. Eso lo haremos de otra manera.

NOMBRE DE LA FUNCIÓN

También llamado identificador, es como llamamos a la función. Depende de cada lenguaje de


programación, pero al igual que cuando declaramos una variable, el nombre de la función no puede
llevar espacios, por ejemplo, suma total es incorrecto, debería ser alguna de estas
opciones: sumaTotal, suma_total, SumaTotal, etc. Tampoco debería de empezar por un número y
no puede usarse ninguna palabra reservada para el lenguaje (una función no podría llamarse int).

ARGUMENTOS O PARÁMETROS DE UNA FUNCIÓN

Los argumentos de una función, también llamados parámetros, representa una lista de variables
cuyos valores son pasados al método para ser usados por éste. Suelen ser opcionales, por eso en
el ejemplo están en corchetes [ ]. Algunos métodos no aceptan argumentos. Los parámetros de una
función tienen una serie de características que hablaremos un poco más abajo para entrar en
detalle.

EL BLOQUE DE CÓDIGO

El código del método es la secuencia de instrucciones o sentencias que la función realiza. Estas
instrucciones son las tareas que hacen que la función tenga sentido. Para saber que un bloque de
código pertenece a una función, en el ejemplo está entre llaves { }. Así sabemos cuándo acaba la
función. En algunos lenguajes nos podremos encontrar otra manera de indicar cuando empieza y
termina una función. Por ejemplo, en Visual Basic acabaría como End Sub o End Function, en
Pascal tenemos BEGIN y END.

EJEMPLO DE UNA FUNCIÓN

Aquí tienes un ejemplo de una función de un método que no tiene argumentos y no retorna nada.
Total, de clase tal es un método básico ejemplo:

9
public void Dibuja()
{
println("*****");
}

Un ejemplo de un método que acepta dos argumentos y devuelve un resultado de una suma:

public int Suma(int num1, int num2)


{
return num1 + num2;
}
LLAMADAS A FUNCIONES EN PROGRAMACIÓN

Las pautas para hacer una llamada a una función son:

• No hay límite en cuanto a la cantidad de llamadas a funciones que un método puede realizar.
• Se puede invocar a los métodos en cualquier orden.
• Para funciones en objetos:
o Los métodos no necesitan ser completados en el orden que son listados en la clase,
que es dónde están declarados.
o El método llamado y el método desde dónde se llama pueden estar en la misma clase
o en diferentes clases.

COMO PASAR ARGUMENTOS O PARÁMETROS A UNA FUNCIÓN

Como hemos dicho anteriormente, las funciones pueden ser invocadas desde otro método, con una
lista de argumentos. Adicionalmente, las funciones pueden devolver un valor para ser usado como
resultado. Muchos de los métodos que declaras o usas desde la biblioteca que te ofrece el
compilador del lenguaje también aceptan argumentos. Pasa pasar argumentos desde un método a
otro, se hace desde los paréntesis de la llamada al método. Los argumentos pasados conservadores
literales o variables. Al llamar a un método, se deben listar los argumentos en el mismo orden que
dichos argumentos están declarados en la definición del método, además que deben pasarse todos
los argumentos requeridos. El compilador verificará si el tipo y cantidad de argumentos pasados
concuerda con el tipo, el orden y cantidad de parámetros que acepta el método llamado.

10
DECLARAR MÉTODOS QUE DEVUELVEN UN RESULTADO

La mayoría de las declaraciones de métodos que se han visto en el curso no devuelven un


valor(dado por la palabra voy en la declaración del método). Sin embargo, los métodos que se
crearán devolverán un valor y muchos de los métodos en las bibliotecas de clase Java también
devuelven valores.

Para declarar un método que devuelve un valor, se debe incluir el tipo del valor que devuelve delante
del identificador del método en la declaración de este. El siguiente ejemplo muestra un método que
acepta dos valores del tipo int y devuelve un valor de tipo int:

public int Sum(int a, int b)


DEVOLUCIÓN DE UN VALOR CON RETURN

Para devolver un valor desde un método, se utiliza la palabra clave return. Por ejemplo, el siguiente
código devuelve el valor que tiene actualmente la variable result.

return result;

RECEPCIÓN DE VALORES DEVUELTOS

Si se invoca un método que devuelve un valor, como en el caso anterior, se puede utilizar el valor
devuelto en el método desde dónde se ha llamado. Veamos esta función:

public int Sum(int a, int b)


{
return a + b;
}

Se utilizaría de la siguiente manera:

int resultado;
resultado = Sum(4, 5);

11
VENTAJAS DEL USO DE FUNCIONES EN PROGRAMACIÓN

Los métodos son el mecanismo por el cual los objetos interactúan entre sí. En un programa es
común tener varios objetos que interactúan invocando los métodos en forma mutua.

A continuación, se describen algunas ventajas del uso de métodos en los programas:

• Hace que los programas sean más legibles y fáciles de mantener. Por ejemplo, es fácil saber
lo que un programa hace si el código está dividido en varios métodos diferentes con nombres
que describan el comportamiento de estos.
• El desarrollo y el mantenimiento es más rápido. Por ejemplo, puedes elegir crear y probar un
método por vez cada para asegurar que el programa, en su totalidad, funciona bien cuando
se ha finalizado.
• Son utilizados para que el software sea reusable. Por ejemplo, las bibliotecas de cualquier
compilador tienen muchas clases con métodos que pueden ser usados una y otra vez en los
programas.
• Se puede crear métodos para que otros programadores puedan usar.
• Los métodos permiten separar los objetos para comunicar y distribuir el trabajo realizado por
el programa.

FUNCIÓN MAIN EN PROGRAMACIÓN

En casi todos los lenguajes de programación, se utiliza el método main, que debe ser escrito de
forma tal que aceptan argumentos uno o más parámetros, pero nos lo encontramos como un array
de Strings.

public static void main (String args[ ])

¿ POR QUÉ EL MÉTODO MAIN DEBE ACEPTAR ESTOS ARGUMENTOS?

El lenguaje de programación requiere que el método main se escriba de forma que acepte valores
cuando es ejecutado desde la línea de comando (en Windows sería la ventana Símbolo del sistema).
Por ejemplo, si quieres pasar un número con una cantidad de 22.00, se escribiría de esta manera
con parámetros:

Nombre_ejecutable 22.00

12
Para que se pueda usar en el programa, los valores numéricos pasados al método main deben ser
convertidos de cadena de caracteres, o string, a un tipo primitivo.

• Nota: El pase de argumentos al método main es una característica usada para probar
programas. Además, necesitas conocer cómo funcionan las arrays para saber cómo tratar
los diferentes argumentos pasados.

De esta manera se define una función que al ser invocada ejecute dicho código, y en el lugar donde
estaba la porción de algoritmo original, se hace un llamado (ejecución) de la función creada.

Una función se declara de la siguiente manera:

Donde,

• nombre: es el nombre de la función

• arg: es nombre del argumento i-esimo de la función.

•tipo: es el tipo del i-esimo argumento de la función.

•tipo: es el tipo de dato que retorna la función.

•<declaraciones>: es el conjunto de variables definidas para la función (diferentes a los argumentos)

ARRAYS

Un array es una manera de poder guardar datos del mismo tipo o clase (Enteros, carácteres,
booleanos, etc.). Es posible el acceso a cada elemento de un array a través de un número entero
que se denomina índice (pueden existir 2 o más índices según la dimensionalidad del array). La

13
numeración de estos elementos dentro del array comienza en 0 (primer elemento del array) y finaliza
en n-1 (último elemento del array) donde n es el tamaño completo de dicho array.

Para utilizar los arrays de manera adecuada se realizan las siguientes acciones sobre ellos:

• Declarar el array
• Crear el array e inicializarlo (Esta acción puede ser incluida en la declaración)
• Acceder y utilizar el array

CARACTERÍSTICAS PRINCIPALES DE LOS ARRAYS


Las principales características de un array son:

• Tiene un nombre de variable único que representa a cada elemento dentro de él y estos
elementos son diferenciados por un índice.
• Los elementos dentro del array son guardados en posiciones de memoria de forma continua.
• Se puede acceder a cada elemento individual del array de manera directa o aleatoria.

DIMENSIONALIDADES DE LOS ARRAYS


Dependiendo de la forma como se declaran o construyen los arrays, se pueden clasificar
en: unidimensional, bidimensional o multidimensional. Los más utilizados son los arrays
estructurados como un vector (unidimensionales) o como una matriz (bidimensionales), aunque se
pueden crear estructuras de más de 2 dimensiones (multidimensionales) sin ningún problema.

14
ARRAYS UNIDIMENSIONALES
Un array unidimensional (vector) es aquel en el cual se puede acceder a cualquier elemento
solamente con un índice. Se puede imaginar como si se tratase de una lista de datos en la cual,
para referirnos a cada elemento de dicha lista, emplearemos un número (índice) para indicar la
posición en la que podemos encontrar dicho elemento dentro de ella.

ARRAYS BIDIMENSIONALES
En el caso de los arrays bidimensionales (También llamados tablas o matríces), son 2 los índices
necesarios para localizar cualquier elemento.
Cualquier elemento dentro del array bidimensional se puede imaginar como un elemento que se
encuentra localizado dentro de una posición determinadas en un “eje X” y un “eje Y”.
En la imagen anterior, si cogemos cualquier posición dentro del array como una posición {x,y}:

• {0,0} corresponde al número 1 azul.


• {2,3} corresponde al número 1 rojo.
• {4,4} corresponde al número 2 verde.

ARRAYS MULTIDIMENSIONALES
También se pueden crear arrays de más de 2 dimensiones y son los denominados Arrays
multidimensionales.
En este caso el número de índices viene determinado por el número de dimensiones de nuestro
array, por ejemplo, para un array tridimensional el número de índices sería 3. Igual que ocurre con
los otros tipos de arrays, cualquier elemento puede ser localizado mediante una posición concreta.

15
Si cogemos como ejemplo la imagen anterior, se trata de un array tridimensional, en el que, cualquier
elemento, puede ser localizado mediante una posición {x,y,z}.

Por ejemplo:

• Para el cuadrado rojo que está en la cara inferior izquierda la posición sería {0,2,0}
• Si queremos localizar el cuadrado verde de la cara inferior derecha sería {2,1,1}

DECLARACIÓN Y ACCESO DE ARRAYS EN VARIOS LENGUAJES


Los arrays, como dije anteriormente, son una estructura básica dentro de cualquier lenguaje de
programación.
Pero cada lenguaje administra, declara y usa los arrays de manera distinta.
A continuación, expongo una breve guía sobre la declaración y el acceso a arrays con distintos
lenguajes de programación.

Anotación: Todas las declaraciones de arrays que se van a hacer a continuación se hacen de forma
vacía, es decir, no se inicializan valores dentro de dicha declaración, pero perfectamente se pueden
inicializar valores dentro del array a la hora de la declaración.
ARRAY EN C Y C++
Para declarar un array unidimensional tanto en C como en C++, la sentencia a utilizar es:
Tipo_dato nombre_array[número_elementos];
Donde número de elementos debe ser mayor o igual a 1.

16
Un ejemplo podría ser: int ejemplo[7];
Para acceder a cualquier posición dentro dicho array, la sentencia a utilizar es:

Nombre_array[posición];
Donde “posición” debe encontrarse en el rango desde 0 a “número_elementos”-1.

Por tanto, si por ejemplo quisiéramos acceder a la posición 6 de dicho array, la sentencia a utilizar
sería ejemplo[5]; ya que, como dijimos anteriormente, los índices en los arrays comienzan en la
posición 0. En el caso de los arrays bidimensionales y multidimensionales, la declaración es igual
que para los unidimensionales aumentando el número de “corchetes” donde quedan especificadas
las dimensiones del array. Por ejemplo, para un array bidimensional un ejemplo de declaración
sería: char palabras[4][5]; mientras que si queremos declarar un array de 4 dimensiones un ejemplo
sería: bool elección[3][2][3][2]; a la hora de acceder estamos ante la misma situación aumentando
las dimensiones en la consulta. Por ejemplo: palabras[2][0]; o elección[0][0][1][2]; C es un lenguaje
de programación (considerado uno de los más importantes) que se utiliza en aplicaciones como en
sistemas operativos, además de ser la base de otros lenguajes más actuales como Java o C++.
Lo que es un array es visto en el lenguaje C como una cadena de caracteres declarados. C permiten
la utilización de cierto número de notaciones y de funciones especiales y, por ejemplo, en C++ no
es posible crear de manera sencilla un vector (o array unidimensional) capaz de almacenar una
cantidad de información indefinida, siendo necesario ingresar con antelación la cantidad de datos
(tamaño) que el vector o la matriz tendrán. Lo que son los arrays unidimensionales y bidimensionales
forman parte de la amplia variedad de estructuras de datos que ofrece el lenguaje de programación
C, siendo además una de las principales y más útiles estructuras que puedes tener como
herramienta de programación. Para declarar un array unidimensional tanto en C como en C++, la
sentencia a utilizar es:
Tipo_dato nombre_array[número_elementos]

Donde el número de elementos debe ser mayor o igual a 1.

ARRAY EN JAVA
Declarar y acceder a un array en Java es muy parecido a C o C++. La principal diferencia radica en
que Java trata a un array como si fuera un objeto mientras que en C y C++ se trata como si fuera
una variable. La sentencia utilizada para declarar un array unidimensional en Java es:
Tipo_dato nombre_array[]; Nombre_array = new tipo_dato[tamaño_array];
Y para acceder la sentencia sería:

17
nombre_array[posición];

Un ejemplo sería:

Int números[]; // Declaramos un array “números” de tipo entero


números= new int[8]; // Inicializamos un objeto “números” de tipo array de números enteros con 9
elementos.
números[5]; // Accedemos al sexto elemento dentro del array “números”
Para arrays de más dimensiones sería exactamente igual solamente añadiendo más “corchetes”
con las dimensiones deseadas.

ARRAY EN JAVASCRIPT
En el caso de Javascript, para declarar un array existen 2 métodos:
Var nombre_array = new Array(); O Var nombre_array = [];
Para acceder a cualquier elemento dentro del array la sentencia sería:

nombre_array [posición];
Para arrays multidimensionales en Javascript podéis ver el siguiente tutorial.

ARRAY EN PHP
Finalmente, vamos a ver cómo declarar y acceder a los elementos de un array con PHP.
Para declarar un array unidimesional, la sintaxis sería:

$nombre_variable = array();
Ejemplo: $colores = array();
En el caso de que queramos declarar un array multidimensional (2 ó más dimensiones) simplemente
habría que ir concatenando la función array() para cada dimensión dentro de la dimensión anterior:

$nombre_variable = array(array(…));
Por ejemplo, si queremos un array bidimensional sería:

$tabla = array(array());
Mientras que si queremos uno tridimensional sería:

$variable = array(array(array()));
Para acceder a los arrays en PHP la sentencia a utilizar sería:

18
$nombre_variable[posición];
Ejemplo: $colores[3];
Y en el caso de multidimensionales simplemente basta con ir incluyendo “corchetes” con la posición
dentro de dicha dimensión. Ejemplo: $variable[3][2][0];
En programación de computadoras , una declaración es una construcción de lenguaje que especifica
las propiedades de un identificador : declara lo que una palabra (identificador) "significa". Las
declaraciones se usan más comúnmente para funciones , variables , constantes y clases , pero
también se pueden usar para otras entidades como enumeraciones y definiciones de tipos. Más allá
del nombre (el identificador en sí) y el tipo de entidad (función, variable, etc.), las declaraciones
suelen especificar el tipo de datos (para variables y constantes) o la firma de tipo (para funciones);
los tipos también pueden incluir dimensiones, como para matrices.

Se utiliza una declaración para anunciar la existencia de la entidad al compilador ; esto es importante
en aquellos lenguajes fuertemente tipados que requieren funciones, variables y constantes, y sus
tipos deben especificarse con una declaración antes de su uso, y se usa en la declaración directa .

El término "declaración" se contrasta con frecuencia con el término "definición", pero el significado
y el uso varían significativamente entre idiomas; vea abajo. Las declaraciones son particularmente
prominentes en los idiomas de la tradición ALGOL , incluida la familia BCPL , principalmente C y C
++ , y también Pascal . Java usa el término "declaración", aunque Java no requiere declaraciones y
definiciones separadas.

Una dicotomía básica es si una declaración contiene o no una definición: por ejemplo, si una
declaración de una constante o variable especifica el valor de la constante (respectivamente, el valor
inicial de una variable), o solo su tipo; y de manera similar si una declaración de una función
específica el cuerpo ( implementación ) de la función, o solo su tipo de firma. No todos los idiomas
hacen esta distinción: en muchos idiomas, las declaraciones siempre incluyen una definición y
pueden denominarse "declaraciones" o "definiciones", según el idioma.

Sin embargo, estos conceptos se distinguen en lenguajes que requieren declaración antes de su
uso (para los cuales se utilizan declaraciones directas) y en lenguajes donde la interfaz y la
implementación están separadas: la interfaz contiene declaraciones, la implementación contiene
definiciones.

En el uso informal, una "declaración" se refiere solo a una declaración pura (solo tipos, sin valor ni
cuerpo), mientras que una "definición" se refiere a una declaración que incluye un valor o cuerpo.

19
Sin embargo, en el uso formal (en las especificaciones del lenguaje), "declaración" incluye ambos
sentidos, con distinciones más precisas por lenguaje: en C y C ++, una declaración de una función
que no incluye un cuerpo se llama un prototipo de función , mientras que una declaración de una
función que incluye un cuerpo se denomina "definición de función". En Java, las declaraciones se
presentan de dos formas.

Para los métodos públicos, se pueden presentar en interfaces como firmas de métodos, que
consisten en los nombres de los métodos, los tipos de entrada y el tipo de salida. Se puede utilizar
una notación similar en la definición de métodos abstractos , que no contienen una definición. Se
puede crear una instancia de la clase adjunta, en lugar de una nueva clase derivada, que
proporciona la definición del método, se necesitaría crear para crear una instancia de la clase. A
partir de Java 8 , la expresión lambda se incluyó en el lenguaje, que podría verse como una
declaración de función.

En la familia C de lenguajes de programación, las declaraciones a menudo se recopilan en archivos


de encabezado , que se incluyen en otros archivos de origen que hacen referencia y usan estas
declaraciones, pero no tienen acceso a la definición.

La información en el archivo de encabezado proporciona la interfaz entre el código que usa la


declaración y el que la define, una forma de ocultar información . Una declaración se usa a menudo
para acceder a funciones o variables definidas en diferentes archivos fuente o en una biblioteca .
Una discrepancia entre el tipo de definición y el tipo de declaración genera un error de compilación.

Para las variables, las definiciones asignan valores a un área de memoria que se reservó durante
la fase de declaración. Para las funciones, las definiciones proporcionan el cuerpo de la función. Si
bien una variable o función puede declararse muchas veces, normalmente se define una vez (en C
++ , esto se conoce como la regla de una definición o ODR).

Los lenguajes dinámicos como JavaScript o Python generalmente permiten redefinir las funciones,
es decir, volver a enlazarlas ; una función es una variable muy parecida a cualquier otra, con un
nombre y un valor (la definición).

A continuación, se muestran algunos ejemplos de declaraciones que no son definiciones, en C:

extern char example1;

extern int example2;

void example3(void);

20
Aquí hay algunos ejemplos de declaraciones que son definiciones, nuevamente en C:

char example1; /* Outside of a function definition it will be initialized to zero. */

int example2 = 5;

void example3(void) { /* definition between braces */ }

VARIABLES INDEFINIDAS

En algunos lenguajes de programación, se


proporciona una declaración implícita la
primera vez que se encuentra una variable de
este tipo en tiempo de compilación . En otros
idiomas, dicho uso se considera un error, que
puede generar un mensaje de diagnóstico.
Algunas lenguas han comenzado con el
comportamiento declaración implícita, pero a
medida que maduraban que proporciona una
opción para desactivarlo (por ejemplo, Perl 's '
use strict ' o Visual Basic ' s " Option Explicit ").
Significado de declaración de variables: En programación, las líneas de código de declaración son
aquellas en donde se escriben las variables que se usarán y los tipos de datos de definición de
declaración de variables (programación)

En programación, las líneas de código de declaración son aquellas en donde se escriben


las variables que se usarán y los tipos de datos de cada una. Algunos lenguajes de programación
obligan al programador a declarar las variables se usará y sus tipos.

Al declararse las variables, el programa en ejecución reserva ese espacio de memoria según el tipo
de datos escogido. La declaración de variables es un proceso esencial en la programación, ya que
permite al programador especificar las variables que serán utilizadas en el programa y sus
respectivos tipos de datos. Es importante destacar que algunos lenguajes de programación,
como Python, no obligan al programador a declarar las variables, lo que puede tener ventajas y
desventajas en términos de eficiencia y legibilidad del código.

En la declaración de variables, el programador debe indicar el nombre de la variable y su tipo


de dato. Los tipos de datos pueden variar de acuerdo con el lenguaje de programación utilizado,

21
pero suelen incluir tipos simples como enteros, flotantes, caracteres y booleanos, así como tipos
más complejos como arreglos y estructuras. Cada tipo de dato ocupa un espacio específico en
la memoria, lo que tiene implicaciones en la eficiencia y gestión de recursos del programa. Es
importante destacar que, al declarar variables, el programa reserva un espacio específico en la
memoria para almacenar su valor. Por lo tanto, es necesario tener en cuenta la gestión adecuada
de la memoria en el programa, evitando errores como fugas de memoria y sobrecargas que pueden
afectar su desempeño y estabilidad.

En resumen, la declaración de variables es un paso fundamental en la programación, ya que permite


al programador especificar las variables que serán utilizadas en el programa y sus tipos de datos.
Esto permite una mejor organización y gestión de recursos en el programa, lo que se traduce en
un código más eficiente y legible.

DECLARACIÓN DE VARIABLES EN C
El siguiente código declara dos variables llamadas numero1 y numero2 que contendrán números
enteros (int) y una tercera numero3 con un número flotante (float).

int numero1, numero2; float numero3;

En lenguaje C y C++ todas las variables deben declararse antes de ser usadas, de lo contrario
dará un error de compilación.

DISTINTOS TIPOS DE VARIABLES


Veamos otro ejemplo donde declaramos variables de otros tipos:

int main()
{
char caracter;
short valor;
int numero
long numeroLargo;
float numeroReal;
double numeroRealDoble;
return 0;}

DECLARACIÓN DE VARIABLE Y ASIGNACIÓN DE VALOR


También se puede declarar una variable y asignarle un valor directamente. Por ejemplo:

int contador = 0;

22
Esta línea declara una variable de nombre contador del tipo entero iniciándola en valor 0 (cero).

Declaración de variables dentro de un bucle.

También es posible declarar variables dentro de un bucle, las variables declaradas dentro de un
bucle serán accesibles sólo desde el propio bucle, esto es, tendrán un ámbito local para el bucle.

Por ejemplo, el siguiente bucle for:

for (int i=0; i < 100; i++) ...

En este caso el bucle FOR declara la variable de nombre "i".

Las líneas de código de declaración en programación son donde se escriben las variables y sus
tipos de datos. Al declarar las variables, el programa reserva espacio de memoria según el tipo de
datos elegido.

¿CUÁL ES LA IMPORTANCIA DE LAS DECLARACIONES DE VARIABLES EN LA


PROGRAMACIÓN?
Las declaraciones de variables son fundamentales en la programación porque permiten reservar
espacio en memoria para almacenar valores y asignarles un nombre significativo. Esto facilita la
organización y manipulación de los datos dentro de un programa.

¿CUÁL ES EL PROPÓSITO DE ESPECIFICAR EL TIPO DE DATOS EN UNA


DECLARACIÓN DE VARIABLE?
Es crucial especificar el tipo de datos en una declaración de variable para indicarle al compilador qué
tipo de valor se almacenará en esa variable. Esto es necesario para optimizar la memoria y
garantizar el correcto funcionamiento del programa, evitando errores de tipos de datos
incompatibles.

¿CUÁLES SON LOS TIPOS DE DATOS MÁS COMUNES UTILIZADOS EN LAS


DECLARACIONES DE VARIABLES?
Los tipos de datos más comunes utilizados en las declaraciones de variables son: enteros (int),
números de punto flotante (float), caracteres (char), cadenas de caracteres (string), booleanos (bool)
y arreglos (arrays). Estos tipos permiten almacenar diferentes tipos de información según las
necesidades del programa.

¿PUEDO MODIFICAR EL TIPO DE DATO DE UNA VARIABLE DESPUÉS DE HABERLA


DECLARADO?
En lenguajes de programación fuertemente tipados, como Java o C++++, no se puede modificar el
tipo de dato de una variable una vez que ha sido declarada. Sin embargo, en lenguajes de

23
programación débilmente tipados, como JavaScript, es posible cambiar el tipo de dato de una
variable durante la ejecución del programa.

¿ES OBLIGATORIO ASIGNAR UN VALOR INICIAL A UNA VARIABLE EN LA


DECLARACIÓN?
Depende del lenguaje de programación utilizado. Algunos lenguajes, como C++, requieren que se
asigne un valor inicial a una variable en la declaración, mientras que, en otros, como Python, esto
no es obligatorio. En cualquier caso, es una buena práctica asignar un valor inicial para evitar errores
y facilitar el mantenimiento del código.

¿QUÉ SUCEDE SI DECLARO UNA VARIABLE CON EL MISMO NOMBRE QUE OTRA
YA EXISTENTE EN EL PROGRAMA?
Si declaras una variable con el mismo nombre que otra ya existente en el programa, se producirá
un conflicto de nombres y el compilador o intérprete mostrará un error. Para evitar este problema,
es importante usar nombres de variables únicos y significativos en el programa.

ALMACENAMIENTO
Hay dos clases, almacenamiento primario, que son los que usa la CPU directamente
(memoria principal, memoria caché, etc) y el almacenamiento secundario, a los cuales la CPU no
accede directamente, sino que deben almacenarse previamente en uno primario. Son de
almacenamiento secundario los discos magnéticos, ópticos, cintas magnéticas, tambores
magnéticos, etc.El almacenamiento de datos puede usarse también para copias de seguridad,
ver backup.Con el correr de los años, el almacenamiento de datos informáticos ha ido bajando de
precio. Por ejemplo, 1 GB de memoria en 1956 costaba 8,2 millones de dólares.

El almacenamiento es la propiedad o capacidad de guardar datos que tiene un dispositivo


electrónico. Computadoras, teléfonos celulares, tabletas, televisores smart, calculadoras, consolas
de videojuegos y demás dispositivos electrónicos tienen esta propiedad, la cual es muy útil no sólo
para guardar datos sino también para procesarlos.

CLASIFICACIÓN PRINCIPAL DE ALMACENAMIENTO EN COMPUTADORAS


En las computadoras típicas existen dos tipos de almacenamiento.

- Almacenamiento primario: que son los que usa la CPU directamente (memoria principal, memoria
caché, etc)

- Almacenamiento secundario: a los cuales la CPU no accede directamente, sino que deben
almacenarse previamente en uno primario. Son de almacenamiento secundario los discos
magnéticos, ópticos, cintas magnéticas, tambores magnéticos, etc.

24
DIRECCIONAMIENTO
Un modo de direccionamiento especifica la forma de calcular la dirección de memoria efectiva de
un operando mediante el uso de la información contenida en registros y / o constantes, contenida
dentro de una instrucción de la máquina o en otra parte. Los modos de direccionamiento son las
diferentes maneras de especificar en informática un operando dentro de una instrucción
(lenguaje ensamblador). Cómo se especifican e interpretan las direcciones de memoria según las
instrucciones. Pueden ser:

o Inmediato: En la instrucción está incluido directamente el operando.


o Directo: El campo de operando en la instrucción contiene la dirección en memoria donde se
encuentra el operando.
o Indirecto: El campo de operando contiene una dirección de memoria, en la que se encuentra
la dirección efectiva del operando.
o Absoluto: El campo de operando contiene una dirección en memoria, en la que se encuentra
la instrucción.
o De registro: Sirve para especificar operandos que están en registros.
o Indirecto mediante registros: El campo de operando de la instrucción contiene un identificador
de registro en el que se encuentra la dirección efectiva del operando.
o De desplazamiento: Combina el modo directo e indirecto mediante registros
o De pila: Se utiliza cuando el operando está en memoria y en la cabecera de la Pila.

REPRESENTACIÓN DE MEMORIA
• Secure Digital (SD)

Están basadas en el formato Multimedia Card (MMC). Las tarjetas marcadas como HC (High
Capacity) funionan a alta velocidad y tienen tasas de transferencia de datos muy altas; algunas
cámaras fotográficas digitales requieren este tipo de tarjetas para poder grabar video con fluidez o
para capturar múltiples fotografías en sucesión rápida.

• Starmedia

También conocidas como (Tarjeta de Disco Floppy en Estado Sólido). Son duraderas y su apariencia
física es similar a la de un disquete, pero con el tamaño aproximado de una estampilla de correo.
Su forma impide introducirlas en su ranura en sentido contrario.

• Memory Stick

25
Tarjetas digitales con con memoria flash diseñadas con la compañía Sony. Ademas de ser aptas
para cámaras digitales de esta marca, las Memory Stick se pueden utilizar en una gran variedad de
aparatos digitales. Estas tarjetas sirven para almacenar imágenes, música, datos, textos y gráficos
Ofrecen una alta velocidad de acceso y o necesitan ningún dispositivo para la reproducción, pues
disponen de un adaptador para disquetes.

• Minini SD FLASH MEMORY

Por su tamaño tan reducido, este formato de tarjeta se utiliza especialmente en teléfonos celulares.
Combina gran capacidad de almacenamient, alta tasa de transferencia de datos, confiabilidad,
seguridad y bajo consumo de energía. También se utiliza en reproductores de audio, cámaras
digitales (por medio de un adaptador) y asistentes digitales personales (PDA).

• Micro SD CARD

Este formato de tarjeta solo mide 10.9mm x 14.9mm x 1mm y puede almacenar vrios GB de
información. Al igual que el MINI SD, es my utilizado en teléfonos celular. En 1980, 184 mil dólares;
en 1990 eran 5.200 dólares; en 2000 eran 12 dólares, y en 2006 fueron 1,2 dólares.

COLA (DEFINICIÓN)
Una cola es una estructura de almacenamiento, donde la podemos considerar como una lista de
elementos, en la que éstos van a ser insertados por un extremo y serán extraídos por otro. Las colas
son estructuras de tipo FIFO (first-in, first-out), ya que el primer elemento en entrar a la cola será el
primero en salir de ella. Existen muchísimos ejemplos de colas en la vida real, como, por ejemplo:
personas esperando en un teléfono público, niños esperando para subir a un juego mecánico,
estudiantes esperando para subir a un camión escolar, etc.

Podemos representar a las colas de dos formas :

• Como arreglos
• Como listas ordenadas

En esta unidad trataremos a las colas como arreglos de elementos, en donde debemos definir el
tamaño de la cola y dos apuntadores, uno para accesar a el primer elemento de la lista y otro que
guarde el último. En lo sucesivo, al apuntador del primer elemento lo llamaremos F, al del último
elemento A y MÁXIMO para definir el número máximo de elementos en la cola.

26
INICIALIZACIÓN

Para la inicialización de una lista de listas primero tendremos que reservar memoria para la lista (para
indicar cuántos elementos habrá en ella) y después habrá que reservar memoria para cada uno de
los elementos de dicha lista (pues son listas). Según el párrafo anterior, si se deseara una lista de n-
elementos en una lista, y que cada uno de esos elementos contuvieran una lista de m-valores, en total
se necesitaría memoria para n×m valores. Dicha reserva se realiza con una sola instrucción:

lista = new TipoDeDato[n][m]; // Reserva memoria para nxm-valores

Esta es su representación gráfica. La variable lista, después del new, almacena una referencia al lugar
de la memoria donde de guardan n datos y cada uno de esos datos almacena una referencia al lugar
de la memoria donde se guarda otra lista de m datos.

Uno podría
desear que cada uno de los n-elementos de la lista esté formado por otra lista cada cual con una
longitud diferente. Por ejemplo, que el primer elemento esté formado por una lista de 2 elementos,
que el segundo elemento esté formado por una lista de 13 elementos, que el tercer elemento esté
formado por una lista de 7 elementos, y así sucesivamente. Este tipo de estructura de datos se puede
realizar también utilizando solo arrays. Para ellos se deberá de realizar estos dos pasos:

• establecer el número de lista que contendrá mediante la instrucción new TipoDeDato[n][ ].

• indicar para cada uno de los términos de la lista de que longitud será la lista que
"almacenará".

Ejemplo 2. Un array escalonado

27
Observa cómo se pueden construir una lista de listas de distinta longitud. En este caso es una lista de
2 elementos y cada uno es una lista. El primer elemento es una lista de 4 enteros y el segundo de 2
enteros.

1234 int[][] arrayEscalonado = new int[3][];


arrayEscalonado[0] = new int[4];
arrayEscalonado[1] = new int[2];
arrayEscalonado[2] = new int[8];

Su representación gráfica es esta:

ASIGNACIÓN Y RECUPERACIÓN DE VALORES DE LOS ELEMENTOS

Una vez reservados los espacios de memoria para todos los elementos que componen las listas de
la lista, utilizaremos el sistema de índices ya estudiado.

Si array[k] es el patrón básico para acceder el elemento k-ésimo de un array:

1. lista[i], responde al acceso del elemento i-ésimo de la lista (el cuál es otro array);

2. lista[i][j], responde al acceso del elemento j-ésimo de la lista lista[i].

Necesitamos dos índices para acceder a cada uno de los elementos en un array de arrays.

Recuerda que para recorrer los elementos de una lista se hacía:

for (int i=0; i<lista.length; i++) {


acciones sobre lista[i]
}

pero como ahora lista[i] es otra lista, actuaremos sobre cada elemento utilizando este patrón:

28
for (int i=0; i<lista.length; i++) {
for (int j=0; j<lista[i].length; j++) {
acciones sobre lista[i][j]
}
}

EXTENDIENDO LA DIMENSIÓN
Todo lo explicado en los apartados anteriores sobre lista de listas se puede extender a "más
dimensiones". Por ejemplo, podemos trabajar con una lista que contenga lista y éstas a su vez
contengan otras listas.

Para añadir una nueva "dimensión" (o lista) en el array basta añadir un nuevo conjunto de
corchetes, [ ], y su índice correspondiente. Continuando con el ejemplo, se necesitará una variable
"3-dimensional", en el sentido de que se requerirán 3 índices para poder acceder a un elemento.
Una variable "3-D" se declarará como TipoDato[ ][ ][ ] variable;

Para acceder a cada uno de los elementos se necesitarán tantos índices como corchetes se utilicen
y tantos bucles (anidados) como índices para poder recorrer todos los elementos del array.

En el caso de conocer todos los elementos literales que contendrá el array existen algunos atajos.
Por ejemplo,

int[ ][ ][ ] array3D =

{ {1,3}, {5,7,8} },

{ {0,2}, {4,6}, {8,10} },

{ {11,22}, {99,88,4}, {0,9}, {3,6,2} }

};

define un array cuyos elementos son listas de listas de enteros (de distinta longitud).

ESTRUCTURAS

La programación estructurada es una teoría orientada a mejorar la claridad, calidad y tiempo de


desarrollo utilizando únicamente subrutinas o funciones. Basada en el teorema del programa
estructurado propuesto por Böhm y Jacopini, ha permitido desarrollar software de fácil comprensión.

29
¿Repetimos? ¡No te asustes! Vamos a contarte de forma sencilla y rápida todo lo que debes saber
sobre la programación estructurada. La palabra programación, a veces, asusta. Y si le
pones estructurada justo después, más. Pero en realidad, no es para tanto. Vamos a verlo.
La programación estructurada es una corriente que nació con la vocación de facilitar la vida de los
programadores, sobre todo cuando estos debían abordar fases de mejora posteriores a la creación
del programa, y de ordenar la forma en la que se creaba cualquier tipo de programa.

Para comprenderlo mejor, vamos a hacer un pequeño viaje en el tiempo. Nos vamos al año 1966,
cuando Böhm y Jacopini proponen el teorema del programa estructurado, con el que demuestran
que cualquier programa puede ser escrito utilizando solo tres instrucciones de control.

Imagínate, ¡esto fue toda una revolución! Implicaba la construcción de programas más sencillos y
rápidos, en los que disminuía la complejidad de las pruebas y el testing para ponerlos en
funcionamiento. Avanzamos dos años más en el tiempo. En 1968, Edsger Dijkstra publicó un
célebre artículo que impactó en la computación moderna: Go To Statement Considered
Harmful. ¿Por qué es tan importante? Pues porque este científico holandés promovió activamente
el uso de lenguajes de programación estructurada, fomentando la verificación formal de programas
y la eliminación de la sentencia Goto. De hecho, Dijkstra participó en el comité que diseñó Algol 60,
el primer lenguaje de programación estructurado. La programación estructurada se convierte así,
junto con la programación orientada a objetos, en uno de los paradigmas de programación más
populares que ejecuta los lenguajes más potentes que seguro conoces, incluidos, entre otros, Java,
C, Python y C++.

CARACTERÍSTICAS Y VENTAJAS
El teorema del programa estructurado es la base teórica sobre la que se construyó esta nueva forma
de programar, ya que nos da la característica fundamental de la programación estructurada. Postula
que, simplemente con la combinación de tres estructuras básicas, es suficiente para expresar
cualquier función computable.

Parece sencillo, ¿verdad? En realidad, lo es y, precisamente por eso, se abre inmediatamente el


debate entre los programadores que querían continuar con el sistema anterior y los que abrazaban
estas nuevas estructuras de control con los ojos cerrados. ¿Quién crees que ganó?

Vale, nadie fue declarado vencedor inmediatamente, pero sí que es cierto que ‘los Digital Workers
de los años 70’ empezaban a ver poco a poco las grandes ventajas que ofrecía la programación
estructurada sobre el código espagueti (los programas de computación antiguos que tenían una
estructura de control de flujo compleja e incomprensible). Y, ¿qué ventajas eran esas?

30
• Los programas desarrollados con la programación estructurada son más sencillos de
entender, ya que tienen una estructura secuencial y desaparece la necesidad de rastrear los
complejos saltos de líneas (propios de la sentencia Goto) dentro de los bloques de código
para intentar comprender la lógica interna.

• Como consecuencia inmediata de lo anterior, otra ventaja es que los programas resultantes
tendrán una estructura clara, gracias a que las sentencias están ligadas y relacionadas entre
sí.

• La fase de prueba y depuración de los programas se optimiza, ya que es mucho más sencillo
hacer el seguimiento de los fallos y errores y, por tanto, detectarlos y corregirlos.

• El coste del mantenimiento de los programas que usan la programación estructurada es más
reducido. ¿Por qué? Pues porque modificar o extender los programas es más fácil al estar
formados por una estructura secuencial.

• Al ser más sencillos los programas, son más rápidos de crear y los programadores aumentan
su rendimiento.

LAS 3 ESTRUCTURAS BÁSICAS


Ya nos ha quedado claro que la programación estructurada es una forma de programar más sencilla
que se basa únicamente en la combinación de tres órdenes. Pero ¿cuáles son esos tipos de
estructuras de control que son capaces de expresarlo todo?

• Secuencia. La estructura secuencial es la que se da de forma natural en el lenguaje, porque


las sentencias se ejecutan en el orden en el que aparecen en el programa, es decir, una
detrás de la otra.

• Selección o condicional. La estructura condicional se basa en que una sentencia se ejecuta


según el valor que se le atribuye a una variable booleana. ¡Un pequeño inciso! Una variable
booleana es aquella que tiene dos valores posibles. Por tanto, esta estructura se puede
ejecutar de dos formas distintas, dependiendo del valor que tenga su variable.
Como apunte para los verdaderos amantes de la programación: para las estructuras
condicionales o de selección, Python dispone de la sentencia if, que puede combinarse
con elif y/o else.

• Iteración (ciclo o bucle). La estructura de repetición ejecuta una o un conjunto de sentencias


siempre que una variable booleana sea verdadera. Para los bucles o iteraciones, los
lenguajes de programación usan las estructuras while y for.

31
Y solamente con estas tres estructuras de control, ¡se pueden escribir todos los programas y
aplicaciones posibles! ¡Todos! Si estás pensando que los lenguajes de programación tienen más
estructuras, sí, es cierto, pero cualquiera de ellas puede ser construida gracias a estas tres básicas
que hemos citado. ¿Comprendes ahora todo el revuelo que se formó con el teorema de la
programación estructurada?

PUNTEROS
Un puntero no es más que una variable, en la cual se almacena una dirección de memoria. Esto
parece muy simple, pero luego da muchos quebraderos de cabeza. Al ser una dirección de memoria,
le podemos decir a un puntero que en ese lugar donde apunta queremos almacenar un valor, por
ejemplo, un número. Para realizar una explicación muy sencilla, vamos a decir que un puntero es
como un buzón de correos y nuestra memoria RAM, es similar a una comunidad de vecinos donde
hay muchos buzones. Un puntero es una variable que contiene la dirección de memoria de otra
variable que contiene al dato en un arreglo. Esto quiere decir, que el puntero apunta al espacio físico
donde está el dato o la variable. Un puntero puede apuntar a un objeto de cualquier tipo, como por
ejemplo, a una estructura o una función. Los punteros se pueden utilizar para referencia y manipular
estructuras de datos, para referenciar bloques de memoria asignados dinámicamente y para proveer
el paso de argumentos por referencias en las llamadas a funciones.

Muchas de las funciones estándares de C, trabajan con punteros, como es el caso


del scanf o strcpy. Estas funciones reciben o devuelven un valor que es un puntero. Por ejemplo:
A scanf se le pasa la dirección de memoria del dato a leer...

char a;

32
scanf ("%c",&a);

En este caso se le pasa la dirección de memoria de la variable a, la cual tiene reservado un espacio
en la memoria por el compilador. Podríamos hacer lo mismo con este código:

char *a = (char*) malloc (sizeof (char));


scanf ("%c", a);

En este código, al scanf le pasamos el puntero en sí. El puntero es una variable, como bien se ha
dicho anteriormente, que contiene una dirección de memoria, por tanto, no es necesario el uso
de & para pasarle la dirección de memoria a scanf. Anteriormente hemos tenido que reservar un
espacio de memoria con malloc(), que se verá su uso más adelante.

Este código sería erróneo y daría una violación de segmento:

char *a;
scanf ("%c", a);

En este caso, no hemos reservado memoria, por lo tanto la función escribirá en una dirección de
memoria que no le pertenece, y por ello se producirá la susodicha violación de segmento.

DECLARANDO PUNTEROS
Ya se dijo que un puntero es una variable que guarda la dirección de memoria de otra variable. Un
puntero se declara igual que cualquier otra variable, pero anteponiendo un * (asterisco) antes del
nombre de la variable.

Su sintaxis sería:

tipo *NombrePuntero = NULL; Se iguala a NULL para saber que no tiene asignada ninguna
dirección.

Donde tipo es el tipo de dato al que referenciará este puntero, es decir, que si se necesita guardar
la dirección de memoria de un dato int, se necesita un puntero de tipo int.

EXPLICACIÓN
Veamos el siguiente código:

#include <stdio.h>

33
int main()
{
int a=0; //Declaración de variable entera de tipo entero
int *puntero; //Declaración de variable puntero de tipo entero
puntero = &a; //Asignación de la dirección memoria de a
printf("El valor de a es: %d. \nEl valor de *puntero es: %d. \n",a,*puntero);
printf("La dirección de memoria de *puntero es: %p",puntero);
return 0;
}

Igual que cuando usamos un &, en la lectura de datos con scanf, igual de esta forma lo usamos
aquí, tal vez te acordarás de que decíamos que las cadenas de caracteres (%s) no usaban este
operador, esto es porque en una cadena de caracteres es un arreglo de caracteres, por lo que el
primer carácter es la dirección de inicio de la cadena. El operador *, nos permite acceder al valor de
la dirección del puntero, en este caso nos permite acceder al valor que contiene a la variable a.

De esta forma "a" y "*puntero" muestran el mismo dato, pero esto no quiere decir que sea lo mismo,
uno es un entero y el otro un puntero.

La impresión con %p, es para poder imprimir la dirección de memoria en valor hexadecimal (0x...),
también podemos imprimir: ...%p",&a) y funciona de la misma forma, y es lógico que tanto "a" como
"puntero" tienen la misma dirección de memoria.

¿DIFERENTES DIRECCIONES?
Tal vez notaste que en cada ejecución la dirección de memoria cambia, esto es porque es el sistema
operativo quien está encargado de administrar la memoria y es éste quien dice qué espacios podrá
tomar el programa.

Esto quiere decir que uno no puede asignarle una dirección de memoria a un puntero directamente,
es decir yo no puedo hacer lo siguiente.

int *puntero=0xbfc5b1c8;

Esto no puedo ni debo hacerlo ya que yo no sé que está haciendo esta dirección de memoria, si el
sistema la tiene o no disponible, etc... Pero sí puedo hacer esto:

34
int *puntero=NULL;

NULL, es el espacio en memoria con dirección 0, esto quiere decir que existe, lo que significa que
le asignamos una dirección válida al puntero, pero el valor que tiene NULL no se nos permite
modificarlo, ya que pertenece al sistema.

USO EN FUNCIONES
Los punteros se usan habitualmente como parámetros de funciones. El siguiente código muestra
como declarar una función que usa un puntero como argumento. Teniendo en cuenta que C pasa
todos los argumentos por valor, para poder modificar un valor desde el código de la función, se debe
usar un puntero al valor a modificar. También se usan punteros a estructuras como argumentos de
una función aún cuando la estructura no sea modificada dentro de la función. Esto es realizado para
evitar copiar todo el contenido de la estructura dentro de la pila.

int MyFunction( struct MyStruct *pStruct );

OPERADORES
Ya anteriormente te poníamos algunos ejemplos de como asignar la dirección de memoria a un
puntero y de cómo acceder al valor de este.

Operador de Dirección (&): Este nos permite acceder a la dirección de memoria de una variable.

Operador de Indirección (*): Además de que nos permite declarar un tipo de dato puntero, también
nos permite ver el VALOR que está en la dirección asignada.

Incrementos (++) y Decrementos (--): Te darás cuenta que puedes usar un puntero como si de un
array se tratase, es por esto que permite estos operadores.

De lo anterior podemos decir que:

int a; int *puntero=&a;


printf("%d",a);
printf("%d",*puntero); \\Es Igual

OPERACIONES ARITMÉTICAS
Un puntero nos permite sumar o restar números enteros, pero su funcionamiento ahora es de
posiciones, es decir que nos permitirá movernos a la siguiente dirección de memoria.

35
A un puntero no se le puede realizar multiplicaciones, divisiones, sumas o restas con otro puntero o
con un valor de tipo coma flotante (float, double...). Esto es por que un puntero no es un valor, sólo
es una dirección.

En un puntero se pueden realizar varias operaciones de tipo enteras, pero en dependencia de cómo
se usen, sus resultados pueden ser muy diferentes, a continuación les muestro algunas de estas
operaciones:

//Definamos estas variables:


int x[100],b,*pa,*pb;
//...
x[50]=10; //Le asignamos el valor de 10, al array x en la posicion #50
pa=&x[50]; //Le asignamos al puntero pa la direccion de memoria que tiene x[50]
//Ahora mostramos algunas posibles operaciones:
b = *pa+1; //Esto es: Al valor que tiene el array de x[50] sumarle 1.
//Esto es igual a: b=x[50]+1; => Su valor sería igual a 11.
b = *(pa+1); //Esto primero pasa a la siguiente direccion de memoria y luego lo referencia
//El resultado es: b = x[51];
pb = &x[10]; //al puntero pb se le asigna la direccion de x[10]
*pb = 0; //Al valor que tiene el puntero se le asigna 0
//Esto es igual que decir: x[10] = 0
*pb += 2; //El valor del puntero se incrementa en dos unidades, es decir x[10] += 2
(*pb)--; //El valor del puntero se decrementa en una unidad.
x[0] = *pb--; //A x[0] se le pasa el valor de x[10] y el puntero pb, pasa a apuntar a x[9]
//recuerda, que -- es post-decremento, primero asignará y luego restará.

PUNTEROS CONSTANTES
Es posible que hayas pensado cómo declarar un puntero como una constante, tal vez pensaste en
un #define, o en un atributo const. Bueno es posible usar el atributo const, pero para un puntero hay
que decidir qué es lo que se quiere volver constante, ¿el valor -objeto- o la dirección?

Valor Constante:

int a=10,b=20;
const int *p = &a; //objeto constante y puntero variable
*p = 15; // ERROR: el valor apuntado por p es constante.

36
p=&b; //Correcto: p pasa a apuntar a un nuevo objeto.

Pero de esta forma no es muy útil declararlo, pues el que hicimos constante fue el valor al que
apunte p, es decir, mejor hubiésemos hecho que el puntero fuese una constante.

Dirección de memoria constante:

int a=10,b=20;
int * const p = &a; //objeto variable y puntero constante
*p = 15; // Correcto: El valor apuntado es variable.
p=&b; //ERROR: p es constante.

Para recordar de una manera fácil, todo lo que está a la izquierda o antes del “*“ es el tipo de dato
al que apunta el puntero.

const int *p en este caso la variable es un entero constante.

int *p const en este caso la variable es un entero, pero como la palabra clave const esta a la
derecha o despues del “*”, entonces la constante es el puntero.

PUNTEROS GENÉRICOS
Un puntero a cualquier tipo de dato puede convertirse a un puntero del tipo void *. Por esto un
puntero a void *, recibe el nombre de puntero genérico.

En C, se permite la conversión implícita de punteros, pero en C++ esto no es posible, así que por
compatibilidad y buena práctica recomendamos usar la conversión explícita (cast).

Supongamos:

int *puntero;
funcion (*puntero);
....
void funcion (void *p)

int *q;
q=(int *)p; //En C se podria hacer q = p;

37
Es decir que un puntero a void se puede usar sin importar el tipo de dato, recuerden que uno no
puede trabajar con punteros que referencia a un tipo de dato diferente, como lo es un puntero a
char, con un puntero a int.

PUNTEROS Y MATRICES
Anteriormente decíamos que una matriz es una secuencia de espacios en memoria, que nos
permitían alojar datos en cada uno y un puntero es una variable que guarda la dirección de memoria,
también decíamos cómo recorre las direcciones de memoria con los operadores ++ y --.

Aquí veremos cómo puede usarse un puntero como si de una matriz se tratase, luego de que veas
que es técnicamente lo mismo, te preguntaras por que usar punteros, pero estos son muy
necesarios y únicos que nos permiten realizar cosas que con un array normal, no se puede, como
asignarle memoria dinámica, etc...

#include <stdio.h>
int main()
{
int array[10]={0,2,3,5,5,6,7,8,9,0}; //Declarar e inicializar un arreglo.
int *puntero = &array[0]; //Le damos la dirección de inicio del arreglo
int i; //variable contadora...
for (i=0;i<10;i++)
printf("%d\n",*(puntero+i)); //imprimimos los valores del puntero que es equivalente a imprimir
los valores del arreglo.
return 0;
}

Habrás notado que he usado *(puntero+i), así como explica la sección de operaciones aritméticas,
pero también podemos acceder de otras maneras como lo son:

array[i] => Accede como un array normal


*(array+i) => También accede como un array normal.
puntero[i] => Accedemos al valor de puntero sub i
*(puntero+i) => Accedemos al valor de puntero + i.

38
PUNTEROS A CADENAS DE CARACTERES
Ya hemos visto el uso que se le puede dar a un puntero como si de un array se tratase, entonces
usando esta misma lógica podemos hacer un array de caracteres usando punteros.

char *nombre="Gustavo A. Chavarria";//Es como un array de 20 caracteres


printf("%s",nombre);

Sin embargo, al tratarse de una constante de caracteres no podemos modificarla después de definir
sus valores. Como por ejemplo no podemos remplazar un carácter, o leer un nuevo valor.

gets(nombre); //ERROR en ejecución

Para poder modificar el valor de este puntero, este tendría que apuntar a una dirección que no sea
una constante, como un array.

char nombre[]="Gustavo A. Chavarria"; //declaramos un array de caracteres


char *puntero=nombre;//Asignamos al puntero el comienzo del array
printf("%s \nIngrese otro nombre: ",puntero);//Escribimos en pantalla nombre...
gets(puntero); //leemos otro nombre
printf("%s",puntero); //escribimos el nuevo nombre...

Esta vez pudiste notar que sí se pudo remplazar el valor del nombre, pero aun la cantidad de
caracteres está limitada por el array original, más adelante veremos cómo solucionar esto con
memoria dinámica.

MATRICES DE PUNTEROS
Es muy probable que ya te hayas dicho: Si un puntero es una variable, ¿Puedo tener un array de
punteros? La respuesta sería NO Exactamente. Como ya habíamos explicado antes, un puntero
trabaja de la misma forma que un array, tanto que podemos decir que un puntero es un array,
entonces si definimos un array de un array, nos daría como resultados un array bidimensional. En
la práctica es mucho más común utilizar un array de punteros que un array bidimensional.

Hay que recordar que siguen siendo punteros, es decir sólo apuntan a una dirección de memoria,
por ende, hay que asignarles la dirección de memoria a cada uno de los elementos del puntero. Sin
embargo, podemos asignar en un solo ciclo todas las filas.

39
Ejemplo:

#include <stdio.h>
int main()
{
int *puntero[5]; //array de puntero
int a[5][5]; //Array bidimensional.
int i;
for (i=0;i<5;i++){
puntero[i]=&a[i]; //Asignamos las filas al puntero.
}
//Pueden imprimir tambien en un ciclo
//Tambien pueden acceder mediante un ciclo anidado a la variables del puntero[i][j]
}

PUNTEROS A PUNTEROS
Es una variable que contiene la dirección de memoria de un puntero, el cual a su vez contiene la
dirección de memoria de un tipo de dato. Se usa ** para definir un puntero a un puntero. Recuerden
que un puntero sigue siendo un espacio en memoria, pero en vez de almacenar un valor almacena
una dirección.

Si decimos que:

int a=0; //Supongamos que es una variable cuya direccion es 0x1601


int *puntero1=&a; //El puntero tiene guardada la direccion de a,
//pero este tiene como direccion 0x1890
int **puntero2=&puntero1; //**puntero2 guarda la direccion 0x1890

Ahora se entiende mejor. Al uso de punteros se le llama variables con niveles de indirección, ya que
no apuntan directamente a un valor, sino que apuntan a alguien que lo tiene. Basándonos en esto
podemos decir que *puntero1 es un puntero con un nivel de indirección y *puntero2 es un puntero
con dos niveles de indirección. En general estos tipos de datos son usados con matrices
multidimensionales.

40
MATRICES DE PUNTEROS A CADENAS DE CARACTERES
No hablaremos sobre este tema, debido a que es prácticamente una matriz de caracteres que se
usa mediante punteros, y esto es técnicamente lo mismo que hemos estado viendo anteriormente.
También podemos usar punteros a punteros y guardar múltiples cadenas.

Ejemplos:
Tenga en cuenta el siguiente bloque de código que declara 2 punteros

/*1*/ struct MyStruct {


/*2*/ int m_aNumber;
/*3*/ float num2;
/*4*/ };
/*5*/
/*6*/ int * pJ2;
/*7*/ struct MyStruct * pAnItem;

Las primeras 4 líneas definen la estructura. La linea 6 declara una variable que apuntará a un entero,
y la línea 7 declara una variable que apunta a algo de la estructura MyStruct. Entonces declarar un
puntero es algo que apunta a algo de algún tipo, más que contener el tipo. El asterisco ( * ) se coloca

antes del nombre de la variable.

En las siguientes líneas de código, var1 es un puntero a un entero largo ( long ) mientras var2 es

un entero largo ( long ) y no un puntero a un entero largo. En la segunda línea se declara p3 como

un puntero a un puntero de un entero.

long * var1, var2;


int ** p3;

ASIGNANDO VALORES A PUNTEROS


Continuamos con el proceso de asignar valores a los punteros, para esto utilizamos el operador & o

'la dirección de'.

int myInt;
int *pPointer;
struct MyStruct dvorak;

41
struct MyStruct *pKeyboard;
pPointer = &myInt;
pKeyboard = &dvorak;

Aquí, pPointer apunta a myInt y pKeyboard apuntará a dvorak.

Los punteros también pueden ser asignados a referencias de memorias dinámicas creadas
comúnmente por las funciones malloc() y calloc().

#include <stdlib.h>
...
struct MyStruct *pKeyboard;
...
pKeyboard = malloc(sizeof(struct MyStruct));
...

La función malloc retorna un puntero de memoria asignada de manera dinámica (o NULL si falla).
El tamaño de esta memoria es definido de modo que pueda contener la estructura MyStruct

El siguiente código es un ejemplo mostrando un puntero siendo asignado a una referencia y se


retorna el valor del puntero en la función.

static struct MyStruct val1, val2, val3, val4;


...
struct MyStruct *ASillyFunction( int b )
{
struct MyStruct *myReturn;
if (b == 1) myReturn = &val1;
else if (b==2) myReturn = &val2;
else if (b==3) myReturn = &val3;
else myReturn = &val4;
return myReturn;
}
...
struct MyStruct *strPointer;

42
int *c, *d;
int j;
...
c = &j; /* puntero asignado usando el operador & */
d = c; /* asignando un puntero a otro */
strPointer = ASillyFunction( 3 ); /* puntero retornado de la funcion */

Cuando se retorna un puntero de una función, se debe tener cuidado de que el valor apuntado no
sea de una referencia de una variable local a la función, porque estos valores desaparecen después
de salir de la función y el puntero estaría mal referenciado, causando errores en tiempo de ejecución
en el programa.

La memoria creada dinámicamente dentro de la función puede devolverse como puntero, el valor
de retorno, aunque es creado en una variable local la dirección como tal se devuelve por valor
dejando esta información válida. Además, en esta comunidad en lugar de tener el nombre puesto
en el buzón, cada uno va a tener un identificador único.

Como se puede ver en la imagen, hay muchos buzones (zonas de memoria), pero no todas las
podemos usar, ya que hay buzones que son nuestros y otros que son de otros vecinos (otros
programas). El buzón b5 tiene un papel con el número 23 escrito (en esa posición identificada
como b5 está almacenado el número 23). El buzón b1 es un puntero, ya que lo que tiene
almacenado (b5), no es un valor, sino un identificador de otro buzón (una dirección de memoria).

¿CÓMO SE USA UN PUNTERO?


Una vez que ya sabemos que es un puntero, una variable cuyo valor es una dirección de memoria,
vamos a explicar cómo se utilizan. Imaginamos que el cartero sabiendo que hay dos buzones
nuestros, decide introducir un paquete (el valor 23) en uno de nuestros buzones. Pero se da cuenta

43
de que lo introdujo en el buzón que no era, entonces se le ocurre dejarnos en el buzón correcto (b1),
un papel donde pone “tu paquete está en b5“. La manera de obtener el valor es bien sencilla,
nosotros abriríamos b1, veríamos que lo que hay dentro es el papel y entonces diríamos, para
alcanzar el valor, tengo que ir a b5 y obtener su contenido.

En la imagen superior se puede ver cómo funcionan realmente los punteros. El carácter * representa
a un puntero en C. Si quieres aprender este lenguaje te recomiendo este curso de programación en
C. En la dirección de memoria 0x67 tenemos almacenado un 5. Podemos decir que la variable cuya
dirección de memoria es 0x67 es un entero o dicho de otra manera, que tenemos un entero de valor
5 almacenado en 0x67. En la dirección de memoria 0x75 tenemos almacenado otra dirección de
memoria, la 0x67. En este caso tenemos un puntero a entero, ya que tenemos en 0x75 almacenada
la dirección de memoria de un entero. Es importante recalcar que tenemos dónde está el entero, no
cuál es su valor.

De igual manera, en la dirección 0x88 tenemos almacenado otra dirección de memoria, pero en este
caso no es un puntero a entero, ya que la dirección de memoria almacenada no es la de un entero
sino la de un puntero a entero. Esto da como resultado que tenemos un puntero a puntero a entero.
Como ves es fácil generalizar su funcionamiento partiendo de este ejemplo. Respecto al uso dentro
de un programa, los punteros se usan ya que permiten realizar operaciones de manera más eficiente
al trabajar con direcciones de memoria. Por ejemplo, si tuviéramos que intercambiar el valor de dos
cadenas de texto de 200bytes cada una, es mucho más eficiente cambiar los punteros a cada una
de las cadenas (2 bytes, uno por puntero), que copiar el contenido. El tener que gestionar
manualmente estos punteros, quizás hacen de C un lenguaje complejo para empezar a programar.

44
Ejemplo práctico:

Muchos se preguntarán todo esto está muy bien, pero es cierto o me están engañando. Para ello os
dejamos el siguiente programa en C, que os puede servir para afianzar vuestros conocimientos con
los punteros.

#include <stdio.h>

#include <stdlib.h>

int main(){

int valor =5 ;

int *p;

int **pp;

p=&valor;

pp=&p;

printf("Contenido en memoria: %8d Direccion de memoria: %p Tipo de dato: int\n", valor, &valor );

printf("Contenido en memoria: %p Direccion de memoria: %p Tipo de dato: int*\n",p,&p);

printf("Contenido en memoria: %p Direccion de memoria: %p Tipo de dato: int**\n",pp,&pp);

printf("\n\nEl valor al que apunta mi puntero a entero es: %d",*p);

El resultado de la ejecución es: Contenido en memoria: 5

Direccion de memoria: 0x5fcaec Tipo de dato: int Contenido en memoria: 0x5fcaec

Direccion de memoria: 0x5fcae0 Tipo de dato: int* Contenido en memoria: 0x5fcae0

Direccion de memoria: 0x5fcad8 Tipo de dato: int** El valor al que apunta mi puntero a entero es: 5

MANEJO DE ARCHIVOS
El manejo de archivos se convertir en un tema fundamental dentro del campo de la Programación,
pues en ellos radica parte la información, que nuestros programas generen, tanto al usuario como
a nosotros los programadores. Así como hemos revisado la salida y entrada por pantalla y teclado

45
respectivamente, veremos ahora la entrada y/o salida de datos utilizando ficheros, lo cual será
imprescindible para un gran número de aplicaciones que deseemos desarrollar.

FICHEROS
El estándar de C contiene varias funciones para la edición de ficheros, éstas están definidas en la
cabecera stdio.h y por lo general empiezan con la letra f, haciendo referencia a file. Adicionalmente
se agrega un tipo FILE, el cual se usará como apuntador a la información del fichero. La secuencia
que usaremos para realizar operaciones será la siguiente:

• Crear un apuntador del tipo FILE *


• Abrir el archivo utilizando la función fopen y asignándole el resultado de la llamada a
nuestro apuntador.
• Hacer las diversas operaciones (lectura, escritura, etc).
• Cerrar el archivo utilizando la función fclose.
FOPEN
Esta función sirve para abrir y crear ficheros en disco.

El prototipo correspondiente de fopen es:

FILE * fopen (const char *filename, const char *opentype);

Los parámetros de entrada de fopen son:

filename: una cadena que contiene un nombre de fichero válido. opentype: especifica el tipo de
fichero que se abrirá o se creará. Una lista de parámetros opentype para la función fopen son:

• "r" : abrir un archivo para lectura, el fichero debe existir.


• "w" : abrir un archivo para escritura, se crea si no existe o se sobreescribe si existe.
• "a" : abrir un archivo para escritura al final del contenido, si no existe se crea.
• "r+" : abrir un archivo para lectura y escritura, el fichero debe existir.
• "w+" : crear un archivo para lectura y escritura, se crea si no existe o se sobreescribe si
existe.
• "r+b ó rb+" : Abre un archivo en modo binario para actualización (lectura y escritura).
• "rb" : Abre un archivo en modo binario para lectura.

Adicionalmente hay tipos utilizando "b" (binary) los cuales no serán mostrados por ahora y que solo
se usan en los sistemas operativos que no pertenecen a la familia de unix.

46
FCLOSE
Esta función sirve para poder cerrar un fichero que se ha abierto.

El prototipo correspondiente de fclose es:

int fclose (FILE *stream);

Un valor de retorno cero indica que el fichero ha sido correctamente cerrado, si ha habido algún
error, el valor de retorno es la constante EOF.

Un ejemplo pequeño para abrir y cerrar el archivo llamado fichero.in en modo lectura:

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv)
{
FILE *fp;
fp = fopen ( "fichero.in", "r" );
if (fp==NULL) {fputs ("File error",stderr); exit (1);}
fclose ( fp );
return 0;
}

Como vemos, en el ejemplo se utilizó el opentype "r", que es para la lectura.

Otra cosa importante es que el lenguaje C no tiene dentro de sí una estructura para el manejo de
excepciones o de errores, por eso es necesario comprobar que el archivo fue abierto con éxito "if
(fp == NULL)". Si fopen pudo abrir el archivo con éxito devuelve la referencia al archivo (FILE *), de
lo contrario devuelve NULL y en este caso se deberá revisar la dirección del archivo o los permisos
de este. En estos ejemplos solo vamos a dar una salida con un retorno de 1 que sirve para señalar
que el programa termino por un error.

FEOF
Esta función sirve para determinar si el cursor dentro del archivo encontró el final (end of file). Existe
otra forma de verificar el final del archivo que es comparar el caracter que trae fgetc del archivo con
el macro EOF declarado dentro de stdio.h, pero este método no ofrece la misma seguridad (en
especial al tratar con los archivos "binarios").

47
La función feof siempre devolverá cero (Falso) si no es encontrado EOF en el archivo, de lo contrario
regresará un valor distinto de cero (Verdadero).

El prototipo correspondiente de feof es:

int feof(FILE *fichero);

REWIND
Literalmente significa "rebobinar", sitúa el cursor de lectura/escritura al principio del archivo.

El prototipo correspondiente de rewind es:

void rewind(FILE *fichero);

LECTURA
Un archivo generalmente debe verse como un string (una cadena de caracteres) que esta guardado
en el disco duro. Para trabajar con los archivos existen diferentes formas y diferentes funciones. Las
funciones que podríamos usar para leer un archivo son:

• char fgetc(FILE *archivo)


• char *fgets(char *buffer, int tamano, FILE *archivo)
• size_t fread(void *puntero, size_t tamano, size_t cantidad, FILE *archivo);
• int fscanf(FILE *fichero, const char *formato, argumento, ...);

Las primeras dos de estas funciones son muy parecidas entre si. Pero la tercera, por el numero y el
tipo de parámetros, nos podemos dar cuenta de que es muy diferente, por eso la trataremos aparte
junto al fwrite que es su contraparte para escritura.

FGETC
Esta función lee un caracter a la vez del archivo que está siendo señalado con el puntero *archivo.
En caso de que la lectura sea exitosa devuelve el caracter leído y en caso de que no lo sea o de
encontrar el final del archivo devuelve EOF.

El prototipo correspondiente de fgetc es:

char fgetc(FILE *archivo);

48
Esta función se usa generalmente para recorrer archivos de texto. A manera de ejemplo vamos a
suponer que tenemos un archivo de texto llamado "prueba.txt" en el mismo directorio en que se
encuentra la fuente de nuestro programa. Un pequeño programa que lea ese archivo será:

#include <stdio.h>
#include <stdlib.h>

int main()
{
FILE *archivo;
char caracter;
archivo = fopen("prueba.txt","r");
if (archivo == NULL)
{
printf("\nError de apertura del archivo. \n\n");
}
else
{
printf("\nEl contenido del archivo de prueba es \n\n");
while((caracter = fgetc(archivo)) != EOF)
{
printf("%c",caracter);
}
}
fclose(archivo);
return 0;
}

FGETS
Esta función está diseñada para leer cadenas de caracteres. Leerá hasta n-1 caracteres o hasta
que lea un cambio de línea '\n' o un final de archivo EOF. En este último caso, el carácter de cambio
de línea '\n' también es leído.

El prototipo correspondiente de fgets es:

49
char *fgets(char *buffer, int tamaño, FILE *archivo);

El primer parámetro buffer lo hemos llamado así porque es un puntero a un espacio de memoria del
tipo char (podríamos usar un arreglo de char). El segundo parámetro es tamaño que es el limite en
cantidad de caracteres a leer para la funcion fgets. Y por último el puntero del archivo por supuesto
que es la forma en que fgets sabra a que archivo debe leer.

#include <stdio.h>
#include <stdlib.h>

int main()
{
FILE *archivo;
char caracteres[100];
archivo = fopen("prueba.txt","r");
if (archivo == NULL)
{
exit(1);
}
else
{
printf("\nEl contenido del archivo de prueba es \n\n");
while (feof(archivo) == 0)
{
fgets(caracteres,100,archivo);
printf("%s",caracteres);
}
system("PAUSE");
}
fclose(archivo);
return 0;
}

50
Este es el mismo ejemplo de antes con la diferencia de que este hace uso de fgets en lugar de fgetc.
La función fgets se comporta de la siguiente manera, leerá del archivo apuntado por archivo los
caracteres que encuentre y a ponerlos en buffer hasta que lea un carácter menos que la cantidad
de caracteres especificada en tamaño o hasta que encuentre el final de una línea (\n) o hasta que
encuentre el final del archivo (EOF). En este ejemplo no vamos a profundizar más que para decir
que caracteres es un buffer, los pormenores serán explicados en la sección de manejo dinámico de
memoria.

El beneficio de esta función es que se puede obtener una linea completa a la vez. Y resulta muy útil
para algunos fines como la construcción de un parser de algún tipo de archivo de texto.

FREAD
size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );

Esta función lee un bloque de una "stream" de datos. Efectúa la lectura de un arreglo de elementos
"count", cada uno de los cuales tiene un tamaño definido por "size". Luego los guarda en el bloque
de memoria especificado por "ptr". El indicador de posición de la cadena de caracteres avanza hasta
leer la totalidad de bytes. Si esto es exitoso la cantidad de bytes leídos es (size*count). Parámetros:

ptr : Puntero a un bloque de memoria con un tamaño mínimo de (size*count) bytes.

size : Tamaño en bytes de cada elemento (de los que voy a leer).

count : Número de elementos, los cuales tienen un tamaño "size".

stream: Puntero a objetos FILE, que especifica la cadena de entrada.

FSCANF
La función fscanf funciona igual que scanf en cuanto a parámetros, pero la entrada se toma de un
fichero en lugar del teclado.

El prototipo correspondiente de fscanf es:

int fscanf(FILE *fichero, const char *formato, argumento, ...);

Podemos ver un ejemplo de su uso, abrimos el documento "fichero.txt" en modo lectura y leyendo
dentro de él.

#include <stdio.h>
int main ( int argc, char **argv )

51
{
FILE *fp;
char buffer[100];
fp = fopen ( "fichero.txt", "r" );
fscanf(fp, "%s" ,buffer);
printf("%s",buffer);
fclose ( fp );
return 0;
}

ESCRITURA
Así como podemos leer datos desde un fichero, también se pueden crear y escribir ficheros con la
información que deseamos almacenar, Para trabajar con los archivos existen diferentes formas y
diferentes funciones. Las funciones que podríamos usar para escribir dentro de un archivo son:

• int fputc(int caracter, FILE *archivo)


• int fputs(const char *buffer, FILE *archivo)
• size_t fwrite(void *puntero, size_t tamano, size_t cantidad, FILE *archivo);
• int fprintf(FILE *archivo, const char *formato, argumento, ...);
FPUTC
Esta función escribe un carácter a la vez del archivo que esta siendo señalado con el
puntero *archivo. El valor de retorno es el carácter escrito, si la operación fue completada con éxito,
en caso contrario será EOF.

El prototipo correspondiente de fputc es:

int fputc(int carácter, FILE *archivo);

Mostramos un ejemplo del uso de fputc en un "fichero.txt", se escribira dentro del fichero hasta que
presionemos la tecla enter.

#include <stdio.h>
int main ( int argc, char **argv )
{
FILE *fp;

52
char caracter;
fp = fopen ( "fichero.txt", "a+t" ); //parámetro para escritura al final y para file tipo texto
printf("\nIntroduce un texto al fichero: ");
while((caracter = getchar()) != '\n')
{
printf("%c", fputc(caracter, fp));
}
fclose ( fp );
return 0;
}

FPUTS
La función fputs escribe una cadena en un fichero. la ejecución de la misma no añade el carácter
de retorno de línea ni el carácter nulo final. El valor de retorno es un número no negativo o EOF en
caso de error. Los parámetros de entrada son la cadena a escribir y un puntero a la
estructura FILE del fichero donde se realizará la escritura.

El prototipo correspondiente de fputs es:

int fputs(const char *buffer, FILE *archivo)

para ver su funcionamiento mostramos el siguiente ejemplo:

#include <stdio.h>
int main ( int argc, char **argv )
{
FILE *fp;
char cadena[] = "Mostrando el uso de fputs en un fichero.\n";
fp = fopen ( "fichero.txt", "r+" );
fputs( cadena, fp );
fclose ( fp );
return 0;
}

53
FWRITE
Esta función está pensada para trabajar con registros de longitud constante y forma pareja
con fread. Es capaz de escribir hacia un fichero uno o varios registros de la misma longitud
almacenados a partir de una dirección de memoria determinada. El valor de retorno es el número
de registros escritos, no el número de bytes. Los parámetros son: un puntero a la zona de memoria
de donde se obtendrán los datos a escribir, el tamaño de cada registro, el número de registros a
escribir y un puntero a la estructura FILE del fichero al que se hará la escritura.

El prototipo correspondiente de fwrite es:

size_t fwrite(void *puntero, size_t tamano, size_t cantidad, FILE *archivo);

Un ejemplo concreto del uso de fwrite con su contraparte fread y usando funciones es:

#include <stdio.h>
int main ( int argc, char **argv )
{
FILE *fp;
char cadena[] = "Mostrando el uso de fwrite en un fichero.\n";
fp = fopen ( "fichero.txt", "r+" );
fwrite( cadena, sizeof(char), sizeof(cadena), fp ); //char cadena[]... cada posición es de
tamaño 'char'
fclose ( fp );
return 0;
}

FPRINTF
La función fprintf funciona igual que printf en cuanto a parámetros, pero la salida se dirige a un
archivo en lugar de a la pantalla. El prototipo correspondiente de fprintf es:

int fprintf(FILE *archivo, const char *formato, argumento, ...);

Podemos ver un ejemplo de su uso, abrimos el documento "fichero.txt" en modo lectura/escritura y


escribimos dentro de él.

54
#include <stdio.h>
int main ( int argc, char **argv )
{
FILE *fp;
char buffer[100] = "Esto es un texto dentro del fichero.";
fp = fopen ( "fichero.txt", "r+" );
fprintf(fp, buffer);
fprintf(fp, "%s", "\nEsto es otro texto dentro del fichero.");
fclose ( fp );
return 0;
}

Una de las principales funciones de un Sistema Operativo es la administración del almacenamiento


de información, para lo cual es necesario contar con un “Sistema de Archivos”. Con este término se
hace referencia, por un lado, a los mecanismos y estructuras que el sistema operativo utiliza para
organizar la información en medios físicos tales como discos y diskettes (aspecto físico del sistema
de archivos), y por otro a la visión que es ofrecida al usuario para permitir la manipulación de la
información almacenada (una abstracción, o perspectiva lógica del sistema de archivos). Se ofrece
a continuación una descripción sintética de los aspectos lógicos del sistema de archivos de Linux.

ARCHIVOS Y DIRECTORIOS

El sistema de archivos de Linux está organizado en archivos y directorios. Un archivo es una


colección de datos que se almacena en un medio físico y a la cual se le asigna un nombre. Los
archivos, a su vez, están agrupados en conjuntos llamados directorios. Un directorio puede tener
subdirectorios, formándose así una estructura jerárquica con la forma de un árbol invertido. El
directorio inicial de esa jerarquía se denomina directorio raíz y se simboliza con una barra de división
(/).

El sistema de archivos de un sistema Linux típico está formado por los siguientes directorios bajo el
directorio raíz:

55
/bin Contiene los programas ejecutables que son parte del sistema operativo Linux. Muchos
comandos de Linux como cat, cp, ls, more y tar están ubicados en este directorio.

/boot Contienen el kernel (o núcleo) de Linux y otros archivos necesarios para el administrador de
inicio LILO, que realiza la carga inicial del sistema operativo cuando la computadora se enciende.

/dev Contienen todos los archivos de acceso a dispositivos. Linux trata cada dispositivo (terminales,
discos, impresoras, etc.) como si fuera un archivo especial.

/etc. Contiene archivos de configuración del sistema y los programas de inicialización.

/home Contiene los directorios HOME de los usuarios. El directorio HOME el directorio inicial en el
que se encuentra posicionado un usuario al ingresar al sistema, por lo que también se conoce
como directorio de logín o de conexión.

/lib Contiene los archivos de biblioteca utilizados por las aplicaciones y utilidades del sistema, así
también como las librerías pertenecientes a diferentes lenguajes de programación.

/lost+found Directorio para archivos recuperados por el proceso de reparación del sistema de
archivos, que se ejecuta luego de una caída del sistema y asegura su integridad luego de que el
equipo haya sido apagado de manera inapropiada.

/mnt Es un directorio vacío que se usa normalmente para montar dispositivos como disquetes y
particiones temporales de disco.

/proc Contiene archivos con información sobre el estado de ejecución del sistema operativo y de los
procesos.

/root Es el directorio HOME para el usuario root (administrador del sistema).

/sbin Contienen archivos ejecutables que son comandos que se usan normalmente para la
administración del sistema.

/tmp Directorio temporal que puede usar cualquier usuario como directorio transitorio.

/usr Contiene archivos de programa, de datos y de librerías asociados con las actividades de los
usuarios.

/var Contiene archivos temporales y de trabajo generados por programas del sistema. A diferencia
de /tmp, los usuarios comunes no tienen permiso para utilizar los subdirectorios que contiene
directamente, sino que deben hacerlo a través de aplicaciones y utilidades del sistema.

PERMISOS DE ARCHIVOS Y DIRECTORIOS

En cualquier sistema multiusuario, es preciso que existan métodos que impidan a un usuario no
autorizado copiar, borrar, modificar algún archivo sobre el cual no tiene permiso. En Linux las
medidas de protección se basan en que cada archivo tiene un propietario (usualmente, el que creó
el archivo). Además, los usuarios pertenecen a uno o más grupos, los cuales son asignados por el

56
Administrador dependiendo de la tarea que realiza cada usuario; cuando un usuario crea un archivo,
el mismo le pertenece también a alguno de los grupos del usuario que lo creó.

Así, un archivo en Linux le pertenece a un usuario y a un grupo, cada uno de los cuales tendrá
ciertos privilegios de acceso al archivo. Adicionalmente, es posible especificar qué derechos tendrán
los otros usuarios, es decir, aquellos que no son el propietario del archivo ni pertenecen al grupo
dueño del archivo.

En cada categoría de permisos (usuario, grupo y otros) se distinguen tres tipos de accesos: lectura
(Read), escritura (Write) y ejecución (eXecute), cuyos significados varían según se apliquen a un
archivo o a un directorio.

En el caso de los archivos, el permiso R (lectura) habilita a quién lo posea a ver el contenido del
archivo, mientras que el permiso W (escritura) le permite cambiar su contenido. El permiso X
(ejecución) se aplica a los programas y habilita su ejecución.

Para los directorios, el permiso R permite listar el contenido del mismo (es decir, “leer” el directorio,
mientras que el W permite borrar o crear nuevos archivos en su interior (es decir, modificar o
“escribir” el directorio). El permiso X da permiso de paso, es decir, la posibilidad de transformar el
directorio en cuestión en el directorio actual (ver comando cd).

En los listados de directorio, los permisos se muestran como una cadena de 9 caracteres, en donde
los primeros tres corresponden a los permisos del usuario, los siguientes tres a los del grupo y los
últimos, a los de los demás usuarios. La presencia de una letra (r, w o x) indica que el permiso está
concedido, mientras que un guión (-) indica que ese permiso está denegado.

Los permisos de un archivo o directorio pueden cambiarse desde el administrador de archivos KFM
utilizando la ventana de propiedades o utilizando el comando chmod.

57
ARCHIVOS

Todos los datos que un programa utiliza durante su ejecución se encuentran en sus variables, que
están almacenadas en la memoria RAM del computador.

La memoria RAM es un medio de almacenamiento volátil: cuando el programa termina, o cuando el


computador se apaga, todos los datos se pierden para siempre.

Para que un programa pueda guardar datos de manera permanente, es necesario utilizar un medio
de almacenamiento persistente, de los cuales el más importante es el disco duro.

Los datos en el disco duro están organizados en archivos. Un archivo es una secuencia de datos
almacenados en un medio persistente que están disponibles para ser utilizados por un programa.
Todos los archivos tienen un nombre y una ubicación dentro del sistema de archivos del sistema
operativo.

Los datos en un archivo siguen estando presentes después de que termina el programa que lo ha
creado. Un programa puede guardar sus datos en archivos para usarlos en una ejecución futura, e
incluso puede leer datos desde archivos creados por otros programas.

Un programa no puede manipular los datos de un archivo directamente. Para usar un archivo, un
programa siempre abrir el archivo y asignarlo a una variable, que llamaremos el archivo lógico.
Todas las operaciones sobre un archivo se realizan a través del archivo lógico.

Dependiendo del contenido, hay muchos tipos de archivos. Nosotros nos preocuparemos sólo de
los archivos de texto, que son los que contienen texto, y pueden ser abiertos y modificados usando
un editor de texto como el Bloc de Notas. Los archivos de texto generalmente tienen un nombre
terminado en .txt.

LECTURA DE ARCHIVOS

Para leer datos de un archivo, hay que abrirlo de la siguiente manera:

archivo = open(nombre)

nombre es un string que tiene el nombre del archivo. archivo es el archivo lógico a través del que
se manipulará el archivo.

Si el archivo no existe, ocurrirá un error de entrada y salida (IOError).

58
Es importante recordar que la variable archivo es una representación abstracta del archivo, y no los
contenidos de este.

La manera más simple de leer el contenido es hacerlo línea por línea. Para esto, basta con poner el
archivo lógico en un ciclo for:

for linea in archivo:


# hacer algo

Una vez que los datos han sido leídos del archivo, hay que cerrarlo:

archivo.close()

Por ejemplo, supongamos que tenemos el archivo himno.txt que tiene el siguiente contenido:

Puro Chile
es tu cielo azulado
puras brisas
te cruzan también.

El archivo tiene cuatro líneas. Cada línea termina con un salto de línea (\n), que indica que a
continuación comienza una línea nueva.

El siguiente programa imprime la primera letra de cada línea del himno:

archivo = open('himno.txt')
for linea in archivo:
print linea[0]
archivo.close()

El ciclo for es ejecutado cuatro veces, una por cada línea del archivo. La salida del programa es:

P
e
p
t

Otro ejemplo: el siguiente programa imprime cuántos símbolos hay en cada línea:

59
archivo = open('himno.txt')
for linea in archivo:
print len(linea)
archivo.close()

La salida es:

11
20
13
19

Note que el salto de línea (el “enter”) es considerado en la cuenta:

+---+---+---+---+---+---+---+---+---+---+---+
| P | u | r | o | | C | h | i | l | e | \n| = 11 símbolos
+---+---+---+---+---+---+---+---+---+---+---+

Para obtener el string sin el salto de línea, se puede usar el método strip, que elimina todos los
símbolos de espaciado al principio y al final del string:

>>> s = ' Hola\n'


>>> s.strip()
'Hola'

Si modificamos el programa para eliminar el salto de línea:

archivo = open('himno.txt')
for linea in archivo:
print len(linea.strip())
archivo.close()

Entonces la salida es:

10
19

60
12
18

Lo importante es comprender que los archivos son leídos línea por línea usando el ciclo for.

ESCRITURA EN ARCHIVOS

Los ejemplos anteriores suponen que el archivo por leer existe, y está listo para ser abierto y leído.
Ahora veremos cómo crear los archivos y cómo escribir datos en ellos, para que otro programa
después pueda abrirlos y leerlos.

Uno puede crear un archivo vacío abriéndolo de la siguiente manera:

archivo = open(nombre, 'w')

El segundo parámetro de la función open indica el uso que se le dará al archivo. 'w' significa
«escribir» (write en inglés).

Si el archivo señalado no existe, entonces será creado. Si ya existe, entonces será sobreescrito.
Hay que tener cuidado entonces, pues esta operación elimina los datos del archivo que existía
previamente.

Una vez abierto el archivo, uno puede escribir datos en él usando el método write:

a = open('prueba.txt', 'w')
a.write('Hola ')
a.write('mundo.')
a.close()

Una vez ejecutado este programa, el archivo prueba.txt será creado (o sobreescrito, si ya existía).
Al abrirlo en el Bloc de Notas, veremos este contenido:

Hola mundo.

Para escribir varias líneas en el archivo, es necesario agregar explícitamente los saltos de línea en
cada string que sea escrito. Por ejemplo, para crear el archivo himno.txt que usamos más arriba,
podemos hacerlo así:

a = open('himno.txt', 'w')

61
a.write('Puro Chile\n')
a.write('es tu cielo azulado\n')
a.write('puras brisas\n')
a.write('te cruzan también.\n')
a.close()

Además del modo 'w' (write), también existe el modo 'a' (append), que permite escribir datos al final
de un archivo existente. Por ejemplo, el siguiente programa abre el archivo prueba.txt que creamos
más arriba, y agrega más texto al final de él:

a = open('prueba.txt', 'a')
a.write('\n')
a.write('Chao ')
a.write('pescao.')
a.close()

Si abrimos el archivo prueba.txt en el Bloc de Notas, veremos esto:

Hola mundo.

Chao pescao.

De haber abierto el archivo en modo 'w' en vez de 'a', el contenido anterior (la frase Hola mundo) se
habría borrado.

ARCHIVOS DE VALORES CON SEPARADORES

Una manera usual de almacenar datos con estructura de tabla en un archivo es la siguiente: cada
línea del archivo representa una fila de la tabla, y los datos de una fila se ponen separados por algún
símbolo especial.

Por ejemplo, supongamos que queremos guardar en un archivo los datos de esta tabla:

Nombre Apellido Nota 1 Nota 2 Nota 3 Nota 4

Perico Los Palotes 90 75 38 65

Yayita Vinagre 39 49 58 55

62
Nombre Apellido Nota 1 Nota 2 Nota 3 Nota 4

Fulana De Tal 96 100 36 71

Si usamos el símbolo : como separador, el archivo, que llamaremos alumnos.txt, debería quedar
así:

Perico:Los Palotes:90:75:38:65
Yayita:Vinagre:39:49:58:55
Fulanita:De Tal:96:100:36:71

El formato de estos archivos se suele llamar CSV, que en inglés son las siglas de comma-separated
values (significa «valores separados por comas», aunque técnicamente el separador puede ser
cualquier símbolo). A pesar del nombre especial que reciben, los archivos CSV son archivos de
texto como cualquier otro, y se pueden tratar como tales.

Los archivos de valores con separadores son muy fáciles de leer y escribir, y por esto son muy
usados. Como ejemplo práctico, si usted desea hacer un programa que analice los datos de una
hoja de cálculo Excel, puede guardar el archivo con el formato CSV directamente en el Excel, y
luego abrirlo desde su programa escrito en Python.

Para leer los datos de un archivo de valores con separadores, debe hacerlo línea por línea, eliminar
el salto de línea usando el método strip y luego extraer los valores de la línea usando el método split.
Por ejemplo, al leer la primera línea del archivo de más arriba obtendremos el siguiente string:

'Perico:Los Palotes:90:75:38:65\n'

Para separar los seis valores, lo podemos hacer así:

>>> linea.strip().split(':')
['Perico', 'Los Palotes', '90', '75', '38', '65']

Como se trata de un archivo de texto, todos los valores son strings. Una manera de convertir los
valores a sus tipos apropiados es hacerlo uno por uno:

valores = linea.strip().split(':')
nombre = valores[0]

63
apellido = valores[1]
nota1 = int(valores[2])
nota2 = int(valores[3])
nota3 = int(valores[4])
nota4 = int(valores[5])

Una manera más breve es usar las rebanadas y la función map:

valores = linea.strip().split(':')
nombre, apellido = valores[0:2]
nota1, nota2, nota3, nota4 = map(int, valores[2:6])

O podríamos dejar las notas en una lista, en vez de usar cuatro variables diferentes:

notas = map(int, valores[2:6])

Por ejemplo, un programa para imprimir el promedio de todos los alumnos se puede escribir así:

archivo_alumnos = open('alumnos.txt')
for linea in archivo_alumnos:
valores = linea.strip().split(':')
nombre, apellido = valores[0:2]
notas = map(int, valores[2:6])
promedio = sum(notas) / 4.0
print '{0} obtuvo promedio {1}'.format(nombre, promedio)
archivo_alumnos.close()

Para escribir los datos en un archivo, hay que hacer el proceso inverso: convertir todos los datos al
tipo string, pegarlos en un único string, agregar el salto de línea al final y escribir la línea en el
archivo.

Si los datos de la línea ya están en una lista o una tupla, podemos convertirlos a string usando la
función map y pegarlos usando el método join:

alumno = ('Perico', 'Los Palotes', 90, 75, 38, 65)


linea = ':'.join(map(str, alumno)) + '\n'

64
archivo.write(linea)

Otra manera es armar el string parte por parte:

linea = '{0}:{1}:{2}:{3}:{4}:{5}\n'.format(nombre, apellido,


nota1, nota2, nota3, nota4)
archivo.write(linea)

Como siempre, usted debe preferir la manera que le parezca más simple de entender.

Un sitio web consta de muchos archivos: texto del contenido, código, hojas de estilo, contenido
multimedia, etc. Cuando estás creando un sitio web, necesitas ensamblar estos archivos en una
estructura sensible en tu computadora local, asegurarte de que puedan comunicarse entre sí y hacer
que todo su contenido se vea bien antes de que eventualmente los cargues en un servidor. El
manejo de archivos analiza algunos problemas que debes tener en cuenta, para que puedas
configurar una estructura de archivos adecuada para tu sitio web.

¿DÓNDE DEBERÍA ESTAR TU SITIO WEB EN TU COMPUTADORA?

Cuando estés trabajando en un sitio web localmente en tu computadora, debes mantener todos los
archivos relacionados en un solo directorio que refleje la estructura de archivos del sitio web
publicado en el servidor. Este directorio se puede ubicar en cualquier lugar que desees, pero debes
colocarlo en algún lugar donde lo puedas encontrar fácilmente, tal vez en tu escritorio, en tu
directorio de inicio o en la raíz de tu disco duro.

1. Elige un lugar para almacenar los proyectos de tus sitios web. Dentro del lugar elegido, crea
un nuevo directorio llamado proyectosweb (o algo similar). Aquí es donde vivirán todos los
proyectos de tus sitios web.
2. Dentro de este primer directorio, crea otro directorio para almacenar tu primer sitio web.
Llámalo pruebasitio (o algo más imaginativo).

UNA ACOTACIÓN SOBRE LA ENVOLTURA Y EL ESPACIADO

Notarás que, a lo largo de este artículo, te pedimos que nombres los directorios y archivos
completamente en minúsculas sin espacios. Esto es porque:

1. Muchas computadoras, particularmente los servidores web, distinguen entre mayúsculas y


minúsculas. Entonces, por ejemplo, si colocas una imagen en tu sitio web

65
en pruebasitio/MiImagen.jpg y luego, en un archivo diferente intentas invocar la imagen
como pruebasitio/miimagen.jpg, puede que no funcione.
2. Los navegadores, servidores web y lenguajes de programación no manejan los espacios de
manera consistente. Por ejemplo, si usas espacios en tu nombre de archivo, algunos
sistemas pueden tratar el nombre de archivo como dos nombres de archivo. Algunos
servidores reemplazarán las áreas en tus nombres de archivo con "%20" (el código de
caracteres para espacios en URI), lo cual provocará que todos tus enlaces se rompan. Es
mejor separar las palabras con guiones, en lugar de guiones bajos: mi-
archivo.html vs. mi_archivo.html.

La respuesta corta es que debes usar un guión para los nombres de tus archivos. El motor de
búsqueda de Google trata un guión como un separador de palabras, pero no considera un guión
bajo de esa manera. Por estos motivos, es mejor adquirir el hábito de escribir los nombres de los
directorios y archivos en minúsculas, sin espacios y con palabras separadas por guiones, al menos
hasta que sepas lo que estás haciendo. De esa manera, tropezarás con menos problemas en el
futuro.

¿QUÉ ESTRUCTURA DEBE TENER TU SITIO WEB?

A continuación, veamos qué estructura debería tener tu sitio de prueba. Las cosas más comunes
que tendrás en cualquier proyecto de sitio web que crees son un archivo de índice HTML y
directorios para contener imágenes, archivos de estilo y archivos de script. Crea estos ahora:

1. index.html: Este archivo generalmente tendrá el contenido de tu página de inicio, es decir, el


texto y las imágenes que las personas ven cuando visitan tu sitio por primera vez. Usando tu
editor de texto, crea un nuevo archivo llamado index.html y guárdalo dentro de tu
directorio pruebasitio.
2. Directorio images: Este directorio contendrá todas las imágenes que utilices en tu sitio. Crea
un directorio llamado images, dentro de tu directorio pruebasitio.
3. Directorio styles: Este directorio contendrá el código CSS que se utiliza para aplicar estilo al
contenido (por ejemplo, configurar el texto y los colores de fondo). Crea un directorio
llamado styles, dentro de tu directorio pruebasitio.
4. Directorio scripts: Este directorio contendrá todo el código JavaScript utilizado para agregar
funcionalidad interactiva a tu sitio (por ejemplo, botones que cargan datos cuando se hace
clic en ellos). Crea un directorio llamado scripts, dentro de tu directorio pruebasitio.

66
Nota: En las computadoras con Windows, es posible que tengas problemas para ver los nombres
de los archivos, porque de manera predeterminada, Windows tiene activada una opción
llamada Ocultar extensiones para tipos de archivos conocidos. Generalmente, la puedes desactivar
yendo al Explorador de Windows, seleccionando la opción Opciones de directorio..., desmarcando
la casilla de verificación Ocultar extensiones para tipos de archivo conocidos y luego haciendo clic
en Aceptar. Para obtener información más específica sobre tu versión de Windows, puedes buscar
en la web.

RUTAS DE ARCHIVO

Para que los archivos se comuniquen entre sí, debes proporcionar una ruta de archivo entre ellos,
básicamente una ruta, para que un archivo sepa dónde está otro. Para demostrarlo, insertaremos
un poco de HTML en nuestro archivo index.html y haremos que muestre la imagen que elegiste en
el artículo ¿Cómo se verá tu sitio web?

1. Copia la imagen que elegiste anteriormente en tu directorio images.


2. Abre tu archivo index.html e inserta el siguiente código en el archivo exactamente como se
muestra. Por ahora, no te preocupes por lo que significa todo esto; veremos las estructuras
con más detalle más adelante en la serie.

HTMLCopy to Clipboard
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Mi página de prueba</title>
</head>
<body>
<img src="" alt="Mi imagen de prueba" />
</body>
</html>

3. La línea <img src="" alt="Mi imagen de prueba"> es el código HTML que inserta una imagen
en la página. Necesitamos decirle al HTML dónde está la imagen. La imagen está dentro del
directorio images, que está en el mismo directorio que index.html. Para recorrer la estructura

67
del archivo desde index.html hasta nuestra imagen, la ruta del archivo que necesitamos
es images/nombre-archivo-imagen. Por ejemplo, nuestra imagen se llama firefox-icon.png,
por lo que la ruta del archivo es images/firefox-icon.png.
4. Inserta la ruta del archivo en tu código HTML entre las comillas dobles del código src="".
5. Guarda tu archivo HTML, luego cárgalo en tu navegador web (haz doble clic en el archivo).
¡Deberías ver tu nueva página web mostrando tu imagen!

Algunas reglas generales para las rutas de archivo:

1. Para vincular a un archivo destino en el mismo directorio que el archivo HTML de invocación,
simplemente usa el nombre del archivo, p. ej. mi-imagen.jpg.
2. Para hacer referencia a un archivo en un subdirectorio, escribe el nombre del directorio
delante de la ruta, más una barra inclinada, p. ej. subdirectorio/mi-imagen.jpg.
3. Para vincular a un archivo destino en el directorio arriba del archivo HTML que lo invoca,
escribe dos puntos. Por ejemplo, si index.html estuviera dentro de un subdirectorio
de pruebasitio y mi-imagen.jpg estuviera dentro de pruebasitio, puedes hacer referencia
a mi-imagen.jpg desde index.html utilizando ../mi-imagen.jpg.
4. Los puedes combinar tanto como desees, por ejemplo, ../subdirectorio/otro-subdirectorio/mi-
imagen.jpg.

Nota: El sistema de archivos de Windows tiende a utilizar barras invertidas, no barras diagonales,
p. ej. C:\windows. Esto no importa en HTML, incluso si estás desarrollando tu sitio web en Windows,
debes usar barras diagonales en tu código.

68
Así como hemos revisado la salida y entrada por pantalla y teclado respectivamente, veremos ahora
la entrada y/o salida de datos utilizando ficheros, lo cual será imprescindible para un gran número
de aplicaciones que deseemos desarrollar.

PROCESAMIENTO DE TEXTO

Hasta ahora, hemos visto cómo los tipos de datos básicos (strings, enteros, reales, booleanos) y las
estructuras de datos permiten representar y manipular información compleja y abstracta en un
programa. Sin embargo, en muchos casos la información no suele estar disponible ya organizada
en estructuras de datos convenientes de usar, sino en documentos de texto.

Por ejemplo, las páginas webs son archivos de puro texto, que describen la estructura de un
documento en un lenguaje llamado HTML. Usted puede ver el texto de una página web buscando
una instrucción «Ver código fuente» (o algo parecido) en el navegador. A partir de este texto, el
navegador extrae la información necesaria para reconstruir la página que finalmente usted ve.

Un texto siempre es un string, que puede ser tan largo y complejo como se desee. El procesamiento
de texto consiste en manipular strings, ya sea para extraer información del string, para convertir un
texto en otro, o para codificar información en un string. En Python, el tipo str provee muchos métodos
convenientes para hacer procesamiento de texto, además de las operaciones más simples que ya
aprendimos (como s + t, s[i] y s in t).

SALTOS DE LÍNEA

Un string puede contener caracteres de salto de línea, que tienen el efecto equivalente al de
presionar la tecla Enter. El caracter de salto de línea se representa con \n:

>>> a = 'piano\nviolin\noboe'
>>> print a
piano
violin
oboe

Los saltos de línea sólo son visibles al imprimir el string mediante la sentencia print. Si uno quiere
ver el valor del string en la consola, el salto de línea aparecerá representado como \n:

>>> a
'piano\nviolin\noboe'

69
>>> print a
piano
violin
oboe

Aunque dentro del string se representa como una secuencia de dos símbolos, el salto de línea es
un único caracter:

>>> len('a\nb')
3

En general, hay varios caracteres especiales que se representan comenzando con una barra
invertida (\) seguida de una letra. Experimente, y determine qué significan los caracteres
especiales \t y \b:

print 'abcde\tefg\thi\tjklm'
print 'abcde\befg\bhi\bjklm'

Para incluir una barra invertida dentro de un string, hay que hacerlo con \\:

>>> print 'c:\\>'


c:\>
>>> print '\\o/ o\n | /|\\\n/ \\ / \\'
\o/ o
| /|\
/\/\

REEMPLAZAR SECCIONES DEL STRING

El método s.replace(antes, despues) busca en el string s todas las apariciones del texto antes y las
reemplaza por despues:

>>> 'La mar astaba sarana'.replace('a', 'e')


'Le mer estebe serene'
>>> 'La mar astaba sarana'.replace('a', 'i')
'Li mir istibi sirini'
>>> 'La mar astaba sarana'.replace('a', 'o')

70
'Lo mor ostobo sorono'

Hay que tener siempre muy claro que esta operación no modifica el string, sino que retorna uno
nuevo:

>>> orden = 'Quiero arroz con pollo'


>>> orden.replace('arroz', 'pure').replace('pollo', 'huevo')
'Quiero pure con huevo'
>>> orden
'Quiero arroz con pollo'

SEPARAR Y JUNTAR STRINGS

s.split() separa el strings en varios strings, usando los espacios en blanco como separador. El valor
retornado es una lista de strings:

>>> oracion = 'El veloz murcielago hindu comia feliz cardillo y kiwi'
>>> oracion.split()
['El', 'veloz', 'murcielago', 'hindu', 'comia', 'feliz', 'cardillo', 'y', 'kiwi']

Además, es posible pasar un parámetro al método split que indica cuál será el separador a usar (en
vez de los espacios en blanco):

>>> s = 'Ana lavaba las sabanas'


>>> s.split()
['Ana', 'lavaba', 'las', 'sabanas']
>>> s.split('a')
['An', ' l', 'v', 'b', ' l', 's s', 'b', 'n', 's']
>>> s.split('l')
['Ana ', 'avaba ', 'as sabanas']
>>> s.split('aba')
['Ana lav', ' las s', 'nas']

Esto es muy útil para pedir al usuario que ingrese datos en un programa de una manera más
conveniente, y no uno por uno. Por ejemplo, antes hacíamos programas que funcionaban así:

Ingrese a: 2.3

71
Ingrese b: 1.9
Ingrese c: 2.3
El triángulo es isósceles.

Ahora podemos hacerlos así:

Ingrese lados del triángulo: 2.3 1.9 2.3


El triángulo es isósceles.

En este caso, el código del programa podría ser:

entrada = raw_input('Ingrese lados del triangulo: ')


lados = entrada.split()
a = int(lados[0])
b = int(lados[1])
c = int(lados[2])
print 'El triangulo es', tipo_triangulo(a, b, c)

O usando la función map, más simplemente:

entrada = raw_input('Ingrese lados del triangulo: ')


a, b, c = map(int, entrada.split())
print 'El triangulo es', tipo_triangulo(a, b, c)

s.join(lista_de_strings) une todos los strings de la lista, usando al string s como «pegamento»:

>>> valores = map(str, range(10))


>>> pegamento = ' '
>>> pegamento.join(valores)
'0 1 2 3 4 5 6 7 8 9'
>>> ''.join(valores)
'0123456789'
>>> ','.join(valores)
'0,1,2,3,4,5,6,7,8,9'
>>> ' --> '.join(valores)
'0 --> 1 --> 2 --> 3 --> 4 --> 5 --> 6 --> 7 --> 8 --> 9'

72
MAYÚSCULAS Y MINÚSCULAS

s.isupper() y s.islower() indican si el string está, respectivamente, en mayúsculas o minúsculas:

>>> s = 'hola'
>>> t = 'Hola'
>>> u = 'HOLA'
>>> s.isupper(), s.islower()
(False, True)
>>> t.isupper(), t.islower()
(False, False)
>>> u.isupper(), u.islower()
(True, False)

s.upper() y s.lower() entregan el string s convertido, respectivamente, a mayúsculas y minúsculas:

>>> t
'Hola'
>>> t.upper()
'HOLA'
>>> t.lower()
'hola'

s.swapcase() cambia las minúsculas a mayúsculas, respectivamente, a mayúsculas y minúsculas:

>>> t.swapcase()
'hOLA'

Lamentablemente, ninguno de estos métodos funciona con acentos y eñes:

>>> print 'ñandú'.upper()


ñANDú

REVISAR CONTENIDOS DEL STRING

s.startswith(t) y s.endswith(t) indican si el string s comienza y termina, respectivamente, con el


string t:

73
>>> objeto = 'paraguas'
>>> objeto.startswith('para')
True
>>> objeto.endswith('aguas')
True
>>> objeto.endswith('x')
False
>>> objeto.endswith('guaguas')
False

Nuestro conocido operador in indica si un string está contenido dentro de otro:

>>> 'pollo' in 'repollos'


True
>>> 'pollo' in 'gallinero'
False

ALINEACIÓN DE STRINGS

Los métodos s.ljust(n), s.rjust(n) y s.center(n) rellenan el string con espacios para que su largo sea
igual a n, de modo que el contenido quede alineado, respectivamente, a la izquierda, a la derecha
y al centro:

>>> contenido.ljust(20)
'hola '
>>> contenido.center(20)
' hola '
>>> contenido.rjust(20)
' hola'

Estos métodos son útiles para imprimir tablas bien alineadas:

datos = [
('Pepito', (1991, 12, 5), 'Osorno', '***'),
('Yayita', (1990, 1, 31), 'Arica', '*'),
('Fulanito', (1992, 10, 29), 'Porvenir', '****'),

74
]
for n, (a, m, d), c, e in datos:
print n.ljust(10),
print str(a).rjust(4), str(m).rjust(2), str(d).rjust(2),
print c.ljust(10), e.center(5)

Este programa imprime lo siguiente:

Pepito 1991 12 5 Osorno ***


Yayita 1990 1 31 Arica *
Fulanito 1992 10 29 Porvenir ****

INTERPOLACIÓN DE STRINGS

El método format permite usar un string como una plantilla que se puede completar con distintos
valores dependiendo de la situación.

Las posiciones en que se deben rellenar los valores se indican dentro del string usando un número
entre paréntesis de llaves:

>>> s = 'Soy {0} y vivo en {1}'

Estas posiciones se llaman campos. En el ejemplo, el string s tiene dos campos, numerados del
cero al uno.

Para llenar los campos, hay que llamar al método format pasándole los valores como parámetros:

>>> s.format('Perico', 'Valparaiso')


'Soy Perico y vivo en Valparaiso'
>>> s.format('Erika', 'Berlin')
'Soy Erika y vivo en Berlin'
>>> s.format('Wang Dawei', 'Beijing')
'Soy Wang Dawei y vivo en Beijing'

El número indica en qué posición va el parámetro que está asociado al campo:

>>> '{1}{0}{2}{0}'.format('a', 'v', 'c')


'vaca'

75
>>> '{0} y {1}'.format('carne', 'huevos')
'carne y huevos'
>>> '{1} y {0}'.format('carne', 'huevos')
'huevos y carne'

Otra opción es referirse a los campos con un nombre. En este caso, hay que llamar al
método format diciendo explícitamente el nombre del parámetro para asociarlo al valor:

>>> s = '{nombre} estudia en la {universidad}'


>>> s.format(nombre='Perico', universidad='UANM')
'Perico estudia en la UANM'
>>> s.format(nombre='Fulana', universidad='UANM')
'Fulana estudia en la UANM'
>>> s.format(universidad='UANM', nombre='Yayita')
'Yayita estudia en la UANM'

RESOLUCIÓN DE PROBLEMAS DE ACCESO A ARCHIVOS


A menudo, cuando los usuarios tienen problemas, recurren a un administrador del sistema en busca
de ayuda, por ejemplo, si no pueden acceder a un programa, un archivo o un directorio al que antes
sí podían.

Siempre que tenga un problema de esta clase, investigue una de las tres siguientes posibilidades:

• Puede que la ruta de búsqueda del usuario haya cambiado o que los directorios en la ruta
de búsqueda no se encuentren en el orden correcto.

• Puede que el archivo o el directorio no tengan la propiedad o los permisos adecuados.

• Puede que la configuración de un sistema al que se accede mediante la red haya


cambiado.

Este capítulo describe brevemente cómo reconocer los problemas de cada una de estas tres áreas
y se sugieren posibles soluciones.

RESOLUCIÓN DE PROBLEMAS CON RUTAS DE BÚSQUEDA ( COMMAND NOT FOUND)


El mensaje de error Command not found indica una de las siguientes situaciones:

76
• El comando no está disponible en el sistema.

• El directorio del comando no está en la ruta de búsqueda.

Para solucionar un problema de la ruta de búsqueda, necesita saber el nombre de ruta del directorio
donde el comando se encuentra almacenado.

Si se encuentra la versión incorrecta del comando, hay un directorio que tiene un comando con el
mismo nombre en la ruta de búsqueda. En este caso, puede que el directorio correspondiente se
encuentre más adelante en la ruta de búsqueda o que directamente no se encuentre en ninguna
parte. Puede mostrar la ruta de búsqueda actual con el comando echo $PATH. Utilice el
comando type para determinar si está ejecutando la versión incorrecta del comando. Por ejemplo:

$ type acroread
acroread is /usr/bin/acroread

¿CÓMO DIAGNOSTICAR Y CORREGIR PROBLEMAS DE RUTA DE BÚSQUEDA?

• Visualice la ruta de búsqueda actual a fin de verificar que el directorio para el comando
no esté en la ruta ni esté mal escrito.

$ echo $PATH

• Compruebe lo siguiente:
o ¿Es correcta la ruta de búsqueda?

o ¿Está enumerada la ruta de búsqueda antes que otras rutas de búsqueda


donde se encuentra otra versión del comando?

o ¿Se encuentra el comando en una de las rutas de búsqueda?

Si es necesario corregir la ruta, vaya al paso 3. De lo contrario, vaya al paso 4.

• Agregue la ruta al archivo correspondiente, como se muestra en la siguiente tabla.

Shell Archivo Sintaxis Notas

77
bash $HOME/.profile $ PATH=$HOME/bin:/sbin:/usr/local Los nombres de ruta se separan
y ksh93 /bin ... con dos puntos.

$ export PATH

• Active la ruta nueva como se muestra a continuación:

Shell Ubicación de la ruta Comando para activar la ruta

bash y ksh93 .profile . $HOME/.profile

.login hostname$ source $HOME/.login

• Verifique la ruta nueva.

$ which command

Ejemplo 3-6 Diagnóstico y corrección de problemas de ruta de búsqueda

En este ejemplo, se muestra que el ejecutable mytool no está en ninguno de los directorios de la
ruta de búsqueda con el comando type.

$ mytool
-bash: mytool: command not found
$ type mytool
-bash: type: mytool: not found
$ echo $PATH
/usr/bin:
$ vi $HOME/.profile
(Add appropriate command directory to the search path)
$ . $HOME/.profile
$ mytool

Si no puede encontrar un comando, consulte la página del comando man para la ruta de directorio.

78
CAMBIO DE PROPIEDADES DE GRUPO Y ARCHIVO
Con frecuencia, las propiedades de los archivos y los directorios cambian porque un superusuario
edita los archivos. Al crear directorios principales para los usuarios nuevos, asegúrese de asignarles
la propiedad del archivo punto (.) en el directorio principal. Si los usuarios no tienen la propiedad de
“.”, no pueden crear archivos en su directorio principal.

También pueden surgir problemas de acceso cuando cambia la propiedad del grupo o cuando un
grupo del que un usuario es miembro se suprime de la base de datos /etc/group.

Para obtener información sobre cómo cambiar los permisos o la propiedad de un archivo al que no
puede acceder.

RESOLUCIÓN DE PROBLEMAS DE ACCESO A ARCHIVOS


Si los usuarios no pueden acceder a archivos o directorios a los que antes podían acceder, es
probable que la propiedad o los permisos de los archivos o directorios se hayan modificado.

DETECCIÓN DE PROBLEMAS CON EL ACCESO DE RED


Si los usuarios tienen problemas con el comando de copia remota rcp para copiar archivos en la
red, puede que los directorios y los archivos del sistema remoto tengan acceso restringido mediante
la definición de permisos. También se pueden ocasionar problemas si el sistema remoto y el sistema
local no están configurados para permitir el acceso.

CREACIÓN DE UNIDADES

Comentamos en el tema 10 que en muchos lenguajes de programación podemos manejar una serie
de bibliotecas externas (en inglés, library) de funciones y procedimientos, que nos permitían ampliar
el lenguaje base.

En Turbo Pascal, estas bibliotecas reciben el nombre de "unidades" (unit), y existen a partir de la
versión 5. También existen en otras versiones de Pascal recientes, como Free Pascal.

En su momento, empleamos la unidad CRT, que nos daba una serie de facilidades para manejar la
pantalla en modo texto, el teclado y la generación de sonidos sencillos.

Iremos viendo otras unidades estándar cuando accedamos a la pantalla en modo gráfico, a los
servicios del sistema operativo, etc. Pero hoy vamos a ver cómo podemos crear las nuestras
propias.

79
¿Para qué? Nos podría bastar con teclear en un programa todas las funciones que nos interesen.
Si creamos otro programa que las necesite, pues las copiamos también en ese y ya está, ¿no?

¡ NO ! Las unidades nos ayudan a conseguir dos cosas:

La primera es que los programas sean más modulares. Que podamos dejar aparte las funciones
que se encargan de batallar con el teclado, por ejemplo, y en nuestro programa principal sólo esté
lo que realmente tenga este programa que lo diferencie de los otros. Esto facilita la legibilidad y con
ello las posibles correcciones o ampliaciones.

La segunda ventaja es que no tenemos distintas versiones de los mismos procedimientos o


funciones. Esto ayuda a ganar espacio en el disco duro, pero eso es lo menos importante. Lo
realmente interesante es que, si se nos ocurre una mejora para un procedimiento, todos los
programas que lo usen se van a beneficiar de él automáticamente. Me explico: imaginemos que
estamos haciendo un programa de rotación de objetos en tres dimensiones. Creamos nuestra
biblioteca de funciones, y la aprovechamos para todos los proyectos que vayamos a hacer en tres
dimensiones. No solo evitamos reescribir en cada programa el procedimento RotaPunto, p.ej.., que
ahora se tomará de nuestra unidad "MiGraf3D", sino que, si descubrimos una forma más rápida de
rotarlos, todos los programas que utilicen el procedimiento RotaPunto se verán beneficiados sólo
con recompilarlos.

Pero vamos a lo práctico...Una "unit" tiene dos partes: una pública, que es aquella a la que podremos
acceder, y una privada, que es el desarrollo detallado de esa parte pública, y a esta parte no se
puede acceder desde otros programas. La parte pública se denota con la palabra "interface", y
la privada con "implementation".

Debajo de interface basta indicar los nombres de los procedimientos que queremos "exportar", así
como las variables, si nos interesase crear alguna. Debajo de implementation escribimos realmente
estos procedimientos o funciones, tal como haríamos en un programa normal.

Veamos un ejemplo para que se entienda mejor.

Nota: este ejemplo NO SE PUEDE EJECUTAR. Recordemos que una Unit es algo auxiliar, una
biblioteca de funciones y procedimientos que nosotros utilizaremos DESDE OTROS PROGRAMAS.
Después de este ejemplo de Unit incluyo un ejemplo de programa cortito que la emplee.

{--------------------------}

80
{ Ejemplo en Pascal: }

{ }

{ Unidad que "mejora" }

{ la CRT }

{ MICRT1.PAS }

{ }

{ Este fuente procede de }

{ CUPAS, curso de Pascal }

{ por Nacho Cabanes }

{ }

{ Comprobado con: }

{ - Free Pascal 2.2.0w }

{ - Turbo Pascal 7.0 }

{ - Tmt Pascal Lt 1.20 }

{--------------------------}

unit miCrt1;

interface { Parte "pública", que se exporta }

procedure AtXY( X, Y: byte ; texto: string );

{ Escribe un texto en ciertas coordenadas }

implementation { Parte "privada", detallada }

uses crt; { Usa a su vez la unidad CRT }

procedure AtXY( X, Y: byte ; texto: string );

81
begin

gotoXY( X, Y); { Va a la posición adecuada }

write( texto );

end;

end. { Final de la unidad }

Este ejemplo declara un procedimiento "AtXY" que hace un GotoXY y un Write en un solo paso.

Un programa que lo emplease podría ser simplemente:

{--------------------------}

{ Ejemplo en Pascal: }

{ }

{ Programa que usa la }

{ unit "MICRT1" }

{ PMICRT1.PAS }

{ }

{ Este fuente procede de }

{ CUPAS, curso de Pascal }

{ por Nacho Cabanes }

{ }

{ Comprobado con: }

{ - Free Pascal 2.2.0w }

{ - Turbo Pascal 7.0 }

{ - Tmt Pascal Lt 1.20 }

{--------------------------}

program PruebaDeMiCrt1;

82
uses miCrt1;

begin

AtXY( 7, 5, 'Texto en la posición 7,5.' );

end.

Este programa no necesita llamar a la unidad CRT original, sino que nuestra unidad ya lo hace por
Ahora vamos a mejorar ligeramente nuestra unidad, añadiéndole un procedimiento “pausa”:

{--------------------------}

{ Ejemplo en Pascal: }

{ }

{ Unidad que mejora la }

{ CRT (segunda versión) }

{ MICRT2.PAS }

{ }

{ Este fuente procede de }

{ CUPAS, curso de Pascal }

{ por Nacho Cabanes }

{ }

{ Comprobado con: }

{ - Free Pascal 2.2.0w }

{ - Turbo Pascal 7.0 }

{ - Tmt Pascal Lt 1.20 }

{--------------------------}

unit miCrt2; { Unidad que "mejora más" la CRT }

{-------------------}

83
interface { Parte "pública", que se exporta }

procedure AtXY( X, Y: byte ; texto: string );

procedure Pausa;

{-------------------}

implementation { Parte "privada", detallada }

uses crt; { Usa a su vez la unidad CRT }

var tecla: char; { variable privada: el usuario no

puede utilizarla }

procedure AtXY( X, Y: byte ; texto: string );

begin

gotoXY( X, Y); { Va a la posición adecuada }

write( texto );

end;

procedure Pausa; { Pausa, llamando a ReadKey }

begin

tecla := ReadKey; { El valor de "tecla" se pierde }

end;

{-------------------}

end. { Final de la unidad }

Un programa que usase esta unidad, junto con la CTR original podría ser:

{--------------------------}

{ Ejemplo en Pascal: }

{ }

{ Prueba de la unidad }

84
{ MICRT2 }

{ PMICRT2.PAS }

{ }

{ Este fuente procede de }

{ CUPAS, curso de Pascal }

{ por Nacho Cabanes }

{ }

{ Comprobado con: }

{ - Free Pascal 2.2.0w }

{ - Turbo Pascal 7.0 }

{ - Tmt Pascal Lt 1.20 }

{--------------------------}

program PruebaDeMiCrt2;

uses crt, miCrt2;

begin

ClrScr; { De Crt }

atXY( 7, 5, 'Texto en la posición 7,5.' ); { de miCrt2 }

pausa; { de miCrt2 }

end.

Finalmente, hay que destacar que las unidades pueden contener más cosas además de funciones
y procedimientos: pueden tener un "trozo de programa", su código de inicialización, como por
ejemplo:

{--------------------------}

{ Ejemplo en Pascal: }

{ }

85
{ Unidad que mejora la }

{ CRT (tercera versión) }

{ MICRT3.PAS }

{ }

{ Este fuente procede de }

{ CUPAS, curso de Pascal }

{ por Nacho Cabanes }

{ }

{ Comprobado con: }

{ - Free Pascal 2.2.0w }

{ - Turbo Pascal 7.0 }

{ - Tmt Pascal Lt 1.20 }

{--------------------------}

unit miCrt3; { Unidad que "mejora más" la CRT }

{-------------------}

interface { Parte "pública", que se exporta }

var EraMono: boolean; { Variable pública, el usuario puede

acceder a ella }

procedure AtXY( X, Y: byte ; texto: string );

procedure Pausa;

{-------------------}

implementation { Parte "privada", detallada }

uses crt; { Usa a su vez la unidad CRT }

var tecla: char; { variable privada: el usuario no

86
puede utilizarla }

procedure AtXY( X, Y: byte ; texto: string );

begin

gotoXY( X, Y); { Va a la posición adecuada }

write( texto );

end;

procedure Pausa; { Pausa, llamando a ReadKey }

begin

tecla := ReadKey; { El valor de "tecla" se pierde }

end;

{-------------------} { Aquí va la inicialización }

begin

if lastmode = 7 { Si el modo de pantalla era monocromo }

then EraMono := true { EraMono será verdadero }

else EraMono := false; { si no => falso }

end. { Final de la unidad }

y el programa podría usar la variable EraMono sin declararla:

{--------------------------}

{ Ejemplo en Pascal: }

{ }

{ Prueba de la unidad }

{ MICRT3 }

{ PMICRT3.PAS }

{ }

87
{ Este fuente procede de }

{ CUPAS, curso de Pascal }

{ por Nacho Cabanes }

{ }

{ Comprobado con: }

{ - Free Pascal 2.2.0w }

{ - Turbo Pascal 7.0 }

{ - Tmt Pascal Lt 1.20 }

{--------------------------}

program PruebaDeMiCrt3;

uses crt, miCrt3;

begin

ClrScr; { De Crt }

atXY( 7, 5, 'Texto en la posición 7,5.' ); { de miCrt3 }

if not EraMono then

atXY ( 10, 10, 'Modo de color ' );

pausa; { de miCrt3 }

end.

Se podría hablar mucho más sobre las unidades, pero intentaré ser breve:

Al compilar una unidad se crea un fichero con extensión .TPU (.PPU para Free Pascal), al que se
puede acceder desde nuestros programas con dos condiciones: que empleemos la misma versión
de compilador (el formato de estos ficheros variaba en cada versión de Turbo Pascal, y quizá
también entre versiones de Free Pascal), y que sepamos cómo es la parte pública (interface).

Nota: Por eso mucha gente distribuía sus bibliotecas de rutinas Pascal en forma de TPU: se podía
usar las facilidades que nos daban (si teníamos la misma versión de Pascal), pero como no teníamos
disponible la fuente, no podíamos modificarlo ni redistribuirlo con nuestro nombre, por ejemplo.

88
Hoy en día, se tiende más a ceder todo el código fuente, y pedir a los usuarios que conserven el
copyright y/o envíen al autor las mejoras que propongan.

En Turbo Pascal 7 para MsDos, cada unidad tiene su propio segmento de código (esto va para
quien conozca la estructura de la memoria en los PC), así que cada unidad puede almacenar hasta
64k de procedimientos o funciones. Los datos son comunes a todas las unidades, con la limitación
64k en total (un segmento) para todos los datos (estáticos) de todo el programa.

Si queremos almacenar datos de más de 64k en el programa, tenga una o más unidades,
deberemos emplear variables dinámicas, distintas en su manejo de las que hemos visto hasta ahora
(estáticas)

SUBPROGRAMAS Y BLOQUES COMPILADOS INDEPENDIENTEMENTE

Subprogramación es la forma más básica de organizar el código de los programas informáticos, en


la mayoría de los lenguajes de programación implementada por medio de las funciones. Vídeo de
una clase completa con ejemplos en Javascript. La subprogramación es uno de los temas más
básicos y fundamentales para poder hacer un código entendible y bien estructurado, algo que
encontramos en todos los lenguajes de programación actuales.

En cualquier subprograma podemos distinguir:

La cabecera, compuesta por el nombre del subprograma, los parámetros y el tipo de valor de
retorno. El cuerpo, compuesto por las declaraciones, las instrucciones y el manejo de excepciones.

¿QUÉ ES SUBPROGRAMACIÓN?

La subprogramación es fundamental en cualquier lenguaje de programación, aunque no existe


desde siempre. Al principio los lenguajes no facilitaban la creación de subprogramas y todo el código
se escribía en una secuencia interminable de líneas con sentencias. Solo con la programación
estructurada aparecieron las primeras herramientas para crear subprogramas.

En definitiva, es una manera elemental de crear y mantener el código de los programas, que nos
permite dividir los problemas en partes más pequeñas, más fáciles de implementar. Sirven por tanto
para organizar nuestro código, pero nos ofrecen diversas otras ventajas.

Los subprogramas se implementan por medio de lo que conocemos como funciones o


procedimientos. No son más que una lista de sentencias que se escriben para resolver problemas,

89
con algoritmos que pueden operar de manera independiente. Esas piezas de código se pueden
invocar desde diversos sitios de un programa, las veces que se desee, o se necesite.

Por ejemplo, si tenemos una aplicación de gestión empresarial, podrías tener un programa que te
resuelva todo el tema de facturación. Sin embargo, ese objetivo puede ser lo suficientemente grande
y complejo para crear varios subprogramas. Por ejemplo, uno para crear facturas, otro para borrarlas
otro para enviarlas por email al cliente, y así puedes tener tantos subprogramas como necesites,
abonar facturas, marcarlas como pagadas, crear clientes, etc. Incluso, puede haber subprogramas
que llaman a otros subprogramas, quizás al crear la factura necesitas invocar el subprograma que
crea un cliente.

Esa estructura de funciones y funciones que llaman a otras funciones (aquí cuando me refiero a
funciones no es más que un sinónimo de subprograma), es la base del primer modo de jerarquizar
que apareció en los lenguajes de programación, que nos ayuda no solo a resolver un problema
complejo, sino que nos permite entenderlo mejor y también facilita el mantenimiento del código, una
vez el programa ya ha sido creado. Pero, además, la subprogramación facilita muchas otras
necesidades de un buen programa, como la de no repetirse uno mismo y reutilizar el código que se
ha escrito en el mayor número de oportunidades posible. En el vídeo que verás más abajo nos
explican muy bien la necesidad de las funciones y cómo y por qué sirven para reutilizar el código.

¿CÓMO SE IMPLEMENTAN LOS SUBPROGRAMAS O FUNCIONES?

Una vez entendido el concepto de subprograma, y sabiendo que en muchos lenguajes se


implementa por medio de las funciones, en esta clase de programación se ahondó en el modo de
crearlas en el lenguaje Javascript. Durante la clase se explicaron los modos de crear subprogramas,
es decir, la declaración de funciones. Nos referimos a las cosas básicas que todo programador debe
conocer, como la definición de funciones, ya en código Javascript. Se explicó además todo lo
relacionado con la subprogramación, como paso de parámetros, valores de devolución, etc. Sobre
todo, ello, realizamos varios ejemplos de funciones para que los estudiantes sean capaces de
implementar ese conocimiento y ponerlo en marcha en líneas de código. También se muestra cómo
se invocan las funciones en un código, por medio del nombre de la función y se hizo mucho hincapié
en mostrar como un programa mejora en muchos sentidos cuando se realizan funciones para
implementar aquellas tareas básicas.

API DE JAVASCRIPT

90
En el último bloque de esta clase se dio a conocer el API de Javascript, de una manera introductoria.
Se explicó que cualquier lenguaje ofrece un conjunto de funciones ya listas para realizar tareas
básicas, como entrada y salida de datos, trabajo con fechas, estructuras de datos como arrays,
trabajo con cadenas, matemáticas, etc. Javascript es un lenguaje con una extensísima cantidad de
funciones, que no solo nos sirven para realizar programación básica, sino que nos permite además
controlar miles de aspectos del navegador, como la ventana, el historial de navegación, el
almacenamiento local y un largo etc.

FUNCIONES

Las funciones son muy similares a los procedimientos con la diferencia que éstas siempre
devolverán un valor. Su estructura es la siguiente:

CREATE [OR REPLACE] FUNCTION NombreFuncion [(parámetros)] RETURN tipo

IS [parte declarativa]

BEGIN

instrucciones

RETURN <valor o expresión>;

[EXCEPTION excepciones]

END;

La cláusula RETURN de la cabecera nos especifica el tipo de valor que nos va a devolver la función.

PARÁMETROS

Todos los subprogramas utilizan parámetros para pasar y recibir información.

Dentro de los parámetros podemos distinguir dos tipos:

1. Parámetros actuales: son variables indicadas en la llamada a un subprograma.


2. Parámetros formales: son variables declaradas en la especificación del subprograma.

Además, podemos hacer el paso de parámetros de un tipo a otro. Generalmente si los tipos son
compatibles PL/SQL lo hace automáticamente. En cualquier caso, podemos hacerlo de forma
manual utilizando las siguientes notaciones:

91
• Posicional: el compilador asocia los parámetros actuales a los formales, basándose en
suposición.
• Nominal: el símbolo => después del parámetro actual y antes del nombre del formal, indica
al compilador correspondencia.
• Mixta: nos permite usar las dos notaciones anteriores.

Para que esto quede más claro pasamos a escribir un ejemplo de paso de parámetros y conversión
de tipos.

Tenemos la especificación de un procedimiento como esta:

PROCEDURE departamento(

n_departamento INTEGER,

localidad VARCHAR2

IS...

Desde el siguiente bloque se podrán realizar las llamadas indicadas:

DECLARE

num_departamento INTEGER;

aula VARCHAR(30)

BEGIN

...

- - posicional departamento(num_departamento, aula);

- - nominal departamento(num_departamento => n_departamento, aula =>localidad);

END;

Esto nos pasaría los parámetros num_departamento al mismo tipo que n_departamento y localidad
al mismo tipo que aula.

Los parámetros que soporta PL/SQL pueden ser de entrada, salida o entrada/salida

• IN.- Nos permite pasar valores a un subprograma. Dentro del subprograma, el parámetro
actuá como una constante. Puede ser una variable, constante, literal o expresión.

92
• OUT.- Permite devolver valores al bloque que llamó al subprograma. Dentro del
subprograma, el parámetro actúa como una variable no inicializada. Solo puede ser una
variable.
• IN OUT.- Permite pasar un valor inicial y devolver un valor actualizado. Dentro del
subprograma, el parámetro actuá como variable inicializada. Puede intervenir otras
expresiones. El valor actual debe ser una variable. El formato genérico es el siguiente:

<nombrevariable> [IN | OUT | IN OUT] <tipodato>

[ { := | DEFAULT} <valor>]

Además, es importante recordar que al especificar parámetros debemos indicar el tipo, pero no el
tamaño.

CREACIÓN, MODIFICACIÓN Y BORRADO DE SUBPROGRAMAS

Cuando creamos subprogramas con SQL * PLUS utilizando los comandos CREATE, Oracle
automáticamente compila el código fuente, genera el código objeto y los guarda en el diccionario de
datos, quedando disponibles para su utilización. Para volver a compilar un subprograma
almacenado utilizaremos la orden ALTER en vez del CREATE y su formato es el siguiente:

ALTER {PROCEDURE | FUNCITON} nombresubprograma COMPILE;

Para ver el código de un subprograma almacenado podemos ejecutar una sentencia como esta;

select LINE, SUBSTR(TEXT,1,60) from USER_SOURCE where name = 'nombresubprograma';

Para borrar un subprograma almacenado utilizaremos la orden DROP de la siguiente forma:

DROP {PROCEDURE | FUNCTION} nombresubprograma;

Nota: PL/SQL implementa la recursividad en los subprogramas, esto quiere decir, que un programa
puede llamarse a sí mismo.

COMPILADOR E INTÉRPRETE

A la hora de elegir un lenguaje de programación, se debe prestar especial atención a dos cosas: por
una parte, el lenguaje debe contar con todos los componentes básicos necesarios para el proyecto
de software que se quiera desarrollar. Por la otra, tiene que permitir programar e implementar este
proyecto de la manera más sencilla posible. La buena legibilidad y simplicidad del código fuente son

93
fundamentales para garantizar lo segundo, porque estas características no solo facilitan el
aprendizaje del lenguaje de programación, sino también, obviamente, su posterior utilización en el
día a día.

En primer lugar, para que el ordenador o el procesador puedan comprender las instrucciones que
contiene un programa desarrollado previamente, el código fuente escrito en los lenguajes de
programación actuales debe convertirse a un formato legible por máquina. De este procedimiento,
dependiendo del lenguaje de programación, se encarga un compilador o un intérprete. ¿Qué son
exactamente estos dos programas? Y ¿en qué se diferencian?

¿QUÉ ES UN INTÉRPRETE?

Un intérprete es un programa informático que procesa el código fuente de un proyecto de software


durante su tiempo de ejecución, es decir, mientras el software se está ejecutando, y actúa como una
interfaz entre ese proyecto y el procesador. Un intérprete siempre procesa el código línea por línea,
de modo que lee, analiza y prepara cada secuencia de forma consecutiva para el procesador. Este
principio también se aplica a las secuencias recurrentes, que se ejecutan de nuevo cada vez que
vuelven a aparecer en el código. Para procesar el código fuente del software, el intérprete recurre a
sus propias bibliotecas internas: en cuanto una línea de código fuente se ha traducido a los
correspondientes comandos legibles por máquina, esta se envía directamente al procesador.

El proceso de conversión no finaliza hasta que se ha interpretado todo el código. Solo se interrumpe
prematuramente si se produce un fallo durante el procesamiento, lo que simplifica mucho la
resolución de los errores, ya que la línea de código problemática se detecta inmediatamente
después de ocurrir el fallo.

¿QUÉ ES UN COMPILADOR?

Un compilador es un programa informático que traduce todo el código fuente de un proyecto de


software a código máquina antes de ejecutarlo. Solo entonces el procesador ejecuta el software,
obteniendo todas las instrucciones en código máquina antes de comenzar. De esta manera, el
procesador cuenta con todos los componentes necesarios para ejecutar el software, procesar las
entradas y generar los resultados. No obstante, en muchos casos, durante el proceso de
compilación tiene lugar un paso intermedio fundamental: antes de generar la traducción final en
código máquina, la mayoría de los compiladores suelen convertir el código fuente en un código

94
intermedio (también llamado código objeto) que, a menudo, es compatible con diversas plataformas
y que, además, también puede ser utilizado por un intérprete.

Al producir el código, el compilador determina qué instrucciones van a enviarse al procesador y en


qué orden. Si las instrucciones no son interdependientes, incluso es posible que puedan procesarse
en paralelo.

Tanto los compiladores como los intérpretes cumplen la función de convertir el código de software
que se ha escrito a un formato ejecutable y legible por máquina. Sin esta traducción, los
procesadores informáticos no podrían ejecutar el software en lenguajes como C, C++, PHP, Python
o Ruby, lo que convierte estos programas en unos componentes imprescindibles para utilizar
ordenadores, portátiles o smartphones. En los apartados anteriores, hemos visto que compiladores
e intérpretes presentan algunas diferencias básicas, algo que debe tenerse especialmente en
cuenta a la hora de elegir un lenguaje de programación adecuado para desarrollar un nuevo
software. En la siguiente tabla, se resumen los aspectos clave que caracterizan intérpretes y
compiladores:

Si observamos las diferencias entre compilador e intérprete, vemos claramente los puntos fuertes y
débiles de cada solución para traducir el código fuente: con el intérprete, los programas se pueden
ejecutar de inmediato y, por lo tanto, se inician mucho más rápido. Además, el desarrollo es mucho
más fácil que con un compilador, porque el proceso de depuración (es decir, la corrección de
errores) se lleva a cabo igual que la traducción, línea por línea. En el caso del compilador, primero
debe traducirse todo el código antes de poder resolver los errores o iniciar la aplicación. Sin
embargo, una vez que se ejecuta el programa, los servicios del compilador ya no son necesarios,
mientras que el intérprete continúa utilizando los recursos informáticos.

SOLUCIÓN HÍBRIDA DE INTÉRPRETE Y COMPILADOR

Para compensar los puntos débiles de ambas soluciones, también existe el llamado modelo de
compilación en tiempo de ejecución (en inglés, just-in-time-compiler, o “compilador justo a tiempo”).
Este tipo de compilador, que a veces también se conoce por el término inglés compreter (acrónimo
de compiler e interpreter), rompe con el modelo habitual de compilación y traduce el código del
programa durante el tiempo de ejecución, al igual que el intérprete. De esta forma, la alta velocidad
de ejecución típica de los compiladores se complementa con la simplificación del proceso de
desarrollo.

95
Java es uno de los ejemplos más conocidos de lenguaje basado en compilación en tiempo de
ejecución: el compilador JIT, que figura entre los componentes del Java Runtime Environment
(JRE), mejora el rendimiento de las aplicaciones Java traduciendo el código de bytes en código
máquina de manera dinámica.

PROGRAMACIÓN ESTRUCTURADA

Dentro de los paradigmas de la programación, la estructurada es una de los más comunes y a


menudo el primer paso de los estudiantes que comienzan a tratar con el código. En este artículo
queremos explicarte qué es exactamente y qué aportó en el mundo de la programación, hasta qué
punto es importante hoy en día y otros detalles interesantes.

Si no tienes claro lo que es un paradigma te recomendamos la lectura del artículo sobre los
paradigmas de la programación.

¿QUÉ ES LA PROGRAMACIÓN ESTRUCTURADA?

Es un paradigma de la programación, es decir, un estilo de codificar los algoritmos que se aplica en


los lenguajes de programación.

La programación estructurada se establece como paradigma de programación en torno a los años


70, siendo uno de sus principales padres Dijkstra, con el objetivo de mejorar las prácticas de
programación y facilitar la creación de programas más complejos, aumentando también la facilidad
de mantenimiento del software.

Consiste en un estilo de programación en el que encontramos las estructuras básicas ya conocidas


en los lenguajes de programación anteriores, como ciclos y condicionales, a los que se le añade la
posibilidad de ejecutar subrutinas o funciones.

¿QUÉ HABÍA ANTES DE LA PROGRAMACIÓN ESTRUCTURADA?

Antes de aparecer la programación estructurada existía ya un estilo de programación imperativo, en


el que se definían paso por paso las acciones para resolver un problema, el algoritmo, con las
estructuras de control mencionadas anteriormente, como bucles o condicionales. Ese estilo
imperativo ha perdurado hasta hoy y sigue siendo usado en la mayoría de los casos, sin embargo,
para controlar el flujo de ejecución de las sentencias, antes de la programación estructurada, se
usaba una instrucción denominada "GOTO".

96
El "GOTO", que viene de las palabras "go to" (ir a), permitía mencionar una línea de código a la que
el flujo de ejecución debía saltar. Gracias a esta instrucción era posible volver a ejecutar un pedazo
de código, saltarse unas cuantas líneas de código y cosas así. Durante mucho tiempo se había
programado con esa costumbre, pero daba como resultado programas difíciles de entender, ya que
no existía una clara distribución de las responsabilidades y tampoco facilitaba la organización del
código.

Probablemente muchos de los lectores no habrán tenido que lidiar con la sentencia "GOTO" y no se
hagan una idea de cómo eran los programas en aquella época. Básicamente consistían en bloques
de código lineal, carentes de forma y estructura, con muy complicado mantenimiento. Sobre todo,
era imposible ver a simple vista cómo iba a ejecutarse en programa y para hacerse una idea era
necesario seguir una traza, que saltaba de un lugar a otro del maremagnum de sentencias, de
manera enredada.

De hecho, el término del "código spaghetti" viene justamente de esa falta de forma y la disposición
del código sin una estructura definida, todo mezclado.

¿QUÉ APORTÓ LA PROGRAMACIÓN ESTRUCTURADA?

En lugar del "GOTO" la programación estructurada propone una pieza nueva que no existía
anteriores paradigmas de la programación, que es la subrutina, o función.

Gracias a las funciones era posible organizar el código de una manera mucho más clara, creando
pequeñas piezas de código que eran fácilmente utilizables, que aportaban semántica al código y
que conseguían definir una estructura jerárquica.

Con las funciones se pudo comenzar a separar las partes del código en pequeñas piezas fácilmente
comprensibles y mantenibles, a delegar la responsabilidad en rutinas que eran capaces de resolver
un problema y sobre las cuales el programador podía despreocuparse de su funcionamiento interno,
porque sabía que ellas serían capaces de resolver sus problemas.

A la capacidad de ser capaces de obviar los detalles no relevantes de algo es a lo que llamamos
"abstracción". En términos de programación vino gracias a las funciones. El programador puede
simplemente entender qué hace una función sin preocuparse en cómo está desarrollada por dentro,
lo que le permite centrarse en las partes que le interesan en cada momento y deshacer la
complejidad del software.

En resumen, algunas de las ventajas que nos aporta este estilo de programación son las siguientes:

97
• Capacidad de organización jerárquica del código. Unas funciones principales llaman a otras
funciones secundarias y éstas llaman a otras, creando una jerarquía de funciones fácilmente
entendibles.
• Permiten la abstracción, evitando que el programador necesite entender todo el código como
un único bloque.
• Aumenta la capacidad de depuración, ya que cada una de las unidades "función" se pueden
probar por separado.
• Se puede aumentar drásticamente el número de líneas de las aplicaciones sin que éstas se
vuelvan un caos.
• Aumenta la velocidad de desarrollo y, además, la capacidad de que varias personas puedan
participar en el desarrollo de un proyecto.
• Todo ello reduce la complejidad del software y los costes de desarrollo.

TIPOS DE FUNCIONES

A las subrutinas, el concepto que hoy conocemos por simplemente como "funciones", algunos
lenguajes de programación lo dividieron en dos tipos de estructuras:

• Las funciones tenían la particularidad de devolver valores.


• Los procedimientos realizaban procesos, pero no devolvían ningún valor.

Los lenguajes de programación que se usan comúnmente en la actualidad no difieren entre


funciones y procedimientos, los tratan de la misma manera, con la misma estructura.

¿SE USA HOY LA PROGRAMACIÓN ESTRUCTURADA?

Aunque la programación estructurada es algo que ya viene de lejos hoy en día todavía es altamente
usada en muchos proyectos y son la base de la mayoría de los lenguajes de programación actuales.
De hecho, muchos lenguajes populares como Javascript o PHP la fomentan de base, igual aunque
también incorporan otros paradigmas distintos.

Cuando una persona comienza con la programación a menudo se empieza conociendo la


programación estructurada, porque resulta más fácil y posibilita una curva de aprendizaje más
suavizada. Como los lenguajes de programación actuales incorporan todo lo que la programación
estructurada ha aportado, es muy sencillo aplicarla en la ruta de aprendizaje con tecnologías
comúnmente utilizadas.

98
Pero, que se use para aprender, no quiere decir que no se use todavía para resolver los problemas
actuales. Lenguajes como Javascript, aunque soportan otros paradigmas, la tienen muy arraigada
y aplicaciones realmente complejas están resueltas en Javascript con una organización del código
basada en funciones. Igual ocurre con otros lenguajes como PHP.

Muchos otros lenguajes de programación como Java usan cosas de programación estructurada,
pero requiere el desarrollo de clases, de programación orientada a objetos, por lo que no siempre
son usados como primer lenguaje para aprender a programar. también hay que decir que en la
actualidad los equipos de desarrollo están más y más organizando el código con clases, aunque los
lenguajes puedan ser usados solo con funciones. Quizás la comunidad donde más se usan las
funciones para organizar el código sea la de Javascript, aunque en este lenguaje se usan mucho
los objetos, incluso objetos creados de manera literal, como con JSON.

¿QUÉ VINO DESPUÉS DE LA PROGRAMACIÓN ESTRUCTURADA?

Después de la programación estructurada aparecieron otros paradigmas como la programación


orientada a objetos, que es la que domina el panorama actual de la programación.

La programación orientada a objetos hereda todo lo que tiene la programación estructurada,


trayendo un nuevo concepto que es la "clase", la cual permite agrupar datos heterogéneos y
funcionalidades asociadas a esos datos. Es un tema que puedes aprender mejor en el manual de
programación orientada a objetos. Java es el lenguaje de programación más popular que nos obliga
a programar siempre con clases.

Otros paradigmas como la programación funcional también vinieron después y son capaces de
resolver de manera muy elegante ciertos problemas. Actualmente hay muchos lenguajes de
programación funcional como Haskell o Scala, aunque a decir verdad no terminan de cuajar al 100%
porque no facilitan el desarrollo de todos los tipos de aplicaciones.

BIBLIOTECA DEL SISTEMA

Pues bien, una biblioteca de programación, o library como se le dice en inglés, es como ir a Ikea.
Aquí no hay que construir la casa, sino buscar ayuda con los muebles y su disposición dentro de la
casa. En este caso, no se trata de que quieras llevar a cabo el esfuerzo de crear una mesa de
madera tallando un árbol y barnizándola. Simplemente, vas y compras la mesa que más te gusta.
En este caso, se diría que tú tienes el control sobre la disposición de las cosas en tu casa.

99
De manera similar, un programador usa una biblioteca de programación donde toma pedazos de
código (muebles) para llevar a su casa (su código de programación) para cambiar un poco las cosas
aquí y allá. Por ejemplo, en esta reseña hablan de una aplicación web que usa un library.

SISTEMA DE PROGRAMACIÓN O FRAMEWORK

En contraste, un sistema de programación, o framework en inglés, es como preparar el modelo de


una casa para construirla. Aquí tú tienes un conjunto de planos y algunas elecciones limitadas en
cuanto a arquitectura y diseño se refiere. A diferencia con ir a Ikea o usar una biblioteca, el contratista
o los planos son los que marcan la pauta: ellos están en control.

En cierta manera, los frameworks son como plantillas en donde debes colocar la información que
pide el código de programación para usarla en caso de que ocurra cierto evento con la aplicación
web. Por ejemplo, si el usuario hace click en esta web y ocurre un error, enviar tal mensaje de
advertencia con información adicional sobre cómo evitar el error. Por supuesto, las funciones que
traen los frameworks son más complejas.

¿CUÁL ES LA DIFERENCIA ENTONCES? ¿CUÁL USAN LOS PROGRAMADORES?

Los programadores usan un término para establecer la diferencia entre ambos: inversión del control.
Es decir, a nivel de código una biblioteca y un sistema de programación son similares. La diferencia
está en quién tiene el control. En el caso de las bibliotecas, el programador tiene el control. Cuando
alguien usa esta herramienta, la situación es similar a cuando vas a una biblioteca física: tienes tu
lugar donde lees y, cuando necesitas otro libro, vas y buscas en los estantes.

En el caso de los sistemas, el programador no tiene el control. Aquí sucede similar a estas
situaciones donde debes llenar un formulario: no puedes cambiar nada, sino agregar la información
que te solicitan. Tanto los frameworks como las libraries están estrechamente relacionadas. El
primero está contenido en el segundo. De modo que, el programador usa ambos en función de lo
que necesite crear para su aplicación web.

React/Gatsby es un ejemplo de biblioteca/sistema de programación.

LA BIBLIOTECA DEL SISTEMA

Junto con los compiladores de C y C++, se incluyen ciertos archivos llamados bibliotecas más
comúnmente librerías. Las bibliotecas contienen el código objeto de muchos programas que

100
permiten hacer cosas comunes, como leer el teclado, escribir en la pantalla, manejar números,
realizar funciones matemáticas, etc. Las bibliotecas están clasificadas por el tipo de trabajos que
hacen, hay bibliotecas de entrada y salida, matemáticas, de manejo de memoria, de manejo de
textos y como imaginarás existen muchísimas librerías disponibles y todas con una función
específica.

Nota: Existe una discusión sobre el nombre de estos archivos. Muchas personas consideran que el
nombre adecuado es archivos de biblioteca, y están en lo correcto. Sin embargo, la mayoría
llamamos a estos archivos librerías, y también me incluyo entre estos. El error proviene del nombre
en inglés, que es library. Este término se traduce como biblioteca, y no como librería. De este modo
a lo largo de esta sección las llamaré de cualquiera de las dos formas, para estar más claros.

Hay un conjunto de bibliotecas (o librerías) muy especiales, que se incluyen con todos los
compiladores de C y de C++. Son las librerías (o bibliotecas) ANSI o estándar. También hay librerías
que no son parte del estándar, pero en esta sección sólo usaremos algunas bibliotecas (o librerías)
ANSI.

Nota 2: Sé que esto pinta aburrido, pero es muy útil y las librerías nos facilitan enormemente el
trabajo a la hora de programar. Recuerda que antes de hablar librerías y demás es necesario
dominar algunos conceptos de fundamentación en general y otros temas importantes (ciclos,
condicionales y demás) Ahora veamos algunas librerías y como es su sintaxis.

¿QUÉ SON EXACTAMENTE LAS LIBRERÍAS?

En C++, se conoce como librerías (o bibliotecas) a cierto tipo de archivos que podemos importar o
incluir en nuestro programa. Estos archivos contienen las especificaciones de diferentes
funcionalidades ya construidas y utilizables que podremos agregar a nuestro programa, como por
ejemplo leer del teclado o mostrar algo por pantalla entre muchas otras más.

Al poder incluir estas librerías con definiciones de diferentes funcionalidades podremos ahorrarnos
gran cantidad de cosas, imaginemos por ejemplo que cada vez que necesitemos leer por teclado,
debamos entonces crear una función que lo haga (algo realmente complejo), al poder contar con
las librerías en C++, podremos hacer uso de una gran variedad de funciones que nos facilitarán la
vida y aumentarán el modularidad de nuestros códigos. Las librerías no son únicamente archivos
externos creados por otros, también es posible crear nuestras propias librerías y utilizarlas en
nuestros programas. Las librerías pueden tener varias extensiones diferentes, las más comunes
son: .lib, .bpl, .a, .dll, .h y algunas más ya no tan comunes.

101
En conclusión: Las librearías son archivos (no siempre externos) que nos permiten llevar a cabo
diferentes tareas sin necesidad de preocuparnos por cómo se hacen sino simplemente entender
cómo usarlas. Las librearías en C++ permiten hacer nuestros programas más modulares y
reutilizables, facilitando además crear programas con funcionalidades bastante complejas en unas
pocas líneas de código.

SINTAXIS PARA DECLARAR LIBRERÍAS EN C++

La declaración de librerías, tanto en C como en C++, se debe hacer al principio de todo nuestro
código, antes de la declaración de cualquier función o línea de código, debemos indicarle al
compilador que librerías usar, para el saber que términos estaran correctos en la escritura de nuestro
código y cuáles no. La sintaxis es la siguiente: #include <nombre de la librería> o alternativamente
#include "nombre de la librería". Cualquiera de las 2 formas es válido en C++ (no estoy seguro si en
C sea válido), ten en cuenta que siempre el nombre de la librería debe ir entre " y " o entre < y >. En
tu código puedes declarar todas las librerías que quieras, aunque en realidad no tienen sentido
declarar una librería que no vas a usar en tu programa, sin embargo no existe límite para esto.

Librerías Estandar de C++ (Standar Template Library o STL)

A continuación, pondremos algunas de las librerías de uso más común de C++ y que forman parte
de las librerías estándar de este lenguaje.

• Fstream: Flujos hacia/desde ficheros. Permite la manipulación de archivos desde el


programar, tanto leer como escribir en ellos.
• Iosfwd: Contiene declaraciones adelantadas de todas las plantillas de flujos y sus typedefs
estándar.
• Iostream: Parte del a STL que contiene los algoritmos estándar, es quizá la más usada e
importante (aunque no indispensable).
• La biblioteca list: Parte de la STL relativa a contenedores tipo list; listas doblemente enlazadas
• Math: Contiene los prototipos de las funciones y otras definiciones para el uso y manipulación
de funciones matemáticas.
• Memory: Utilidades relativas a la gestión de memoria, incluyendo asignadores y punteros
inteligentes (auto_ptr). "auto_ptr" es una clase que conforma la librería memory y permite un
fácil manejo de punteros y su destrucción automaticamente.
• Biblioteca new: Manejo de memoria dinámica
• Numeric: Parte de la librería numérica de la STL relativa a operaciones numéricas.

102
• Ostream: Algoritmos estándar para los flujos de salida.
• Queue: Parte de la STL relativa a contenedores tipo queue (colas de objetos).
• Librería stdio: Contiene los prototipos de las funciones, macros, y tipos para manipular datos
de entrada y salida.
• Librería stdlib: Contiene los prototipos de las funciones, macros, y tipos para utilidades de
uso general.
• String: Parte de la STL relativa a contenedores tipo string; una generalización de las cadenas
alfanuméricas para albergar cadenas de objetos. Muy útil para el fácil uso de las cadenas de
caracteres, pues elimina muchas d elas dificultades que generan los char.
• Typeinfo: Mecanismo de identificación de tipos en tiempo de ejecución.
• Vector: Parte de la STL relativa a los contenedores tipo vector; una generalización de las
matrices unidimensionales C/C++.
• Forward_list: Esta librería es útil para implementar con gran facilidad listas enlazadas simples.
• List: Permite implementar listas doblemente enlzadas (listas enlazadas dobles) facilmente.
• Iterator: Proporciona un conjunto de clases para iterar elementos.
• Regex: Proporciona fácil acceso al uso de expresiones regulares para la comparación de
patrones.
• Thread: Útil para trabajar programación multihilos y crear múltiples hilos en nuestra
aplicación.
• Time: Útil para obtener marcas de tiempo durante ejecución. Se usa con frecuencia para
conocer el tiempo exacto durante un programa.

¿CÓMO DECLARAR UNA LIBRERÍA EN C++?

Veamos a continuación como se haría la declaración de unas cuantas librerías conocidas, recuerda
que ese puede declarar todas las librerías necesarias y siempre debe hacerse al comienzo del
código fuente.

#include "iostream"

#include "string"

#include <math.h>

#include <conio.h>

using namespace std;

103
Con esto debió quedar claro, como declarar librerías C++ al interior de un código fuente. Lo único
adicional, es la línea que dice using namespace std; esta línea nos ayuda a declarar un espacio de
nombre que evita tener que usarlo cada que accedemos a alguna función especifica de una librería.
Teniendo este namespace declarado podemos llamar por ejemplo el comando cout >>, que
pertenece a la librería iostream, sin embargo sin este namespace sería std::cout >>, imagina tener
que hacer esto cada vez que uses algún comando o función de las librerías, sería bastante tedioso.

ACERCA DEL NAMESPACE STD

Todas las librerías estándar de C++ contienen una declaración del espacio de nombre std, es decir
que todas las librerías que hacen parte del estándar de C++ colocan entidades dentro de este
espacio de nombre.

Por esta razón cuando declaramos el uso del espacio de nombre std por medio de "using
namespace std;", podemos evitar estar escribiendo std::cout o std::cin, etc en nuestro código.

El espacio de nombre std como tal no es una librería sino simplemente un namespace, por esta
razón no reemplaza la declaración de las librerías del código, simplemente facilita la escritura de
éste al momento de usar las entidades de las librerías estándar. Sin embargo si vamos a hacer uso
de una o varias librerías estándar de C++ es recomendable que declaremos el namespace std, para
no tener que estar constantemente escribiendo cosas similares a las que puse hace unas líneas
como std::cin o similares, dado que únicamente se puede acceder a la entidades de las librerías
estándar por medio del espacio nombre std.

Muy bien, ahora veamos algunos ejemplos simples del uso de librerías o bibliotecas en C++

Ejemplo de librerías en C++

En el siguiente ejemplo veremos el uso de la librería stdlib.h que posee una gran variedad de
funcionalidades, para este ejemplo usaremos la función rand que nos permite generar un número
aleatorio.

#include <stdlib.h>

#include <iostream>

#include

using namespace std;

104
int main ()

// Se genera una semilla diferente cada vez (basada en el tiempo exacto de ejecución)

// Se debe llamar siempre, para generar números realmente diferentes cada vez

// La funciçon time viene de la libtrería time.h

srand (time(NULL));

cout << ("Se va a generar un numero aleatorio ....\n");

cout << ("El numero generado es : ");

cout << rand(); //Se genera el número con rand y se muestra en pantalla

return 0;

En el anterior código hemos hecho uso de dos librerías: iostream y stdlib. La librería o biblioteca
iostream, nos permitirá hacer uso del cin y el cout para obtener o imprimir valores por pantalla,
respectivamente mientras stdlib nos dará acceso a la función rand que generará por nosotros un
número cualquiera.

DISEÑO DE INTERFAZ DE USUARIO

El diseño centrado en el usuario es un proceso iterativo que dirige sus objetivos a los usuarios y sus
necesidades. Sus creadores se apoyan en una variedad de técnicas de investigación y diseño para
crear productos altamente utilizables y accesibles.

Los diseñadores emplean una combinación de métodos y herramientas de investigación, como las
encuestas, entrevistas o lluvia de ideas con la finalidad de comprender a profundidad las
necesidades del usuario.

El término «experiencia del usuario» lo acuñó Donald Norman en 1993, cuando trabajaba para
Apple. A mediados de la década de 1990, muchas empresas de tecnología lo utilizaron como un
diferenciador de producto clave. El libro de Norman, La psicología de los objetos cotidianos (1988),
sigue siendo un referente para el diseño centrado en el usuario, en él promociona el desarrollo
iterativo y las relaciones entre el usuario y el objeto.

105
Si lo piensas, la experiencia del usuario no es un fenómeno nuevo. Ha existido que los humanos
comenzaron a interactuar con herramientas y máquinas. Se encuentra en todo lo que tocamos y
creamos, desde objetos físicos hasta en la experiencia de hacer una página web.

IMPORTANCIA DEL DISEÑO CENTRADO EN EL USUARIO

El diseño centrado en el usuario es vital para lograr el reconocimiento de marca por parte del cliente.
No solo facilita la vida de los usuarios, sino que permite establecer un canal de comunicación con
ellos, gracias a sus virtudes.

En otras palabras, un diseño centrado en el usuario consigue captar su atención y retener su interés.
ya que este puede interactuar con el sitio de una manera intuitiva, sin la necesidad de capacitación
o experiencia.

Como estrategia, el diseño centrado en el usuario es crucial para una nueva o pequeña empresa.
Usualmente se dice «la primera impresión es la que cuenta», por ello, el uso del diseño centrado en
el usuario puede hacer o deshacer el reconocimiento de tu marca.

CARACTERÍSTICAS DEL DISEÑO CENTRADO EN EL USUARIO

1. Facilidad y sencillez del entorno

Si alguna vez te has encontrado en un sitio web y no entiendes lo que ofrece o no puedas navegar
fácilmente por la página, es muy probable que hayas cerrado la ventana e intentado con otra página.
Finalmente, si tu empresa depende del tráfico de Internet, debes asegurarte de que el diseño
centrado en el usuario esté a la altura y que capte y aborde toda la experiencia del usuario. Para
esto, puedes pedir la ayuda de profesionales de disciplinas que aportan mejoras al proceso de
diseño, como psicólogos, ingenieros de software y hardware, lo mismo que de expertos en dominios
y los propios usuarios.

2. Equipos de trabajo especializados en el área

Para abarcar toda la experiencia del usuario considera involucrar a los usuarios en la evaluación y
garantizar que la supervisión del diseño centrado en el usuario sea a largo plazo. El diseño centrado
en el usuario es una forma poderosa de descubrir qué funciona bien, qué no y por qué. Tus usuarios
son un sistema de alerta temprana que puedes utilizar para corregir el curso y ajustar un diseño
ideal que te ayude a alcanzar tus objetivos.

106
3. Sentimiento de facilidad

Este será el resultado de una planificación y diseño intuitivos por parte de los equipos de trabajo.
Será cuando el usuario se sienta capaz de realizar sus propios procesos de conocimiento y
exploración, sin la necesidad de recurrir a consultas especializadas en la red. De esta manera, el
usuario permanecerá más tiempo con tu marca, pues todas sus necesidades se satisfarán.

4. Comprobación de uso y accesibilidad

Este proceso expone aspectos positivos y negativos que tu equipo pudo haber pasado por alto en
áreas vitales, como la usabilidad y la accesibilidad. El diseño centrado en el usuario es un proceso
iterativo que se enfoca en la comprensión de los usuarios y su contexto en todas las etapas de
diseño y desarrollo.

Cada iteración del enfoque del diseño centrado en el usuario implica cuatro fases distintas.

• Etapas del diseño centrado en el usuario


• Entender el contexto del usuario.
• Especificar los requerimientos del usuario.
• Diseñar las soluciones.

EVALUAR LOS RESULTADOS

1. Entender el contexto del usuario

Los diseñadores tratan de comprender el contexto de los usuarios que usan un sistema. Las
encuestas, focus groups y sondeos ayudan a entender las necesidades de las personas y a ponerse
en sus zapatos cuando se trata de interactuar con un sitio web, una aplicación o un contenido digital.

2. Especificar los requerimientos del usuario

Estos identifican y especifican los requisitos de los usuarios, como el tipo de dispositivos desde los
que acceden a un sitio, debido a que mirar el contenido desde la pantalla de una computadora no
es lo mismo que hacerlo desde el teléfono móvil.

Por otro lado, la mayoría de los usuarios de una app prefieren ver videos explicativos que leer un
texto para conocer sus funciones. También podría aumentar la demanda de un sistema operativo
que no habían considerado sus desarrolladores.

107
3. Diseñar las soluciones

En esta fase, los diseñadores crean las soluciones específicas a las necesidades del usuario y que
se adapten a los objetivos de la empresa o marca. Es importante discernir entre aquellos cambios
que son relevantes tanto para usuarios como creadores, porque es imposible darles gusto a todas
las personas en el planeta. Así que hay que enfocarse en lo que ayudará a dar una gran experiencia
a quienes lo piden realmente.

4. Evaluar los resultados

En esta etapa se evalúan los resultados según el contexto y los requisitos de los usuarios a fin de
verificar qué tan bien se está desempeñando el diseño. Es decir, se visualiza qué tanto se acercó al
nivel que coincide con los requerimientos específicos de los usuarios y si satisface todas sus
necesidades relevantes.

Como la palabra lo indica, iteración implica repetir varias veces un proceso con la intención de
alcanzar el objetivo deseado. A partir de aquí, el equipo de diseño puede realizar más iteraciones
de estas cuatro fases hasta que los resultados de la evaluación sean satisfactorios.

ETAPAS DEL DISEÑO CENTRADO EN LAS PERSONAS

3 principios del diseño centrado en el usuario

De esta manera, es que podemos centrarnos en tres principios fundamentales para crear un diseño
centrado en el usuario de una manera más ágil y efectiva.

1. Obedece a un análisis

Antes de tener la posibilidad de realizar un diseño centrado en el usuario es necesario conocer lo


que él busca, quiere y necesita. Así que ejecuta un periodo de tiempo en el que desarrolles una
investigación exhaustiva para desentrañarlo.

2. Define las acciones del usuario

Esto significa que cada acción que ejecute el usuario será planeada y prevista por el diseño centrado
en él. En este sentido no hay coincidencias ni espacios abiertos, ya que cada aspecto será
considerado por un equipo de trabajo que logré no solo pensar en el usuario en primer término, sino
que logré, incluso, adelantarse a lo que quiere y busca.

108
3. Prueba y verifica

Finalmente, la única manera de lograr un diseño centrado en el usuario es por medio de un constante
proceso de pruebas. Así que prueba y modifica cada aspecto cuantas veces sea necesario, pues
en esto se basa la seguridad y funcionalidad que tu diseño centrado en el usuario pueda otorgar.

LOS 6 ELEMENTOS PARA UNA METODOLOGÍA DEL DISEÑO CENTRADO EN EL


USUARIO

El diseño centrado en el usuario es un proceso en el que las decisiones están dirigidas por y hacia
el usuario y los objetivos que pretende satisfacer el producto. La usabilidad del diseño es evaluada
y mejorada en el proceso.

El proceso de diseño centrado en el usuario se compone de varios métodos y tareas relacionadas


con el desarrollo digital. Determina las tareas que creas convenientes y el orden de acuerdo con el
tipo de proyecto, sus requisitos, el equipo disponible y las fechas límite.

1. Grupos focales o focus group

Estos, involucran a un grupo invitado de usuarios intencionados y reales de un sitio para que
compartan sus pensamientos, sentimientos, actitudes e ideas sobre un determinado tema.
Organizar grupos focales dentro de tu organización también puede ser muy útil para lograr la
aceptación de un proyecto. Es mejor usar los grupos focales utilizan con mayor frecuencia como
una entrada para el diseño. Generalmente producen datos no estadísticos y son un buen medio
para obtener información sobre un dominio. Es necesario tener un moderador y un analista
experimentados para que un grupo focal sea efectivo.

2. Pruebas de usabilidad

Las sesiones de prueba de usabilidad evalúan un sitio mediante la recopilación de datos de las
personas a medida que lo usan. Se invita a una persona a asistir a una sesión en la que se le pedirá
que realice una serie de tareas, mientras un moderador toma nota de las dificultades que encuentre.
Se puede pedir a los usuarios que sigan el protocolo de pensar en voz alta. Esta técnica les permite
verbalizar lo que están haciendo y por qué lo están haciendo. Debes tener en cuenta que el uso de
esta técnica ralentizará considerablemente las tareas de los usuarios. También puedes cronometrar
a los usuarios para conocer cuánto tiempo los lleva completar las tareas, lo que es una buena
medida de eficiencia. Normalmente se requiere la presencia de dos especialistas por sesión: uno
para moderar y otro para detectar problemas.

109
Las pruebas de usabilidad se pueden emplear al inicio de un diseño o al final de un proyecto. Este
método representa una excelente manera de descubrir cuáles son los problemas de usabilidad más
probables en tu sitio o producto y se puede utilizar para generar datos no estadísticos o estadísticos.

Las pruebas de usabilidad requieren que haya un diseño disponible para probar, incluso si es solo
en papel. Este método funciona mejor si se centra en la recopilación de comentarios no estadísticos
sobre un diseño, a través de la técnica de «hablar en voz alta» o medidas estadísticas.

3. Clasificación de tarjetas

Este método se utiliza para sugerir estructuras y categorías intuitivas.

Se le presenta a un participante un paquete de fichas sin clasificar. Cada tarjeta tiene una
declaración escrita que se relaciona con una página de un sitio o de una parte del proyecto. Se le
pide al participante que clasifique estas tarjetas en grupos y luego que nombre esos grupos. Los
resultados de múltiples usuarios se combinan y analizan estadísticamente. La clasificación de
tarjetas generalmente se usa como una entrada al diseño. Es una excelente manera de sugerir
buenas categorías para el contenido de tu sitio y derivar la arquitectura de información, por ejemplo.
Asimismo, se puede utilizar para generar datos estadísticos. Hay que proporcionar a los
participantes una prueba en algunas tarjetas fáciles de reconocer, como de deportes o animales.
Con esto se les prepara sobre lo que se espera que hagan durante el ejercicio, por lo que el resultado
puede ser una sesión más productiva.

4. Diseño participativo

En este método no solo se les pide a los usuarios sus opiniones sobre temas de diseño, sino que
los involucra activamente en los procesos de diseño y toma de decisiones. El diseño participativo
generalmente se usa dentro de un miniproyecto para generar prototipos que se incorporen al
proceso de diseño de un proyecto general. Un ejemplo sería un taller de diseño participativo en el
que los desarrolladores, diseñadores y usuarios trabajen juntos para crear un prototipo inicial. Este
prototipo inicial se incorporaría a un proceso de diseño más tradicional.

Los proyectos que solo utilizan diseño participativo son muy raros. Como las sesiones de diseño
participativo pueden ser muy fluidas requieren un moderador experimentado con un conocimiento
profundo del dominio para guiarlas.

110
5. Cuestionarios

Los cuestionarios son el método más conocido. Son el medio para pedir a los usuarios sus
respuestas a un conjunto predefinido de preguntas. Representan una buena forma de generar datos
estadísticos. Los cuestionarios generalmente se emplean cuando un equipo de diseño solo tiene
acceso remoto con los usuarios de un sitio. También se utiliza cuando se está buscando un tamaño
de muestra mayor que el que puede lograrse por medio del contacto directo. Es por esta razón que
los cuestionarios generalmente se administran por correo o medios electrónicos.

Los cuestionarios permiten el análisis estadístico de los resultados, lo que puede aumentar la
credibilidad de un estudio a través de su apariencia científica. Esto hace que sea aún más importante
que el cuestionario esté bien diseñado y que contenga preguntas no sesgadas.

6. Entrevistas

Este método generalmente involucra a un entrevistador que habla con un participante a la vez. Las
ventajas de una entrevista son que se puede explorar en detalle el punto de vista de un participante.
También se puede identificar cualquier malentendido entre el entrevistador y los participantes, el
cual se puede abordar rápidamente. Por lo general, el resultado de una entrevista es exclusivamente
no estadístico. Es fundamental que los informes de las entrevistas sean analizados a profundidad
por profesionales experimentados.

Las entrevistas generalmente se emplean al principio del proceso de diseño para obtener una
comprensión más detallada de un dominio y área de actividad o requisitos específicos.

EL MARKETING CENTRADO EN EL USUARIO

En el pasado, las estrategias de marketing solían centrarse en el producto. El trabajo del vendedor
era informar a los clientes potenciales de todos los beneficios y ventajas de su mercancía. Sin
embargo, la industria está encontrando formas nuevas e innovadoras para atraer a los clientes a
sus negocios. El marketing centrado en el usuario es una estrategia que consiste en poner al cliente
en el centro de lo que hace tu empresa. Cada proceso debe comenzar y terminar con el cliente en
mente. Esto más que una mera estrategia, es una cultura organizacional. Las empresas centradas
en el cliente han demostrado ser un 60 % más rentables que las empresas centradas en el producto.

El marketing centrado en el usuario no ocurre de la noche a la mañana y requiere una serie de


estrategias para implementarlo. Hay muchos métodos para adoptar esta cultura y las empresas

111
deben elegir el que sea más acorde con su marca. Una de las mejores maneras de comenzar es a
través de un enfoque inbound marketing.

Se trata de crear un marketing que los usuarios amen y busquen. Para obtener este tipo de
marketing es esencial tener en cuenta tres aspectos: el contenido, el usuario al que está destinado
y el contexto de uso. La información sobre estos tres aspectos se recopila mediante un análisis
constante durante el proceso de creación.

Para lograr esto, se debe implementar una metodología que se divide en tres etapas: atraer,
interactuar y deleitar. Así, las experiencias que crea tu empresa deben satisfacer a tus clientes
desde la etapa inicial hasta el proceso posterior a la compra. Si tu objetivo es desarrollar relaciones
rentables a largo plazo, centra el interés en tus clientes en todo momento.

CÓMO APLICAR EL DISEÑO CENTRADO EN EL USUARIO EN TU SITIO WEB

• Identifica las necesidades de tus usuarios y el contexto que los rodea.


• Especifica los requisitos tanto para la empresa como para el usuario.
• Diseña las soluciones.
• Analiza y evalúa tus diseños en función de las necesidades del usuario.
• Diseña tu sitio web.
• Repite el proceso.

1. Identifica las necesidades de tus usuarios y el contexto que los rodea

Para hacer esto, debes responder tres preguntas:

• ¿Quién es mi usuario? Averigua el tipo de personas que utilizarán tu producto y, lo que es


más importante, cuáles son sus objetivos.
• ¿Cuáles son los problemas de mis usuarios? Estos son los problemas a los que se enfrentan
tus usuarios y que ayudan directa e indirectamente a resolver el diseño.
• ¿Qué hacen los usuarios? Esto puede significar todo: desde su interacción con el diseño
hasta las emociones que experimentarán al usarlo.

Una gran herramienta para usar en este paso es un generador de buyer persona. Esto puede
ayudarte a formular un usuario objetivo para el que está diseñado y fundamentado tu producto.
Recuerda que tener esta plantilla no reemplaza la comunicación con tus usuarios. Realizar una

112
investigación adecuada de los usuarios mediante entrevistas y la interacción con ellos es crucial
para cualquier proceso de diseño centrado en el usuario.

Es por eso que una buena investigación de usuarios es indispensable para el éxito de tu proyecto.

2. Especifica los requisitos tanto para la empresa como para el usuario

Ahora que conoces a tus usuarios y sus necesidades, es hora de comprender sus métricas de éxito.
Esto significa tener una idea clara de dos aspectos:

• Requisitos comerciales. Estos son los objetivos y resultados que quieres conseguir, como la
cantidad de leads o el alcance del diseño.
• Requisitos de usuario. Esto es todo lo que el usuario puede obtener del proceso, entre ellos
los problemas que está resolviendo el diseño.

Ambos abordan el gran por qué: ¿por qué este diseño es beneficioso tanto para la empresa como
para el usuario? ¿Por qué vale la pena destinar tiempo para hacerlo ahora?

3. Diseña las soluciones

Ahora que has identificado las necesidades de tus usuarios, así como sus métricas para el éxito, es
el momento de establecer y diseñar soluciones para ellos. Esta etapa del proceso significa construir
y decidir junto con los diseñadores aspectos como el mapa del sitio, flujo de usuario, maquetas,
imágenes, iconos y paleta de colores. Una vez que tu equipo de diseño haya abordado los
problemas de tus usuarios objetivo, es hora de continuar al paso final.

4. Analiza y evalúa tus diseños en función de las necesidades del usuario

Este paso será un vistazo general a tu producto final para ver si cumple con todos los objetivos que
se propuso en el paso dos. Algunas preguntas que te puedes hacer son:

• ¿Fue nuestro proceso correcto? ¿Por qué?


• ¿Cómo responden nuestros usuarios al producto?
• ¿Resolvió sus problemas y puntos débiles?

5. Diseña tu sitio web

Ahora debes pensar en lo que necesita tu sitio web para operar formalmente. Así que como primer
paso consulta este artículo que te ayudará a emprender esta tarea desde cero. Recuerda que
además de tu contenido debes prestar atención a la rueda de colores que conforman tu sitio y
también a otros aspectos tales como crear iconos en el menú y cuerpo de tu sitio web.

113
Así que ya sea si llegas a generar este elemento puedes ayudarte de las herramientas que tenemos
diseñadas para facilitarte este proceso.

6. Repite el proceso

Esta es la iteración: volver al paso uno y comenzar otra vez el proceso de diseño centrado en el
usuario, pero con el conocimiento que adquiriste en la primera ronda. Aunque técnicamente no es
un paso, es lo que viene después de los 4 pasos mencionados para asegurar el éxito del ejercicio.

INTERRUPCIONES DE DOS

En informática una interrupción es una señal recibida por el procesador de una computadora, que
indica que debe «interrumpir» el curso de ejecución actual y pasar a ejecutar código específico para
tratar esta situación, una suspensión temporal de la ejecución de un proceso, para pasar a ejecutar
una subrutina de servicio de interrupción, la cual, generalmente, no forma parte del programa, sino
que pertenece al sistema operativo o al BIOS.

Una vez finalizada dicha subrutina, se reanuda la ejecución del programa.

Son generadas por los dispositivos periféricos habilitando una señal del CPU (llamada IRQ del inglés
"interrupt request") para solicitar atención del mismo.

Por ejemplo, cuando un disco duro completa una lectura solicita atención al igual que cada vez que
se presiona una tecla o se mueve el ratón.

La primera técnica que se empleó para esto fue el polling, que consistía en que el propio procesador
se encargara de sondear los dispositivos periféricos cada cierto tiempo para averiguar si tenía
pendiente alguna comunicación para él. Siendo muy ineficiente, ya que el procesador consumía
constantemente tiempo y recursos en realizar estas instrucciones de sondeo.

El mecanismo de interrupciones fue la solución que permitió al procesador desentenderse de esta


problemática, y delegar en el dispositivo periférico la responsabilidad de comunicarse con él cuando
lo necesitara.

El procesador, en este caso, no sondea a ningún dispositivo, sino que queda a la espera de que
estos le avisen (le "interrumpan") cuando tengan algo que comunicarle (ya sea un evento, una
transferencia de información, una condición de error, etc.).

114
FUNCIONAMIENTO DEL MECANISMO DE INTERRUPCIONES

Todos los dispositivos que deseen comunicarse con el procesador por medio de interrupciones
deben tener asignada una línea única capaz de avisar al CPU cuando le requiere para realizar una
operación. Esta línea se denomina IRQ.

Las IRQ son líneas que llegan al controlador de interrupciones, un componente de hardware
dedicado a la gestión de las interrupciones, y que puede estar integrado en el procesador principal
o ser un circuito separado conectado al mismo. El controlador de interrupciones debe ser capaz de
habilitar o inhibir las líneas de interrupción y establecer prioridades entre las mismas.

Cuando varias líneas de petición de interrupción se activan a la vez, el controlador de interrupciones


utilizará estas prioridades para escoger la interrupción sobre la que informará al procesador
principal.

También puede darse el caso de que una rutina de tratamiento de interrupción sea interrumpida
para realizar otra rutina de tratamiento de una interrupción de mayor prioridad a la que se estaba
ejecutando; aunque hay interrupciones que no se pueden deshabilitar (conocidas como
interrupciones no enmascarables o NMI).

Un procesador principal que no tenga un controlador de interrupciones integrado suele tener una
única línea de interrupción llamada habitualmente INT.

Esta línea es activada por el controlador de interrupciones cuando tiene una interrupción que servir.
Al activarse esta línea, el procesador consulta los registros del controlador de interrupciones para
averiguar cuál IRQ hay que atender.

A partir del número del IRQ busca en la tabla de vectores de interrupción la dirección de la rutina a
la que debe llamar para atender la petición del dispositivo asociado a dicha IRQ.

Terminar la ejecución de la instrucción máquina en curso.

1. Salvar el estado del procesador (valores de registros y flags) y el valor del contador de programa,
IP, en la pila, de manera que, en la CPU, al terminar el proceso de interrupción, pueda seguir
ejecutando el programa a partir de la última instrucción.

2. La CPU salta a la dirección donde está almacenada la rutina de servicio de interrupción (Interrupt
Service Routine, o abreviado ISR) y ejecuta esa rutina que tiene como objetivo atender al dispositivo
que generó la interrupción.

115
3. Una vez que la rutina de la interrupción termina, el procesador restaura el estado que había
guardado en la pila en el paso 2 y retorna al programa que se estaba usando anteriormente.

MECANISMO Y LÍNEAS DE PETICIÓN DE INTERRUPCIÓN

El bus de control de la placa base dispone de líneas específicas para el sistema de interrupciones.
Un PC típico dispone en su placa base de un controlador de interrupciones 8259 de Intel o de un
circuito integrado análogo.

Este dispositivo electrónico dispone de hasta 16 líneas IRQ, numeradas desde el 00 hasta el 15. En
las nuevas placas base este circuito está integrado junto con el resto del chipset y permite hasta 24
interrupciones.

En el IBM PC y XT existían 8 líneas de petición de interrupción manejadas por el controlador de


interrupciones Intel 8259. Estas líneas están numeradas del 0 al 7, las dos primeras están asignadas
al timer tick del temporizador Intel 8253, y al teclado. Solo quedaban 6 líneas para otros dispositivos,
que aparecen como tales en el bus de control (IRQ2 - IRQ7). A partir del modelo AT se añadieron
otras 8 líneas, numeradas del 8 al 15, mediante un segundo controlador de interrupciones (PIC),
aunque la tecnología empleada exigió colgarlo de la línea IRQ2 del primero, de forma que esta línea
se dedica a atender las interrupciones del segundo controlador a través de la línea 9 de este último,
y la línea 8 se dedicó al reloj de tiempo real, un dispositivo que no existía en los modelos XT.

Aunque internamente se manejan 16 líneas, no todas tienen contacto en los zócalos del bus externo
(son las marcadas con asterisco en la tabla que sigue). La razón de esta ausencia en los zócalos
de conexión es que son de asignación fija, y solo son usadas por ciertos dispositivos instalados en
la propia placa base.

En concreto la línea NMI está asignada al mecanismo de control de paridad de la memoria, la línea
0 está asignada al cronómetro del sistema y la línea 1 al chip que controla el teclado (dispositivos
que pueden requerir atención urgente por parte del procesador). Es costumbre denominar IRQx a
las que tienen prolongación en el bus.

Teóricamente las restantes líneas podrían ser asignadas a cualquier nuevo dispositivo, pero en la
práctica algunas están reservadas a dispositivos estándar. Por ejemplo, IRQ3 está casi siempre
asignado al puerto serie COM2 y el IRQ4 al COM1; IRQ6 al controlador estándar de disquetes y
IRQ7 al puerto de impresora LPT1.

116
Atendiendo a la fuente que las produce, las interrupciones pueden clasificarse de la siguiente forma:

Interrupciones de hardware.

Estas son asíncronas a la ejecución del procesador, es decir, se pueden producir en cualquier
momento independientemente de lo que esté haciendo el CPU en ese momento. Las causas que
las producen son externas al procesador y a menudo suelen estar ligadas con los distintos
dispositivos de entrada o salida.

Excepciones

Son aquellas que se producen de forma síncrona a la ejecución del procesador y por tanto podrían
predecirse si se analiza con detenimiento la traza del programa que en ese momento estaba siendo
ejecutado en la CPU. Normalmente son causadas al realizarse operaciones no permitidas tales
como la división entre 0, el desbordamiento, el acceso a una posición de memoria no permitida, etc.

Interrupciones por software

Son aquellas generadas por un programa en ejecución, para generarlas, existen distintas
instrucciones en el código máquina que permiten al programador producir una interrupción, las
cuales suelen tener nemotécnicos tales como INT (por ejemplo, en DOS se realiza la instrucción
INT 0x21 y en Unix se utiliza INT 0x80 para hacer llamadas de sistema).

Interrupciones de hardware

Son aquellas interrupciones que se producen como resultado de, por lo general, una operación de
E/S. No son producidas por ninguna instrucción de un programa sino por las señales que emiten los
dispositivos periféricos para indicarle al procesador que necesitan ser atendidos.

Cuando el microprocesador accede a un periférico (disco duro, puerto de comunicación.), puede


transcurrir algún tiempo antes de que los datos sean obtenidos o transmitidos. La solución más
simple es esperar hasta recibir los datos o hasta que se haya efectuado la transmisión (polling), pero
esta solución bloquea todos los programas en ejecución, y eso no puede admitirse en un sistema
multitarea. Por ello, en los sistemas modernos se prefiere un funcionamiento mediante
interrupciones, ya que éstas permiten mejorar la productividad del procesador, de forma que este
último puede ordenar una operación de entrada o salida y, en lugar de tener que realizar una espera
activa, se puede dedicar a atender a otro proceso o aplicación hasta que el dispositivo esté de nuevo
disponible, siendo dicho dispositivo el encargado de notificar al procesador mediante la línea de
interrupción que ya está preparado para continuar o terminar la operación de entrada o salida.

117
Excepciones

Son un tipo de interrupción sincrónica típicamente causada por una condición de error en un
programa, como por ejemplo una división entre 0 o un acceso inválido a memoria en un proceso de
usuario. Normalmente genera un cambio de contexto a modo supervisor para que el sistema
operativo atienda el error. Así pues, las excepciones son un mecanismo de protección que permite
garantizar la integridad de los datos almacenados tanto en el espacio de usuario como en el espacio
kernel. Cuando el Sistema Operativo detecta una excepción intenta solucionarla, pero en caso de
no poder simplemente notificará la condición de error a la aplicación/usuario y abortará la misma.

Interrupciones por software

Interrupciones por software, también denominadas llamadas al sistema son aquellas generadas por
un programa mientras este está ejecutándose. En general, actúan de la siguiente manera:

Un programa en ejecución llega a una instrucción que requiere del sistema operativo para alguna
tarea, por ejemplo, para leer un archivo en el disco duro (cuando un programa necesita un dato
exterior, se detiene y pasa a cumplir con las tareas de recoger ese dato).

En ese momento por tanto llama al sistema y se interrumpe virtualmente hasta recibir respuesta, en
el ejemplo anterior hasta que no se haya leído el disco y el archivo esté en memoria principal.

Durante esa espera las instrucciones que se ejecutarán no serán del programa, sino del sistema
operativo. Una vez este termine su rutina ordenará reanudar la ejecución del programa auto
interrumpido en espera. Por último, la ejecución del programa se reanuda.

Determinación de la dirección de la rutina de servicio de interrupción

Hay dos alternativas para determinar la dirección de la rutina de servicio de interrupción que se debe
ejecutar al recibir una interrupción determinada:

Direcciones fijas

Se hallan cableadas en el procesador y por tanto nunca pueden ser cambiadas. Esto implica que
las RSI siempre estarán en una determinada posición de la memoria.

Direcciones variables por interrupciones vectorizadas

En este grupo se incluyen aquellas que presentan una dirección variable y que, por tanto, no se
halla cableada en el procesador. De esta manera el dispositivo debe dar información acerca de la
localización de la dirección de comienzo de la RSI asociada a dicho periférico.

118
Determinación de la fuente que genera la interrupción

Hay distintas formas de identificar la fuente de una determinada interrupción. La primera alternativa
que se consideró fue asignar una línea (un bit) para cada interrupción, lo cual suponía un gran costo
en cuanto a la relación de número de dispositivos y número de bits usados y a menudo limitaba el
número de dispositivos que se podían conectar.

Por ello, se pensó con posterioridad en que en cada patilla de interrupción debería poder conectarse
más de un dispositivo, debiendo implementar por tanto una metodología que permitiese identificar
de forma unívoca de qué dispositivo se trataba. Para ello hay varias directrices:

Direcciones variables

Hay distintas metodologías de diseño para las interrupciones con direcciones variables. En la
actualidad, las alternativas que son implementadas de manera habitual son las siguientes:

Direccionamiento absoluto

En este caso es el dispositivo o la interfaz del dispositivo la encargada de conocer la dirección de la


RSI y de enviarla al procesador para que este pueda localizar dicha subrutina y ejecutarla.

Direccionamiento relativo

El dispositivo solo suministra parte de la dirección de comienzo y es el procesador el encargado de


completarla (añadiendo bits o sumando una determinada cantidad, que siempre será fija).

Esta alternativa tiene una ventaja sobre la anterior y es que permite especificar la dirección de
comienzo con menos bits y por tanto simplifica el diseño.

Ahora bien, tiene una desventaja principal y es que limita el número de dispositivos que podemos
conectar y además ciertos bits de la dirección quedan fijados de forma permanente por la CPU lo
que reduce la capacidad de reubicabilidad de la ISR. Una alternativa que utilizan ciertos
procesadores como el 8080 o el 8085 es que en vez de enviar solamente la dirección de comienzo
de la ISR se envía también el código de la operación de salto (por ejemplo CALL).

Direccionamiento indirecto

También conocida como direccionamiento por interrupciones vectorizadas.

Se mantiene una tabla de vectores de interrupción (direcciones de comienzo de las distintas ISR) y
a cada interrupción se le asocia un número que será el índice por el cual se accederá a la tabla y se
recuperará la información de la dirección de comienzo. Necesita señales de conformidad o

119
handshaking para sincronizar al procesador con la interfaz, ya que esta última tiene que indicarle al
procesador cuando va a enviarle el índice que necesita para buscar el vector de interrupción (INT)
y el procesador deberá enviar otra señal para indicar que se ha reconocido la interrupción (INTA#).

Determinación de la fuente que genera la interrupción

Hay distintas formas de identificar la fuente de una determinada interrupción. La primera alternativa
que se consideró fue asignar una línea (un bit) para cada interrupción, lo cual suponía un gran costo
en cuanto a la relación de número de dispositivos y número de bits usados y a menudo limitaba el
número de dispositivos que se podían conectar. Por ello, se pensó con posterioridad en que en cada
patilla de interrupción debería poder conectarse más de un dispositivo, debiendo implementar por
tanto una metodología que permitiese identificar de forma unívoca de qué dispositivo se trataba.
Para ello hay varias directrices

Polling:

El microprocesador comprueba de manera sistemática todos los dispositivos de manera que


«busca» cuál de ellos fue el que solicitó la interrupción.

Esto tiene una ventaja y es que es barato a nivel de coste hardware ya que el polling se implementa
en software, no obstante, tiene otras desventajas que no podemos olvidar y es que suele ser lento
porque tiene que comprobar en serie todos los dispositivos y establece una prioridad en los
dispositivos (el orden de sondeo) y por tanto puede provocar inanición.

Interrupciones vectorizadas

Como ventajas podemos destacar que suele ser rápido, pero implica un alto costo en el hardware.

Hardware paralelo

Se utiliza un registro de interrupción cuyos bits se controlan de forma independiente por las señales
de petición de interrupción de cada periférico. Según la posición de cada bit en el registro, se
establece la prioridad.

Sistemas de prioridad

El sistema operativo necesita un mecanismo para priorizar las interrupciones y tratar primero las
más urgentes.

Para ello, existen varias alternativas:

Interrupciones simultáneas

120
No tienen por qué ocurrir de manera simultánea, sino que se refiere a que en un momento dado
puede haber varias interrupciones activas.

Interrupciones anidadas

Mientras se está procesando una determinada rutina de servicio de interrupción sucede otra señal
de interrupción.

Inhibición de interrupciones

Se deshabilitan las demás interrupciones mientras se está tratando una.

Interrupciones simultáneas

En este método tenemos dos alternativas:

Una de ellas es que exista algún hardware que tenga como entradas las señales de interrupción y
de cómo salida la interrupción más prioritaria que está activa en ese momento.

Otra alternativa es tener un método de identificación de prioridades distribuida y no generalizada


como en el caso anterior, en este caso tenemos que destacar dos técnicas distintas que se pueden
implementar en la práctica:

Polling

El microprocesador verifica los dispositivos y el orden de sondeo determina la prioridad.

Daisy-chain (conexión en cadena): se puede conectar los distintos dispositivos en cadena, en orden
decreciente de prioridad y por tanto la señal de reconocimiento de interrupción (INTA#) solo será
pasada al siguiente dispositivo en caso de que el anterior (más prioritario) no haya solicitado los
servicios del procesador.

Sin embargo, algo importante es que las señales de interrupción que van al procesador están
conectadas todas a un mismo cable, por tanto, deberemos utilizar alguna técnica especial para que
no se produzca un cortocircuito. Para evitar precisamente que la pista se cortocircuite se utiliza la
técnica del open-collecto o «colector abierto» y consiste en conectar el colector de un transistor a la
pista común (un transistor por cada dispositivo) y por tanto estarán tantos colectores conectados
como dispositivos tengamos (se entiende que son dispositivos que mandan petición de interrupción
al procesador).

Híbrida: mezcla las dos técnicas explicadas anteriormente.

121
Interrupciones anidadas

Existen dos métodos para tratar las interrupciones anidadas.

El primero se basa en inhabilitar las interrupciones mientras se está ejecutando una determinada
RSI. Esto puede realizarlo el hardware de manera automática en algunos procesadores, pero en
otros será el usuario el encargado de deshabilitarlas en caso de que no desee que ninguna otra
interrupción pueda interrumpir el transcurso normal de la rutina de servicio de interrupción. No es
aconsejable deshabilitar las interrupciones durante mucho tiempo ya que esto puede provocar
errores y pérdida de información.

Inhibición de interrupciones

Hay distintas alternativas de inhibición de interrupciones. Como ya hemos visto estas se pueden
hacer de manera automática por el hardware en algunos casos mientras que en otros será el usuario
el encargado de realizarlo por software y esto depende de la arquitectura del procesador que
consideremos. Las distintas opciones son:

Deshabilitar todas las interrupciones. Para esto basta con inhibir el bit del registro de flag dedicado
a las interrupciones.

Deshabilitar al principio de la RSI y activarlas de nuevo al finalizar la misma. Puede ser de manera
automática o por el usuario.

Desactivar solo las interrupciones que tengan menor prioridad que la asociada a la RSI que se está
ejecutando en ese momento.

Deshabilitar de forma selectiva distintos niveles de prioridad de interrupción. Para lo cual se emplean
registros especiales denominados máscaras en el que cada uno de sus bits identifican a un nivel
distinto y modificando su contenido se puede establecer que niveles están activos en ese momento.
Se puede cambiar por el programador.

Ensamblador Interrupciones

Una interrupción es el rompimiento en la secuencia de un programa para ejecutar un programa


especial llamando una rutina de servicio cuya característica principal es que al finalizar regresa al
punto donde se interrumpió el programa.

Dentro de una computadora existen dos clases de interrupciones

Interrupciones por software

122
Son aquellas programadas por el usuario, es decir, el usuario decide cuando y donde ejecutarlas,
generalmente son usadas para realizar entrada y salida.

Interrupciones por hardware

Son aquellas que son provocadas por dispositivos externos al procesador su característica principal
es que no son programadas, esto es, pueden ocurrir en cualquier momento en el programa.

Existen dos clases de interrupciones de este tipo:

Interrupciones por hardware enmascarables

Aquellas en las que el usuario decide si quiere o no ser interrumpido. Interrupciones por hardware
no enmascarables (NMI): Aquellas que siempre Interrumpen al programa.

Las interrupciones por software se ejecutan con ayuda de las instrucciones: INT e IRET, además se
tiene 256 interrupciones: de la 00 a la FF.

Asociado al concepto de interrupción se tiene un área de memoria llamada vector de interrupciones;


la cual contiene las direcciones de las rutinas de servicio de cada interrupción.

Esta área se encuentra en el segmento 0000:0000. Para cada una de las direcciones se utilizan 4
bytes, dos bytes para el segmento y 2 para el desplazamiento. La instrucción INT tipo, realiza las
siguientes tareas

1. Salvar el registro de banderas

2 salvar el IP de la dirección de regreso

3. Salvar el CS de la dirección de regreso

4. Salva los registros

5. Calcula el área donde está la dirección de la rutina de servicio de la siguiente manera: tipo*4, en
el vector de interrupciones.

6. Ejecuta la rutina de servicio.

A su vez, IRET, que regresa de la interrupción, ejecuta lo siguiente:

Desempila los registros.

Desempila la dirección de regreso

Desempila el registro de banderas

123
Salvar el IP de la dirección de regreso.

Salvar el CS de la dirección de regreso

Salva los registros

Calcula el área donde está la dirección de la rutina de servicio de la siguiente manera: tipo*4, en el
vector de interrupciones

Ejecuta la rutina de servicio

A su vez, IRET, que regresa de la interrupción, ejecuta lo siguiente:

1. Desempila los registros.

2. Desempila la dirección de regreso.

3. Desempila el registro de bandera.

Al encender la computadora se ejecuta un programa; llamada rutina iniciadora; que inicia todo el
sistema dicho programa esta almacenado en la memoria ROM, y forma parte del BIOS que es un
conjunto de rutinas básicas para realizar E/S a dispositivos.

Las funciones son:

1. Realiza una prueba de memoria.

2. Inicia el vector de interrupciones.

3. Inicia circuitos de soporte y dispositivos de E/S.

4. Realiza el proceso conocido como el BOOT STRAP que consiste en leer el sector del disco en
memoria, dicho sector contiene un programa que pasará el sistema operativo a la memoria y le
transfiere el control.

Las interrupciones del BIOS siempre están disponibles al usuario, en cambio las del sistema
operativo, sólo si es sistema se ha cargado en memoria. BIOS permite realizar entrada y salida a
dispositivos, el acceso a estas rutinas es también por medio de interrupciones de software y
enviando parámetros a través de los registros.

La interrupción 21h permite leer de teclado, escribir en vídeo, escribir en impresora, leer y escribir
de dispositivo auxiliar, además realizar cambios en el vector de interrupciones, obtener y poner tanto
la fecha como la hora.

124
Manejo de Vídeo

Las computadoras usan los llamados al sistema de vídeo o adaptadores de display, para desplegar
información en la pantalla.

La función de tales adaptadores es conectar la computadora a un monitor. Dichos sistemas están


formados por una serie de circuitos integrados entre los que destacan el controlador de display,
puertos de E/S programables, una ROM generadora de caracteres y una memoria RAM para
mantener la información desplegada.

La función del controlador del display es definir el tipo de pantalla usada, definir y controlar el cursor,
asignar color y generar los caracteres

Los sistemas de vídeo pueden trabajar la pantalla en:

-Modo texto

-Caracteres alfanuméricos

-Modo gráfico

-Despliega puntos

El controlador de display controla al cursor, que nos dice donde se va a escribir el siguiente carácter.
Los caracteres pueden verse como la unión de punto dentro de una matriz para formar el carácter
deseado. En los dos modos de vídeo se tienen dos tipos de resolución: Alta y mediana resolución,
aunque ya no se utiliza la resolución mediana; la resolución, nos brinda mejor imagen. La pantalla
se puede ver como si fuera una matriz de puntos o caracteres.

Cada elemento en la matriz se encuentra almacenado en la memoria RAM del adaptador de vídeo,
de ahí se toma para ser enviado a la pantalla. En modo texto cada elemento ocupa solo 2 bytes,
uno mantiene el código ASCII del carácter y el otro un atributo con el que se desplegará dicho
carácter.

El modo gráfico utiliza 4 bytes, 3 bytes para el color y el cuarto es para el atributo. Atributos:
Background (fondo) y Foreground (frente).

La matriz de vídeo se mapea en memoria por renglones, es decir, primero se almacena el renglón
cero, enseguida el renglón uno y así sucesivamente. Escribir un carácter en vídeo equivale a escribir
en la RAM de vídeo. Todos los sistemas de vídeo tienen RAM para almacenar más de una pantalla;
cada pantalla se distingue por un número y se le conoce como página.

125
Para escribir un carácter en directo a RAM se necesita: Dir(i, j) = Dir_incial_de_vídeo + 80*2*i + j*2.
Si se escribe un carácter de esta forma se le conoce como manejo directo de memoria. Para este
tipo de acceso, se puede utilizar las funciones de la interrupción 10h.

Las formas que se tienen para escribir un carácter son:

-En lenguaje de alto nivel por medio de una instrucción.

-En lenguaje de bajo nivel con la INT 21h del sistema operativo DOS

Con funciones del BIOS con la INT 10h. Con el manejo directo de vídeo metiendo el carácter en
memoria

Manejo de Teclado La interrupción 16h

Sirve para el manejo de teclado, también se manejan por medio de funciones.

El teclado envía un carácter al CPU y lleva el código de barrido (Scan Code) que sólo es un número
y después lo transforma a ASCII. Interrupciones por Hardware En las PC que trabajan con el
procesador, se tienen 2 tipos de interrupciones, como ya se mencionó; las NMI llegan a través de
una línea directamente al procesador y cuando ésta se activa, el CPU provoca una interrupción por
software del tipo 2.

Además, se tienen 8 líneas que reciben las interrupciones enmascarables, también llamadas IRQ
(Interrupt ReQuest), asociada a estas líneas se tiene una bandera IF (Interrupt Flag) para determinar
si se acepta o no las interrupciones. Si IF = 1 entonces IRQ’s están habilitadas Si IF = 0 entonces
IRQ’s deshabilitadas.

Esta bandera se manipula con las instrucciones: STI IF = 1 CLI IF = 0

Las 8 líneas de IRQ llegan directamente al CPU, antes son detenidas por un circuito llamado el
control de interrupciones. La función de este circuito es determinar cuál de las 8 líneas puede entrar
a interrumpir al CPU en caso de provocarse dos o más interrupciones a la vez. Esta determinación
se lleva a cabo en base en dos cosas:

Prioridad

Las IRQ están numeradas: IRQ 0 IRQ 1 IRQ7 Las de más alta prioridad es la IRQ 0 y la de más
baja prioridad es la IRQ 7 Habilitación en el registro de máscaras:

El controlador de interrupciones contiene un registro de máscaras de 8 bits en el que cada bit

126
El registro de máscaras

Se puede leer o escribir en el puerto 21h. Además de que el registro de máscaras habilita o
deshabilita el CPU. El IRQ 0 está conectado a un circuito que es el TIMER. El IRQ 1 está conectado
con una línea al teclado.

El IRQ 6 está conectado a las unidades de disco. Timer (INT 8): Las PC tiene internamente un
circuito que es el Timer, y el cual tiene la función de interrumpir el CPU, un número de veces
determinado por segundo.

Su rutina de servicio tiene la función de actualizar contadores en variables internas de la


computadora para que puedan usarse en la actualización de la fecha y la hora; además de apagar
el motor que mueve el disco si este no es usado, finalmente provoca una interrupción por software,
la INT 1Ch, quien inicialmente puede usarse en rutinas de usuario que requieren sincronización con
el tiempo. El contador empieza con un número y cada pulso que le da el timer, éste se decrementa
y cuando llega a cero entonces el timer, interrumpe y ejecuta la INT 8, sólo en caso de que sea
aceptado por el CPU y después vuelve el contador con el valor inicial. Además, apaga el motor y el
foco de las unidades del disco. Las rutinas de servicio de las interrupciones por hardware deben ser
transparentes al usuario, esto es, deben preservar todos sus registros.

Teclado

El teclado tiene incluido un procesador, cuya función es estar censando continuamente las teclas y
si alguna de ellas se presiona entonces provoca una interrupción IRQ 1 y además le envía al
procesador central a través del puerto 60h, el código de barrido asociado a esa tecla. Entonces se
ejecuta una INT 9, cuya función es leer el código de barrido del puerto y convertirlo a código ASCII,
si es el caso, o bien interpretar el código de barrido para cambiar el estado del teclado. Finalmente,
ambos códigos se colocan en un buffer para que puedan leerse por medio de la INT 16h

Las llamadas de interrupción del BIOS

(Basic Input Output System)

Son una facilidad soportada por el BIOS que los programas DOS, u otro tipo de programas como
cargadores de arranque, así como sistemas operativos usan para acceder al hardware más básico
de un computador PC Compatible (arquitectura x86).

Algunos sistemas operativos también usan el BIOS para probar e inicializar recursos de hardware
durante las primeras etapas del arranque.

127
Estas llamadas pueden verse como parte de la funcionalidad de un sistema operativo implementada
en memoria no volátil por el propio fabricante del computador.

Los sistemas operativos de PC primitivos se apoyaban en estas llamadas para realizar parte de sus
operaciones de entrada/salida. Sin embargo, estas llamadas están implementadas en modo real,
mientras que muchos sistemas operativos ya funcionan en Modo Protegido.

Tales sistemas operativos han de cambiar a modo real antes de realizar la llamada de interrupción
y regresar a modo Protegido después. Linux y las versiones recientes de sistemas Windows ya no
aprovechan estas llamadas e implementan enteramente todo el acceso al hardware en rutinas
propias.

Invocar una interrupción puede hacerse usando la instrucción INT en lenguaje ensamblador de los
procesadores x86. Por ejemplo, para imprimir un carácter a la pantalla usando la interrupción 10h
del BIOS, las siguientes instrucciones deberán ser ejecutadas:

MOV AH, 0Eh ; Imprime carácter en la pantalla

MOV AL, '!' ; carácter a imprimir

INT 10h ; Llamada a las funciones de video del BIOS

Vector de interrupción en Hex

00h CPU: Ejecutado después de un intento de división por cero o cuando un cociente no cabe en
el destino

01h CPU: Ejecutado después de cada instrucción de código de máquina mientras la bandera de
trazado esté activo

02h CPU: NMI. Usado por el Power On Self Test (POST) para errores de memoria

03h CPU: La más baja interrupción no reservada, es usada exclusivamente para depuración, y el
manejador INT 03h siempre es implementado por un programa de depuración

04h CPU: Numeric Overflow. Usualmente causado por la instrucción INTO cuando la bandera de
desbordamiento está activada

05h Ejecutado cuando es presionado Shift-Print Screen, así como cuando la instrucción BOUNDh
detecta una falla de límite

128
06h CPU: Llamada cuando una excepción de opcode indefinido (código inválido). Usualmente
instalado por el sistema operativo

07h CPU: Llamada cuando se intenta usar una instrucción de coma flotante y no está disponible
un coprocesador numérico

08h IRQ0: Implementada por el componente de temporización del sistema; llamado 18,2 veces
por segundo (una cada 55 ms) por el PIC

09h IRQ1: LLamada después de que cada tecla es presionada o soltada (como también durante
el tiempo en que una tecla es mantenida presionada)

0Bh IRQ3: Llamada por los puertos seriales 2 y 4 (COM2 y COM4) cuando es necesaria atención

0Ch IRQ4: Llamada por los puertos seriales 1 y 3 (COM1 y COM3) cuando es necesaria atención

0Dh IRQ5: Llamada por el controlador del disco duro (PC/XT) y el segundo puerto paralelo LPT2
(AT) cuando es necesaria atención

0Eh IRQ6: Llamada por el controlador de disco floppy cuando es necesaria atención

0Fh IRQ7: Llamada por el primer puerto paralelo LPT1 (impresora) cuando es necesaria atención

10h

Servicios de video - Instalado por el BIOS o el sistema operativo; llamado por programas de software

AH Descripción (Ing) Descripción (Esp)

00h Set Video Mode Selecciona modo de vídeo

01h Set Cursor Shape Ajusta forma del cursor

02h Set Cursor Position Ajusta la posición del cursor

03h Get Cursor Position And Shape Lee la posición y la forma del cursor

04h Get Light Pen Position Lee la posición del Light Pen

05h Set Display Page Selecciona la Página de exhibición

06h Clear/Scroll Screen Up Borra la pantalla / Desplazamiento (Scroll) hacia arriba

07h Clear/Scroll Screen Down Borra la pantalla / Desplazamiento (Scroll) hacia abajo

08h Read Character and Attribute at Cursor Lee un carácter y su atributo en la posición del cursor

129
09h Write Character and Attribute at Cursor Escribe un carácter y su atributo en la posición del
cursor

0Ah Write Character at Cursor Escribe un carácter en la posición del cursor

0Bh Set Border Color Ajusta el color del borde de la pantalla

0Eh Write Character in TTY Mode Escribe un carácter en modo TTY

0Fh Get Video Mode Lee el modo de vídeo

13h Write String Escribe un string

11h Instalado por el BIOS; retorna la lista del equipo instalado

12h Instalado por el BIOS o el sistema operativo; retorna el tamaño de la memoria convencional

13h Servicios de disco de bajo nivel; instalado por el BIOS o el sistema operativo; llamado por
programas de software

AH Descripción (Ing) Descripción (Esp)

00h Reset Disk Drives Reinicia las unidades de disco

01h Check Drive Status Chequea el estado de las unidades

02h Read Sectors From Drive Lee sectores desde la unidad

03h Write Sectors To Drive Escribe sectores hacia la unidad

04h Verify Sectors On Drive Verifica sectores en la unidad

05h Format Track On Drive Formatea una pista en la unidad

08h Get Drive Parameters Lee los parámetros de la unidad

09h Init Fixed Drive Parameters Inicia los parámetros de la unidad fija (disco duro)

0Ch Seek To Specified Track Hace un Seek a la pista especificada

0Dh Reset Fixed Disk Controller Reinicia el controlador de la unidad fija

15h Get Drive Type Lee el tipo de la unidad

16h Get Floppy Drive Media Change Status Lee el estado de cambio del medio de la unidad
floppy

130
14h Rutinas para la comunicación vía el puerto serial. Usado por programas de software

AH Descripción (Ing) Descripción (Esp)

00h Serial Port Initialization Inicialización del puerto serial

01h Transmit Character Transmite carácter

02h Receive Character Recibe carácter

03h Status Estado

15h Misceláneas (Rutinas de soporte para servicios del sistema)

AH AL Descripción (Ing) Descripción (Esp)

4Fh Keyboard Intercept Intercepta el teclado

83h Event Wait Espera evento

84h Read Joystick Lee el Joystick

85h Sysreq Key Callout

86h Wait Espera

87h Move Block

88h Get Extended Memory Size Lee el tamaño de la memoria extendida

C0h Get System Parameters Lee los parámetros del sistema

C1h Get Extended BIOS Data Area Segment Lee el segmento del área de datos extendida
del BIOS

C2h Pointing Device Functions Funciones del dispositivo apuntador

E8h 01h Get Extended Memory Size (Newer function, since 1994). Gives results for memory
size above 64 Mb. Lee el tamaño de la memoria extendida

E8h 20h Query System Address Map. The information returned from e820 supersedes what is
returned from the older AX=E801hh and AH=88hh interfaces. Información sobre el Mapa de
memoria del sistema

16h Implementado por el BIOS o el sistema operativo. Provee rutinas a ser llamadas por programas
de software que se comunican con el teclado

131
AH Descripción (Ing) Descripción (Esp)

00h Read Character Lee carácter

01h Read Input Status Lee el estado de entrada

02h Read Keyboard Shift Status Lee el estado de las teclas de desplazamiento (SHIFT,
CTRL, ALT)

10h Read Character Extended Lee el carácter extendido

11h Read Input Status Extended Lee el estado de entrada extendido

12h Read Keyboard Shift Status Extended Lee el estado de las teclas de desplazamiento
extendido. Servicios de Impresora - Usado por los programas de software para comunicarse con la
impresora

AH Descripción (Ing) Descripción (Esp)

00h Print Character to Printer Imprime un carácter a la impresora

01h Initialize Printer Inicializa la impresora

02h Check Printer Status Lee el estado de la impresora

Ejecuta el IBM ROM BASIC: Los computadores personales de originales de IBM contienen el BASIC
en ROM para ser ejecutado por esta rutina en el evento de una falla en la carga (boot). LLamado
por el BIOS

19h Boot Strap Loader. Después del POST, esta interrupción es usada por el BIOS para cargar
el sistema operativo

1Ah Servicios del Real Time Clock (RTC) (Reloj de Tiempo Real) - Llamado por programas de
software para comunicarse con el RTC

AH Descripción

00h Lee el RTC

01h Ajusta el RTC

02h Lee la hora del RTC

03h Ajusta la hora del RTC

132
04h Lee la fecha del RTC

05h Ajusta la fecha del RTC

06h Ajusta la alarma RTC

07h Resetea la alarma del RTC

1Bh Instalado por el sistema operativo; automáticamente llamado por INT 9h cuando ha sido
presionado Ctrl-Break

1Ch Llamado automáticamente por INT 08h; disponible para el uso por programas de software
cuando una rutina necesita ser ejecutada regularmente

1Dh No debe ser llamado; simplemente un puntero para la Tabla de Parámetros del Video (VPT),
que contiene datos sobre modos de video

1Eh No debe ser llamado; simplemente un puntero para la Tabla de Parámetros del Disquete
(DPT), conteniendo una variedad de información concerniente a las unidades de disquete

1Fh No debe ser llamado; simplemente un puntero para Tabla la Tabla de Caracteres de Gráficos
de Video (VGCT), que contiene los datos para los caracteres ASCII 80h a FFh

41h Puntero de dirección: Tabla de Parámetros del Disco Fijo (FDPT) (Primera unidad de disco)

46h Puntero de dirección: Tabla de Parámetros del Disco Fijo (FDPT) (Segunda unidad de disco)

4Ah Llamado por el RTC para alarma

70h IRQ8: Llamado por el RTC

74h IRQ12: Llamado por el ratón

75h IRQ13: Llamado por el coprocesador matemático

76h IRQ14: Llamado por el controlador IDE primario

77h IRQ15: Llamado por el controlador IDE secundario

El IBMBIO.COM del PC DOS, y el su equivalente, el IO.SYS del MS-DOS, se enganchaban (hook)


al INT 13 para la detección del cambio del disco floppy, llamadas para formateo de pistas, corregir
errores de límites en el DMA, trabajar alrededor de problemas en el IBM PC ROM BIOS del
"01/10/84" que modela el código FC antes de la primera llamada.

133
El vector de interrupción 13 puede apuntar a un hook de software en vez de la rutina en el BIOS,
con el que algunos virus búlgaros son conocidos para usar en contra del software de monitoreo de
virus.1

INT 18h: Ejecuta el BASIC en ROM

El INT 18h tradicionalmente saltaba a una implementación de BASIC almacenada en ROM, el


Cassette BASIC. Esta llamada típicamente sería invocada si el BIOS no podía identificar ningún
volumen booteable en el inicio. (En el momento en que el IBM PC fue lanzado, en 1981, el BASIC
en ROM fue una característica clave).

A medida que el tiempo pasó y el BASIC ya no fue despachado en todos los PC, esta interrupción
simplemente exhibiría un mensaje de error indicando que no fue encontrado ningún dispositivo
booteable (el famoso "No ROM BASIC", o un mensaje más explicativo en versiones posteriores del
BIOS). En otras versiones del BIOS se solicitaba al usuario insertar un volumen booteable y
presionar una tecla, y después que el usuario lo hiciera, retornaría al bootstrap loader para tratar de
cargar de nuevo.

Desde la perspectiva de la informática, un programa de aplicación consiste en una clase de software


que se diseña con el fin de que para el usuario sea más sencilla la concreción de un determinado
trabajo.

Esta particularidad lo distingue del resto de los programas, entre los cuales se pueden citar a los
sistemas operativos (que son los que permiten el funcionamiento de la computadora), los lenguajes
de programación (aquellos que dan las herramientas necesarias para desarrollar los programas
informáticos en general) y las utilidades (pensadas para realizar acciones de mantenimiento y tareas
generales).

El software es el elemento intangible y lógico que forma parte de una computadora. El hardware, en
cambio, es el componente material y físico. Se dice que los sistemas operativos constituyen el lazo
que une al software con el hardware.

Los procesadores de texto, las hojas de cálculo y las bases de datos forman parte de los
denominados programas de aplicación.

Esto demuestra que las aplicaciones informáticas sirven para automatizar tareas como la
contabilidad o la redacción de textos.

134
Cabe destacar que el paquete o suite de oficina más popular a escala internacional es Office, un
producto impulsado por Microsoft.

Esta compañía, fundada en 1975 por Bill Gates y Paul Allen, es la firma de software más grande del
mundo. Su actividad no se agota en los programas de aplicación, sino que la empresa también
desarrolla el sistema operativo más popular: Windows.

En el caso de los procesadores podemos destacar a Microsoft Word, que es el más utilizado
actualmente en todo el mundo y que se caracteriza o define porque le ofrece la posibilidad al usuario
de llevar a cabo la creación, diseño e impresión de documentos textuales de diversa tipología como
pueden ser informes, cartas, redacciones. Microsoft Excel, por su parte, es el programa de
aplicación más extendido en materia de hojas de cálculo.

En multitud de empresas de distinta índole, y también a nivel personal, se opta por hacer uso de
dicho software que se utiliza frecuentemente en lo que son labores de tipo contable y financiero. En
materia de las bases de datos, hay que destacar como programación de aplicación a Access que
está diseñado tanto para poder trabajar con aquellas en el ámbito profesional como en el más
personal.

Gracias al mismo se pueden desarrollar desde tablas para guardar los datos pertinentes hasta
consultas para recuperar cierta información pasando por formularios para actualizar aquellos o los
informes que se utilizan para llevar a cabo la impresión de los datos que se estimen oportunos.

No obstante, no podemos pasar por alto que estos tres programas pertenecientes a Microsoft tienen
un importante rival desde hace algún tiempo: OpenOffice. Y es que es una llamada “suite
informática” de tipo libre que cuenta con una serie de aplicaciones que permiten realizar las mismas
tareas que aquellos nos ofrecen.

En concreto los rivales serían OpenOffice Writer como procesador de textos, OpenOffice Calc como
hojas de cálculo y OpenOffice Base que funciona como base de datos.

En ocasiones, los programas de aplicación son diseñados a medida, es decir, según las
necesidades y pretensiones de cada usuario, por eso, el software permite resolver dificultades
específicas. En otros casos, se trata de paquetes integrados que solucionan problemas generales
e incluyen múltiples aplicaciones. Por ejemplo, un paquete de oficina combina aplicaciones como
procesadores de textos y hojas de cálculo.

Como se mencionó anteriormente la interfaz para accesar a los servicios de DOS es por medio de
la instrucción INT. Los servicios de DOS, que se accesan con las interrupciones [0x20,0x3f]. La

135
interrupción 0x21 es la fuente principal de los servicios de MS-DOS. Las funciones de la interrupción
0x21 se llaman colocando el número de la función deseada en el registro del procesador AH,
colocando cualquier parámetro necesario en los demás registros y ejecutando la insterrupción 0x21.

Los servicios que da esta interrupción se muestran en la tabla

Servicios de la interrupción 0x21

Servicio Acción

0x00 Termina Programa.

0x01 Entrada de Teclado

0x02 Salida de carácter a video

0x03 Entrada por el dispositivo Aux. estándar

0x04 Salida por el dispositivo Aux. estándar

0x05 Salida a impresora

0x06 Consola E/S

0x07 Entrada de consola sin eco

0x08 Entrada de consola sin eco sin checar ^C

0x09 Imprime cadena

0x0A Lee cadena

0x0B Checa el estado de la entrada

0x0C Limpia el buffer del teclado e invoca el servicio

0x0D Reset del disco

0x0E Selecciona disco

0x0F Abre archivo existente

0x10 Cierra archivo

0x11 Busca el primer archivo con algún atributo en el nombre

0x12 Busca el siguiente archivo con algún atributo en el nombre

136
0x13 Borra archivos

0x14 Lectura secuencial

0x15 Escritura secuencial

0x16 Crea archivo

0x17 Renombra archivo

0x18 Servicio interno de DOS

0x19 Busca el disco actual

0x1A Habilita una localidad DTA

0x1B Información FAT del disco por omisión

0x1C Información FAT de un disco específico

0x1D - 0x20 Servicio interno de DOS

0x21 Lectura aleatoria

0x22 Escritura aleatoria

0x23 Tamaño de archivo

0x24 Habilita un campo de registro aleatorio

0x25 Habilita nueva dirección en el vector de interrupciones

0x26 Crea un nuevo PSP

0x27 Lectura de bloque aleatoria

0x28 Escritura de bloque aleatoria

0x29 Busca el nombre de archivo

0x2A Obtiene la fecha

0x2B Actualiza la fecha

0x2C Obtiene la hora

0x2D Actualiza la hora

137
0x2E Habilita o inicializa el switch verify

0x2F Obtiene el DTA actual

0x30 Obtiene el número de versión de DOS

0x31 Termina un proceso y lo mantiene residente

0x32 Servicio interno de DOS

0x33 Checa por ^BREAK

0x34 Servicio interno de DOS

0x35 Obtiene una dirección del vector de interrupciones

0x36 Obtiene el espacio libre en disco

0x37 Servicio interno de DOS

0x38 Regresa la información dependiente a un país

0x39 Crea un subdirectorio

0x3A Borra un subdirectorio

0x3B Cambia de directorio actual

0x3C Crea un archivo

0x3D Abre un archivo

0x3E Cierra un manejador de archivo

0x3F Lee de un archivo o dispositivo

0x40 Escribe a un archivo o dispositivo

0x41 Borra un archivo

0x42 Mueve apuntador de lectura / escritura

0x43 Cambia los atributos de un archivo

0x44 Control de E/S

0x45 Duplica un manejador de archivo

138
0x46 Forza la duplicación de un manejador de archivo

0x47 Obtiene el directorio actual en una unidad de disco específico

0x48 Asigna memoria

0x49 Libera memoria asignada

0x4A Habilita Bloque

0x4B Carga o ejecuta un programa

0x4C Salir (este servicio puede terminar un programa)

0x4D Obtiene el código de regreso de un subproceso

0x4E Encuentra el primer archivo con algún atributo en el nombre

0x4F Encuentra el siguiente archivo con algún atributo en el nombre

0x50 - 0x53 Servicio interno de DOS

0x54 Obtiene estado de verificación

0x55 Servicio interno de DOS

0x56 Renombre archivo

0x57 Obtiene o actualiza la fecha y hora de un archivo

0x58 Servicio interno de DOS

0x59 Obtiene error extendido de DOS 3+

0x5A Crea un archivo sencillo DOS 3+

0x5B Crea un nuevo archivo DOS 3+

0x5C Acceso a un archivo DOS 3+

0x5E00 Obtiene el nombre de una máquina DOS 3+

0x5E02 Habilita impresora para DOS 3+

0x5E03 Obtiene impresora para DOS 3+

0x5F03 Redirecciona un servicio de DOS 3+

139
0x5F04 Cancela la redirección DOS 3+

0x62 Obtiene el segmento de un programa DOS 3+

0x67 Habilita manejador de contador DOS 3.30

0x68 Asigna archivo DOS 3.30

El sistema básico de entrada-salida o BIOS (del inglés Basic Input/Output System) es un estándar
de facto que define la interfaz de firmware para computadoras IBM PC compatibles1. También es
conocido como BIOS del sistema, ROM BIOS y BIOS de PC. El nombre se originó en 1975, en el
BIOS usado por el sistema operativo CP/M.2

El firmware del BIOS es instalado dentro de la computadora personal (PC), y es el primer programa
que se ejecuta cuando se enciende la computadora.

El propósito fundamental del BIOS es iniciar, y probar el hardware del sistema y cargar un gestor de
arranque o un sistema operativo desde un dispositivo de almacenamiento de datos. Además, el
BIOS provee una capa de abstracción para el hardware, por ejemplo, que consiste en una vía para
que los programas de aplicaciones y los sistemas operativos interactúen con el teclado, el monitor
y otros dispositivos de entrada/salida.

Las variaciones que ocurren en el hardware del sistema quedan ocultas por el BIOS, ya que los
programas usan servicios de BIOS en lugar de acceder directamente al hardware. Los sistemas
operativos modernos ignoran la capa de abstracción provista por el BIOS y acceden al hardware
directamente.

El BIOS del PC/XT de IBM original no tenía interfaz interactiva con el usuario. Los mensajes de error
eran mostrados en la pantalla, o codificados por medio de una serie de sonidos. Las opciones en la
PC y el XT se establecían por medio de interruptores y jumpers en la placa base y en las placas de
los periféricos. Las modernas computadoras compatibles Wintel proveen una rutina de
configuración, accesible al iniciar el sistema mediante una secuencia de teclas específica. El usuario
puede configurar las opciones del sistema usando el teclado y el monitor.

El software del BIOS es almacenado en un circuito integrado de memoria ROM no volátil en la placa
base. Está específicamente diseñado para trabajar con cada modelo de computadora en particular,
interconectando los diversos dispositivos que componen el conjunto de chips complementarios del
sistema.

140
En computadoras modernas, el BIOS está almacenado en una memoria flash, por lo que su
contenido puede ser reescrito sin retirar el circuito integrado de la placa base. Esto permite que el
BIOS sea fácil de actualizar para agregar nuevas características o corregir errores, pero puede hacer
que la computadora sea vulnerable a los rootkit de BIOS.

El MS-DOS (PC DOS) fue el sistema operativo de PC dominante desde principios de la década de
1980 hasta mediados de la década de 1990. Dependía de los servicios del BIOS para las funciones
de disco, teclado y visualización de textos. Windows NT, Linux y otros sistemas operativos de modo
protegido en general no lo usan después de cargarse en memoria.

La tecnología de BIOS está en un proceso de transición hacia la interfaz de firmware extensible


unificada (UEFI) desde el año 2010.3

El sistema básico de entrada-salida o BIOS (del inglés Basic Input/Output System) es un estándar
de facto que define la interfaz de firmware para computadoras IBM PC compatibles1. También es
conocido como BIOS del sistema, ROM BIOS y BIOS de PC. El nombre se originó en 1975, en el
BIOS usado por el sistema operativo CP/M.2

El firmware del BIOS es instalado dentro de la computadora personal (PC), y es el primer programa
que se ejecuta cuando se enciende la computadora.

El propósito fundamental del BIOS es iniciar, y probar el hardware del sistema y cargar un gestor de
arranque o un sistema operativo desde un dispositivo de almacenamiento de datos. Además, el
BIOS provee una capa de abstracción para el hardware, por ejemplo, que consiste en una vía para
que los programas de aplicaciones y los sistemas operativos interactúen con el teclado, el monitor
y otros dispositivos de entrada/salida.

Las variaciones que ocurren en el hardware del sistema quedan ocultas por el BIOS, ya que los
programas usan servicios de BIOS en lugar de acceder directamente al hardware. Los sistemas
operativos modernos ignoran la capa de abstracción provista por el BIOS y acceden al hardware
directamente.

El BIOS del PC/XT de IBM original no tenía interfaz interactiva con el usuario.

Los mensajes de error eran mostrados en la pantalla, o codificados por medio de una serie de
sonidos. Las opciones en la PC y el XT se establecían por medio de interruptores y jumpers en la
placa base y en las placas de los periféricos. Las modernas computadoras compatibles Wintel
proveen una rutina de configuración, accesible al iniciar el sistema mediante una secuencia de teclas
específica.

141
El usuario puede configurar las opciones del sistema usando el teclado y el monitor.

El software del BIOS es almacenado en un circuito integrado de memoria ROM no volátil en la placa
base. Está específicamente diseñado para trabajar con cada modelo de computadora en particular,
interconectando los diversos dispositivos que componen el conjunto de chips complementarios del
sistema.

En computadoras modernas, el BIOS está almacenado en una memoria flash, por lo que su
contenido puede ser reescrito sin retirar el circuito integrado de la placa base. Esto permite que el
BIOS sea fácil de actualizar para agregar nuevas características o corregir errores, pero puede hacer
que la computadora sea vulnerable a los rootkit de BIOS.

El MS-DOS (PC DOS) fue el sistema operativo de PC dominante desde principios de la década de
1980 hasta mediados de la década de 1990.

Dependía de los servicios del BIOS para las funciones de disco, teclado y visualización de textos.
Windows NT, Linux y otros sistemas operativos de modo protegido en general no lo usan después
de cargarse en memoria. La tecnología de BIOS está en un proceso de transición hacia la interfaz
de firmware extensible unificada (UEFI) desde el año 2010.3

El acrónimo BIOS fue inventado por Gary Kildall4 y apareció por primera vez en 1975 en el sistema
operativo CP/M56 describiendo la parte específica de la máquina del CP/M cargado durante el
arranque que interactúa directamente con el hardware2 (por lo general, una máquina de CP/M solo
tiene un simple arranque en su ROM).

Las versiones de MS-DOS o PC DOS contienen un archivo denominado bajo alguno de los
siguientes nombres: IO.SYS, IBMBIO.COM, IBMBIO.SYS, o DRBIOS.SYS. Este archivo se conoce
como el BIOS DOS o Sistema I/O DOS, y contiene la parte de hardware específico de bajo nivel del
sistema operativo. Junto con el hardware específico, pero independiente del BIOS del sistema
subyacente al sistema operativo que reside en la memoria ROM, este representa el análogo al CP/M
BIOS.

En otros tipos de computadoras, se emplean en su lugar los términos monitor de arranque, gestor
de arranque, y ROM de arranque. Algunos equipos basados en PowerPC y Sun utilizan Open
Firmware para este propósito. Con la introducción de las máquinas PS/2, IBM dividió el sistema
BIOS en porciones en modo real y modo protegido. La porción de modo real estaba destinada a
proporcionar retrocompatibilidad con los sistemas operativos como DOS, y por lo tanto fue
nombrado CBIOS (para compatibilidad del BIOS), mientras que el ABIOS (por Advanced BIOS)

142
proporcionaba nuevas interfaces adaptadas específicamente para sistemas operativos multitarea
como OS/2.

Hay algunas alternativas a la funcionalidad de la legacy BIOS en el mundo x86: Extensible Firmware
Interface, Open Firmware (usado en la OLPC XO-1), y Coreboot.

FUNCIONAMIENTO

Cuando se reinicia el procesador x86, se carga el contador de programa con una dirección fija en la
parte superior del espacio de direccionamiento en modo real de 1 megabyte. La dirección de la
memoria del BIOS está situada de tal manera que se ejecutará cuando el equipo se pone en marcha
primero.

Entonces, una instrucción de salto dirige el procesador para iniciar la ejecución de código en el
BIOS. Si el sistema acaba de ser encendido o el botón de reinicio fue presionado (arranque en frío),
se ejecuta completamente la autoprueba de encendido (POST). Si se inició Ctrl+Alt+Supr ("arranque
en caliente"), se detecta un valor de indicador especial en la memoria no volátil (NVRAM) y la BIOS
no ejecuta el POST. Esto ahorra un tiempo que es utilizado para detectar y probar toda la memoria.
La NVRAM está en el reloj en tiempo real (RTC).

El indicador de pruebas de autodiagnóstico identifica e inicializa los dispositivos del sistema, como
la CPU, la RAM, interruptores y controladores DMA y otras partes del chipset, tarjeta de vídeo,
teclado, unidad de disco duro, unidad de disco óptico y otro hardware básico. La BIOS localiza el
software gestor de arranque localizado en un dispositivo almacenamiento designado como
dispositivo de arranque, tal como un disco duro, un disquete, CD o DVD, carga y ejecuta ese
software, dándole el control del PC. Este proceso se conoce como arranque o secuencia de
arranque.

ACTUALIZACIÓN FIRMWARE

Para una referencia de placa base el fabricante puede publicar varias revisiones del BIOS, en las
cuales se solucionan problemas detectados en los primeros lotes, se codifican mejores
controladores o se da soporte a nuevos procesadores. La actualización de este firmware puede ser
realizado con algún programa para quemar una nueva versión directamente desde el sistema
operativo, los programas son propietarios de cada compañía desarrolladora del firmware y por lo
general pueden conseguirse en internet junto al BIOS propiamente dicho.

143
La actualización del BIOS es percibida como no exenta de riesgos, dado que un fallo en el
procedimiento conduce a que la placa base no arranque. Debido a ello algunos fabricantes usan
sistemas como el bloqueo de arranque, que es una porción de BIOS que está protegida y que no es
actualizable a diferencia del resto del firmware.

OVERCLOCKING

Algunos chips de BIOS permiten el overclocking, una acción en el que la CPU se ajusta a una
velocidad de reloj más alta que su ajuste de fábrica.

De manera previsora, es altamente recomendable realizar la implementación de un sistema de


refrigeración y control de temperatura correcto y confiable que asegure la preservación de la
integridad estructural de los componentes electrónicos que serán afectados por la acción del
overclocking, incluyendo la protección de componentes como el bus, chips y múltiples dispositivos
electrónicos adicionales, considerando la regla de proporcionalidad descrita como el Efecto Joule:
"la cantidad de calor producido por un alambre (conductor eléctrico), es proporcional al cuadrado de
la corriente que pasa a través del alambre conductor, multiplicado por la resistencia eléctrica del
mismo." El overclocking podría comprometer seriamente la confiabilidad del sistema en
computadoras insuficientemente refrigeradas y provocar la reducción de la vida útil de sus
componentes.

De realizarse correctamente, el overclocking puede asegurar la integridad estructural e incremento


en el rendimiento de los componentes electrónicos en la placa base, de otro modo podría ocasionar
el sobrecalentamiento de los componentes y su autodestrucción instantánea.

FIRMWARE EN TARJETAS ADAPTADORAS

Un sistema puede contener diversos chips con firmware BIOS además del que existe en la placa
base: tarjetas de vídeo, de red y otras cargan trozos de código en la memoria (con ayuda de la BIOS
principal) que permite el funcionamiento de esos dispositivos. El BIOS de video es visible como un
integrado separado.

TARJETAS DE VÍDEO

A diferencia de otros componentes del sistema, la tarjeta de vídeo debe funcionar desde el arranque
inicial, mucho antes de que cualquier sistema operativo esté siendo cargado en la memoria RAM:

144
en los sistemas con vídeo integrado, el BIOS de la placa base contiene las rutinas necesarias para
hacer funcionar el vídeo de la placa.

Los primeros ordenadores (que no poseían vídeo integrado) tenían BIOS capaces de controlar
cualquier tarjeta adaptadora MDA y CGA. En 1984 cuando aparecieron sistemas nuevos como el
EGA fue necesario agregar una BIOS de vídeo para mantener la compatibilidad con esos sistemas
que no tenían las rutinas de manejo para el nuevo estándar; desde esa época las tarjetas de vídeo
incluyen un firmware propio.

El BIOS de estas adaptadoras provee herramientas básicas para manejar el hardware de vídeo que
ofrece la tarjeta. Cuando el computador inicia, algunas de esas tarjetas muestran en pantalla la
marca de esta, el modelo y la versión del firmware además del tamaño de la memoria de vídeo.

MERCADO DE LOS BIOS

La gran mayoría de los proveedores de placas base de arquitectura x86 delegan a terceros la
producción de los BIOS. Los fabricantes suelen escribir y publicar actualizaciones del firmware en
las cuales se corrigen problemas o se da compatibilidad a nuevos productos. Los principales
proveedores de BIOS son American Megatrends (AMI) y Phoenix Technologies (que compró Award
Software International en 1998). Existen proyectos de BIOS bajo el esquema de Software libre, como
Coreboot, que ofrecen firmwares alternativos para unas pocas referencias de placas base.

ALTERNATIVAS Y SUCESORES

Para obtener software comparable en otros sistemas informáticos, consulte Arranque (informática).
La Unified Extensible Firmware Interface (UEFI) complementa el BIOS en muchas máquinas
nuevas. Inicialmente escrito para la Arquitectura Intel Itanium, UEFI ahora está disponible para
plataformas de arquitectura x86 y ARM; el desarrollo de especificaciones está dirigido por el Unified
EFI Forum, un grupo de interés especial de la industria.

El arranque EFI solo ha sido compatible con las versiones de Microsoft Windows compatibles con
la Tabla de particiones GUID,7 el Núcleo Linux 2.6.1 y posteriores, y macOS en Mac basados en
Intel.8 A partir de 2014, el nuevo hardware de PC se envía predominantemente con firmware UEFI.

La arquitectura de protección de rootkit también puede evitar que el sistema ejecute los cambios de
software propios del usuario, lo que hace que UEFI sea controvertido como un reemplazo de BIOS
heredado en la comunidad de Hardware libre. Además, Windows 11 requiere UEFI para arrancar.

145
CONTENIDOS

• Carcasas y Fuentes de Alimentación


• Placa Base Microprocesadores
• Buses y Tarjetas de Expansión
• Discos Duros y Ópticos
• E/S 4
• Periféricos 3 UA 2.3.1 – BIOS
• BIOS
• Memorias
• Almacenamiento: Discos Duros y Ópticos

BIOS

BIOS (Sistema básico de entradas y salidas, del inglés “Basic Input/Output System“) es un
componente esencial que se usa para controlar el hardware.

Es un pequeño programa, que se carga en la ROM (Memoria de sólo lectura), tipo de memoria que
no puede modificarse y en la EEPROM (Memoria de sólo lectura que es programable y que puede
borrarse eléctricamente). De allí proviene el término “flasher”, que designa la acción de modificar el
EEPROM. Al ser una memoria, contiene dos tipos de software. El POST y el SETUP. 5 UA 2.3.1 –
BIO que se carga en la ROM (Memoria de sólo lectura), tipo de memoria que no puede modificarse
y en la EEPROM (Memoria de sólo lectura que es programable y que puede borrarse eléctricamente

Es un pequeño programa). De allí proviene el término “flasher”, que designa la acción de modificar
el EEPROM. Al ser una memoria, contiene dos tipos de software. El POST y el SETUP.

PASOS DE PROCESO DE CARGA DE LA BIOS 6 UA 2.3.1 – BIOS

Los pasos que realiza la BIOS para el encendido y carga del Sistema Operativo son:

1) Se Inicia la BIOS y se ejecuta la prueba de encendido (POST), así como los recursos asignados.

2) La ROM de la BIOS, inicia la búsqueda de los programas y carga el Sistema Operativo.

3) El Sistema Operativo se configura y completa su propia carga de Software.

146
4) La Aplicación está cargada y ejecutándose

Cuando se enciende o se restablece un sistema informático, el BIOS realiza un “inventario del


hardware” conectado al ordenador y efectúa un diagnóstico llamado Prueba automática en el
encendido (POST, Power-On Self Test) para comprobar que el equipo funciona correctamente.

Las funciones que realiza son:

• Efectuar una prueba del procesador (CPU)


• Verificar el BIOS
• Verificar la configuración del CMOS
• Inicializar el temporizador (reloj interno)
• Inicializar el controlador de DMA (Acceso Directo Memoria
• Verificar la memoria RAM y la memoria caché
• Instalar todas las funciones del BIOS
• Verificar todas las configuraciones (como por ejemplo teclado, unidades de disco y discos
rígidos)

Si en algún momento el POST encuentra un error, intentará continuar con el inicio del ordenador.

Sin embargo, si el error es serio, el BIOS detendrá la carga del sistema y hará una de las siguientes
acciones. De ser posible, mostrará un mensaje en la pantalla (porque el dispositivo puede no haber
sido inicializado o puede presentar errores)

Emitirá una secuencia de sonidos que permite diagnosticar el origen del error. Enviará un código
(denominado código POST) al puerto serial del ordenador, que puede recuperarse a través de
hardware especial de diagnósticos. Si no hay problemas, la BIOS emitirá un sonido corto para
informar que no hay errores. Para simplificar los códigos de sonidos, podemos decir que se
producen 2 tipos de sonidos muy característicos independientemente del tipo de fabricante de BIOS:
RAM por lo que será necesario retirarlos los módulos, limpiarlos (usar una goma de borrar sobre los
contactos metálicos) y probarlos uno a uno en cada una de las ranuras de memoria de la Placa
Base. Suele ser más fiable probar cada módulo de memoria en otro PC para detectar el módulo
defectuoso o sospechar que el problema reside en la propia placa base.

TARJETA GRÁFICA

Si los pitidos son una secuencia melódica y no se repiten, seguramente el problema resida en la
tarjeta gráfica, especialmente si ésta es AGP, que suelen desplazarse fruto de la dilatación de los

147
metales en sus contactos. En este caso, retiraremos la tarjeta, limpiaremos los contactos también
con una goma de borrar y la probaremos de nuevo. Si es necesario probarla en otra placa base. Los
Mac también informan de fallos mediante la BIOS. La musiquita que se reproduce cuando inicias un
Mac, se corresponde con el pitido de la BIOS en el resto de los ordenadores.

Sin embargo, no tienen una larga lista de error: si se reproducen dos tonos diferentes tu Mac te
advierte de que hay un problema con la placa base o el bus SCSI. SETUP: Configuración de la BIOS
10 UA 2.3.1 – BIOS

La mayoría de los BIOS tienen un programa de configuración que permite modificar la configuración
básica del sistema. Este tipo de información se almacena en una memoria CMOS o RAM-CMOS,
autoalimentada (por medio de una batería), para que la información permanezca almacenada
incluso si el ordenador se encuentra apagado (la memoria RAM se reinicia cada vez que se inicia el
sistema). Cada equipo cuenta con varios BIOS: El BIOS de la placa base, la BIOS que controla el
teclado y la BIOS de la tarjeta de video. Eventualmente, el BIOS para controladoras SCSI, que se
utiliza para iniciar desde un dispositivo SCSI, el que luego se comunica con el DOS, sin que se
necesite un controlador adicional. (El BIOS de la tarjeta de red para iniciar desde una red).

Cuando se enciende el ordenador, el BIOS muestra un mensaje de copyright en pantalla, luego


realiza los diagnósticos y pruebas pertinentes a la inicialización. Luego de completadas las pruebas,
el BIOS muestra un mensaje en el que se invita al usuario a que presione una o más teclas para
ingresar a la configuración del BIOS. Acceso Configuración BIOS 11 UA 2.3.1 – BIOS

Para acceder a la configuración, se debe de presionar el botón o secuencia de botones durante el


proceso de POST.

Muchos equipos muestran en la pantalla de presentación, como acceder a la Configuración de la


BIOS, sino se pueden utilizar las siguientes opciones según el fabricante: Tecla Supr Tecla Del Tecla
F2 Teclas Ctrl + Alt + Esc Tecla F1 Tecla F10 Teclas Ctrl + Alt + S Partes de la BIOS 12 UA 2.3.1 –
BIO. Las opciones de la BIOS variarán en función del fabricante y de los componentes hardware del
sistema.

Por lo general, son todas muy similares, teniendo una estructura donde la pantalla de inicio estará
dividida en pestañas y opciones que indican sus características de uso y ayuda. Partes de la BIOS
13 UA 2.3.1 – BIOS

Las opciones más comunes del menú de configuración de la BIOS son:

• Main

148
Configuración básica del sistema: opciones generales (algunas de ellas informativas) y de
configuración de dispositivos de almacenamiento.

• Advanced

Configuración avanzada del sistema: configuración de los puertos, del chipset, etc.

• Boot

Orden de arranque y opciones de dispositivos de arranque: secuencia de arranque después del


POST.

• Security

Configuración de seguridad.

• Power

Configuraciones avanzadas de administración de energía o también de opciones de encendido.

• JUSTw00t!

Configuración avanzada del voltaje y del reloj.

• Exit

Opciones de salida y configuración predeterminada de carga del BIOS (carga de valores por
defecto). Partes de la BIOS 14 UA 2.3.1 – BIO

La información que nos facilita la BIOS puede ayudarnos a saber que equipos son los que están
instalados en nuestro equipo y conocer alguno de sus características principales.

Los componentes más comunes que se muestran en la BIOS son:

• CPU
• RAM
• Discos Duros
• Etc

La BIOS, nos permite personalizar las características de nuestro equipo con el fin de ajustarlo a
nuestras características y sacarlo el mayor rendimiento posible: Overclocking

Por ejemplo: Antes de cambiar nada de la BIOS es importante comprender claramente como estos
cambios pueden afectar a nuestro PC.

149
Configuración de la BIOS: Fecha y Hora 16 UA 2.3.1 – BIOS Campos: System Time y System Data.

Es importante configurar con la hora y fecha correctas, ya que el sistema operativo y otros
programas lo toman como referencia.

Si no se tiene al día, puede provocar problemas de actualización de archivos, perdidas de


recordatorios en Outlook, etc.

Configuración de la BIOS: Deshabilitación de Dispositivos 17 UA 2.3.1 – BIOS

Puede configurar parámetros avanzados del BIOS para deshabilitar dispositivos que no se necesitan
o que el PC no utiliza.

Nota: Si un dispositivo no funciona, se puede revisar en la BIOS si está deshabilitado de manera


predeterminado o se deshabilitó por algún motivo

Configuración de la BIOS: Orden de Arranque 18 UA 2.3.1 – BIOS

Establece el orden de arranque o la secuencia de arranque del Pc en base a una lista ordenada.
Esta lista se encuentra en la ficha Boot del BIOS. En los nuevos PCs, puede venir en la opción
Advanced BIOS Features.

El orden de arranque puede incluir HDD, Unidades Ópticas, Unidades Disquete, Arranque de red y
medios flash. Para permitir el arranque desde una unidad USB, habilite esta opción en el BIOS.

Configuración de la BIOS: Velocidad del Reloj 19 UA 2.3.1 – BIOS

Se puede configurar la BIOS para modificar la velocidad del reloj de la CPU. Con este procedimiento,
podemos aumentar o disminuir la velocidad para que el PC funcione rápidamente pero a una mayor
temperatura, aumentando por lo tanto el rendimiento, o que funcione más lentamente para que tenga
una mayor refrigeración. Aumentar la velocidad del reloj de la CPU por encima de las
recomendaciones del fabricante se conoce como Overclocking

Configuración de la BIOS: Virtualización 20 UA 2.3.1 – BIOS

Para poder utilizar software de virtualización (máquinas virtuales) en las que un programa
informático de virtualización emula las características de un sistema de computación completo,
incluidos el hardware, el BIOS, el sistema operativo y los programas, puede haber BIOS que
habiliten o no esta opción, y para ello haya que realizar el pertinente ajuste en la BIOS

Configuración de la BIOS: Encriptación 21 UA 2.3.1 – BIOS

150
Encriptación de unidades. Se puede encriptar un HDD para evitar el robo de datos. La encriptación
convierte los datos en un código incomprensible, que sin la contraseña correcta, hace que el PC no
pueda arrancar, aunque se coloque en otro PC el HDD, haciendo imposible descifrar los datos.
Módulo de plataforma segura: el chip del módulo de plataforma segura (TPM, Trusted Platform
Module) contiene elementos de seguridad, como claves y contraseñas de encriptación

Configuración de la BIOS:

Encriptación 22 UA 2.3.1 – BIOS

Lojack:

Se trata de un sistema de Absolute Software para proteger el PC, que se divide en dos partes: La
primera parte es un programa denominado Módulo de persistencia, que el fabricante instala en el
BIOS.

La segunda parte es un programa denominado Agente de aplicación, que instala el usuario

Cuando se instala el Agente de aplicación, se activa el Módulo de persistencia.

El Módulo de persistencia instala el Agente de aplicación si se lo elimina del PC. Una vez que se
activa el Módulo de persistencia, no se puede apagar.

El Agente de aplicación llama al Centro de monitorización de Absolute a través de Internet para


informar la ubicación y los datos del dispositivo según un programa establecido. Si roban el PC, el
propietario se puede comunicar con Absolute Software.

Se puede realizar lo siguiente:

Bloquear el PC en forma remota.

Mostrar un mensaje para que puedan devolver el PC perdido al propietario.

Borrar los datos confidenciales del PC.

Usar la geotecnología para localizar el PC.

Configuración de la BIOS

Control de Temperatura 23 UA 2.3.1 – BIOS

Las placas base cuentan con sensores térmicos para controlar el hardware sensible al calor. Un
sensor térmico común se encuentra debajo del socket de la CPU.

151
Este sensor controla la temperatura de la CPU y puede aumentar la velocidad del ventilador de la
CPU para refrigerarla en caso de que se caliente demasiado. Algunas configuraciones del BIOS
también reducen la velocidad de la CPU para disminuir la temperatura de dicho componente. En
algunos casos, el BIOS apaga el PC para evitar que se dañe la CPU.

Otros sensores térmicos controlan la temperatura dentro del gabinete o la fuente de energía.
Además, los sensores térmicos controlan la temperatura de los módulos RAM, los conjuntos de
chips y otro hardware especializado.

El BIOS aumenta la velocidad de los ventiladores o apaga el PC para evitar recalentamiento y daños.

Configuración de la BIOS

Velocidad de los Ventiladores 24 UA 2.3.1 – BIOS

La BIOS controla la velocidad de los ventiladores.

Algunas configuraciones del BIOS permiten configurar perfiles para establecer las velocidades de
los ventiladores a fin de lograr un resultado específico.

Los siguientes son algunos perfiles comunes para la velocidad del ventilador de la

Standard (Estándar)

El ventilador se ajusta de forma automática según la temperatura de la CPU, el gabinete, la fuente


de energía u otro hardware.

Turbo (Turbina)

Máxima velocidad del ventilador.

Silent (Silencioso)

Minimiza la velocidad del ventilador para disminuir el ruido.

Manual

El usuario puede asignar la configuración de control de la velocidad del ventilador

Configuración de la BIOS: Control del Voltaje 25 UA 2.3.1 – BIOS

Es posible controlar el voltaje de la CPU o los reguladores de voltaje de la placa base. Si los voltajes
son demasiado altos o bajos, pueden dañarse los componentes del PC.

152
Si advierte que el voltaje especificado no es correcto o no está cerca del valor correcto, asegúrese
de que la fuente de energía funcione correctamente. Si la fuente de energía envía los voltajes
correctos, es posible que los reguladores de voltaje de la placa base estén dañados.

En ese caso, es posible que se deba reparar o reemplazar la placa base

Configuración de la BIOS: Velocidad de Reloj y BUS 26 UA 2.3.1 – BIOS

En algunas configuraciones del BIOS, se puede controlar la velocidad de la CPU y es posible que
algunas configuraciones del BIOS también permitan controlar uno o más buses.

Posiblemente, deba mirar estos elementos para determinar si un cliente o técnico introdujo en forma
manual la configuración correcta de la CPU, o si el BIOS la detectó en forma automática.

Las velocidades incorrectas de los buses pueden provocar un aumento de la temperatura dentro de
la CPU y en el hardware conectado, o pueden ocasionar que las tarjetas adaptadoras y la RAM no
funcionen correctamente

CONFIGURACIÓN DEL BIOS

Detención de Intrusión 27 UA 2.3.1 – BIOS

Algunas carcasas de PC tienen un interruptor que se activa cuando se abre la carcasa. Es posible
configurar el BIOS para que registre cuándo se activa el interruptor, de modo que el propietario
pueda saber si se manipuló el gabinete. Este interruptor está conectado a la placa base

Control de la BIOS: Diagnóstico 28 UA 2.3.1 – BIOS

Si advierte un problema con un dispositivo conectado al sistema o con una función básica (un
ventilador o con el control de voltaje y temperatura), puede utilizar el diagnóstico incorporado del
sistema para determinar dónde se encuentra el problema. El programa proporciona una descripción
del problema o un código de error para realizar procesos de resolución de problemas adicionales.

Los siguientes son algunos diagnósticos incorporados comunes:

Start test (Prueba de arranque)

Verifica que los componentes principales funcionen correctamente.

Utilice esta prueba cuando el PC no arranque correctamente.

Hard drive test (Prueba de disco duro):

153
Revisa el disco duro para detectar áreas dañadas. Si se encuentran áreas dañadas, esta
herramienta intenta recuperar los datos, trasladarlos a un área en buenas condiciones y marcar el
área dañada como defectuosa para que no se la vuelva a utilizar. Utilice esta prueba si sospecha
que el disco duro no funciona correctamente, si el PC no arranca o si el disco duro emite ruidos
inusuales.

Memory test (Prueba de memoria)

Verifica que los módulos de memoria funcionen correctamente. Utilice esta prueba si el PC se
comporta de manera irregular o no arranca.

Battery test (Prueba de batería)

Verifica que la batería funcione correctamente. Reset de la BIOS 29 UA 2.3.1 – BIOS Si el cambio
en algunas de las configuraciones de la BIOS no produce el efecto deseado o convierte al equipo
en un sistema inestable: Si podemos acceder a la BIOS tendremos que volver a cargar los
parámetros por defecto o de fábrica… hay que buscar la opción Load Default.

Si no podemos acceder a la BIOS debemos detectar en la placa el jumper Clear CMOS ó Clear RTC
RAM (si es una placa ASUS) y seguir las instrucciones del fabricante (apagar equipo, desconectar
fuente de alimentación, mover el jumper de posición durante x segundos, etc…

ACTUALIZACIÓN DEL BIOS 30 UA 2.3.1 – BIOS

La actualización de la BIOS se aconseja que se lleve a cabo para poder usar nuevas funciones del
sistema informático. Es un proceso delicado, cada vez más sencillo, pero debemos tener especial
cuidado a la hora de llevarlo a cabo. Un fallo puede hacer el equipo inservible. Hay que asegurarse
de que el fichero de actualización corresponda al modelo de BIOS del equipo. Algunos modelos de
placa base permiten crear un CD/DVD de arranque con la actualización. En el momento de arranque
se realizará esa actualización. Para los modelos ASUS puede haber varias opciones

CREAR UN CD/DVD CON LA APLICACIÓN ASUS UPDATE AL SUITE II

La Unified Extensible Firmware Interface (UEFI), un nuevo estándar para PCs diseñado para
reemplazar la BIOS. Fue desarrollado en colaboración con más de 140 compañías con el objetivo
de mejorar la interoperabilidad del software y solucionar las limitaciones del BIOS, entre las que se
encuentra la seguridad. Por lo tanto, resulta interesante conocer las diferencias entre BIOS y UEFI
y sus características, para saber cuál es la mejor forma de protegerse

154
CONTROLANDO EL FIRMWARE DEL SISTEMA 32 UA 2.3.1 – BIOS

Para empezar, es importante aclarar que el firmware es una porción de código almacenado en una
en una memoria ROM que se utiliza para establecer las instrucciones que controlan las operaciones
de los circuitos de un dispositivo. Este componente de código va integrado al hardware del
dispositivo, pero puede ser modificado a través de órdenes externas con el objetivo de mantenerlo
actualizado y funcionando de acuerdo con los requerimientos propios del sistema. La función
primordial del BIOS es inicializar los componentes de hardware y lanzar el sistema operativo.
Además, con su carga se inicializan otras funciones de gestión importantes como la energía y la
gestión térmica. Por otra parte, el UEFI se puede cargar en cualquier recurso de memoria no volátil,
lo cual permite que sea independiente de cualquier sistema operativo. Debido a estas
características, posee las mismas funciones que BIOS, pero con características adicionales.

CARACTERÍSTICAS BIOS Y UEFI 33 UA 2.3.1 – BIOS

Dado que la BIOS inicializa el sistema, hay algunas características fundamentales asociadas a su
ejecución:

Puede ejecutar código para verificar la integridad de todos los componentes del firmware antes de
que se ejecute y lance el sistema operativo. Probar los componentes clave de hardware en el
ordenador para garantizar que toda la información cargue correctamente y no genere problemas
sobre la información. Controla módulos adicionales como la tarjeta de vídeo o la tarjeta de red de
área local, entre otros dispositivos. Selecciona el dispositivo de arranque que puede ser el disco
duro, una unidad de CD o un dispositivo USB.

CARACTERÍSTICAS BIOS Y UEFI 34 UA 2.3.1 – BIOS

El proceso de arranque UEFI tiene características similares, pero la diferencia es que el código se
ejecuta en 32 – o 64-bit de modo protegido en la CPU, no en modo de 16 bits como suele ser el
caso de BIOS. En el caso de Windows 8 y superiores, se puede activar el modo UEFI y Secure
Boot,lo cual da un nivel adicional de protección a los sistemas.

Dentro de las características adicionales de UEFI está la reducción en el tiempo de inicio y


reanudación, y cuenta con un proceso que ayuda a prevenir de ataques del tipo bootkit y utilizar el
modo Secure Boot. Estas son algunas de las razones por las cuales UEFI podría reemplazar a BIOS
en el sistema de arranque de los PCs.

155
SEGURIDAD EN BIOS Y UEFI 36 UA 2.3.1 – BIOS

Como la primera porción de código ejecutada por un dispositivo es alguno de estos dos estándares,
deben considerarse como un componente crítico para la seguridad. De hecho, gestionar la
seguridad en la BIOS permite fortalecer el equipo desde el encendido. Dado que se ha detectado
una posible vulnerabilidad que afectaría el modo Secure Boot del UEFI, es importante tener algunas
recomendaciones de seguridad que nos ayudan a elevar los niveles de seguridad en nuestro equipo:

Todos los cambios a BIOS o UEFI deberán utilizar un mecanismo autenticado de actualización o un
mecanismo seguro de actualización local. El mecanismo de actualización local seguro sólo se debe
usar para cargar la primera imagen o para recuperarse de una corrupción en el sistema de arranque.
También garantizará la autenticidad e integridad de la imagen de actualización, especialmente si se
trata de BIOS. Para evitar la modificación no intencional o maliciosa del sistema, deberán estar
protegidos con un mecanismo que no se pueda reemplazar fuera de una actualización autenticada

SEGURIDAD EN BIOS Y UEFI 37 UA 2.3.1 – BIOS.

El mecanismo de actualización será el único capaz de modificar el BIOS del sistema sin necesidad
de intervención física. Al tener presentes estas medidas de seguridad lograremos, independiente
del modelo de arranque utilizado en nuestro dispositivo, que este garantice la integridad de nuestra
información.

Una de las funciones de UEFI, es el Secure Boot, aunque es una característica útil que previene
que algún tipo de malware tome control sobre Windows, también previene que cualquier otro sistema
operativo, como distribuciones de Linux o incluso versiones anteriores de Windows, como Windows
7 o XP, puedan bootear o ser instaladas en el ordenador. Es por esta razón que muchos usuarios
fracasan cuando intentan arrancar desde un disco o pendrive con otro sistema operativo, con la
intención de probarlo o instalarlo en su ordenador.

Windows 8.1 fue diseñado para arrancar rápidamente, tan rápido que no puedes tomar decisiones
antes del arranque como solías hacer para ingresar a las opciones de la BIOS.

Por esta razón Microsoft buscó otras alternativas para que el usuario pueda arrancar la BIOS o al
UEFI. Alternativas nada cómodas y que están escondida bajo un mar de clics y menús que marean
al más diestro

156
EL RELOJ Y PILA CMOS 38 UA 2.3.1 – BIOS

El reloj en tiempo real (o RTC) es un circuito cuya función es la de sincronizar las señales del
sistema. Está constituido por un cristal que, cuando vibra, emite pulsos (denominados pulsos de
temporizador) para mantener los elementos del sistema funcionando al mismo tiempo.

La frecuencia del temporizador (expresada en MHz) no es más que el número de veces que el cristal
vibra por segundo, es decir, el número de pulsos de temporizador por segundo. Cuanto más alta
sea la frecuencia, mayor será la cantidad de información que el sistema pueda procesar

EL RELOJ Y PILA CMOS 39 UA 2.3.1 – BIOS

Cuando se apaga el ordenador, la fuente de alimentación deja inmediatamente de proporcionar


electricidad a la placa base.

Al encender nuevamente el ordenador, el sistema continúa en hora. Un circuito electrónico


denominado CMOS (Semiconductor de óxido metálico complementario), también llamado BIOS
CMOS, conserva algunos datos del sistema, como la hora, la fecha del sistema y algunas
configuraciones esenciales del sistema. El CMOS se alimenta de manera continua gracias a una
pila (pila tipo botón) o bien a una pila ubicada en la placa base.

La información sobre el hardware en el ordenador (como el número de pistas o sectores en cada


disco duro) se almacena directamente en el CMOS. Como el CMOS es un tipo de almacenamiento
lento, en algunos casos, ciertos sistemas suelen proceder al copiado del contenido del CMOS en la
memoria RAM (almacenamiento rápido); el término “memoria shadow” se utiliza para describir este
proceso de copiado de información en la memoria RAM.

EL RELOJ Y PILA CMOS 40 UA 2.3.1 – BIO

Cuando se apaga el ordenador, la fuente de alimentación deja inmediatamente de proporcionar


electricidad a la placa base. Al encender nuevamente el ordenador, el sistema continúa en hora. Un
circuito electrónico denominado CMOS (Semiconductor de óxido metálico complementario), también
llamado BIOS CMOS, conserva algunos datos del sistema, como la hora, la fecha del sistema y
algunas configuraciones esenciales del sistema. El CMOS se alimenta de manera continua gracias
a una pila (pila tipo botón) o bien a una pila ubicada en la placa base.

157
La información sobre el hardware en el ordenador (como el número de pistas o sectores en cada
disco duro) se almacena directamente en el CMOS. Como el CMOS es un tipo de almacenamiento
lento, en algunos casos, ciertos sistemas suelen proceder al copiado del contenido del CMOS en la
memoria RAM (almacenamiento rápido); el término “memoria shadow” se utiliza para describir este
proceso de copiado de información en la memoria RAM.

IMPORTANTE: Cuando la hora del ordenador se reinicia de manera continua o si el reloj se atrasa,
generalmente sólo debe cambiarse la pila.

FABRICANTES DE BIOS 41 UA 2.3.1 – BIOS

Los principales proveedores de BIOS son American Megatrends (AMI) y Phoenix Technologies (que
compró Award Software Internationalen 1998).

158
CONCLUSIÓN
Programar significa tener la habilidad de crear y codificar un algoritmo para que pueda ser ejecutado
por una computadora. Es decir, se desarrollan un conjunto de instrucciones que le indican a la
computadora cómo hacer ciertas tareas. En la actualidad, la programación es catalogada como
un lenguaje tecnológico fundamental.

La programación es fundamental para acrecentar el avance tecnológico dentro de las industrias que
para llevar a cabo sus funciones necesitan de sitios y aplicaciones creadas a partir de los códigos.

No es novedad que vivimos en un mundo computarizado donde la tecnología forma parte de todo
lo que hacemos. Por eso, aprender cómo funciona y saber modificarla será ideal para poder
identificar las necesidades de la sociedad y así abarcarlas a través de la programación. Un ejemplo
para destacar es cómo la tecnología fue el campo que primero se ajustó a las condiciones actuales
del mundo. La pandemia que vivenciamos este 2020 implicó nuevas adaptaciones a nuestra manera
de vivir, surgiendo distintas plataformas o reinventándose las ya existentes. Mantener las clases de
todos los niveles educativos, el trabajo remoto, el crecimiento de las compras online, la telemedicina,
garantizar el entretenimiento, etc. Todas estas variantes representan oportunidades con las que los
programadores se han tenido que enfrentar al comienzo del año para poder ofrecer los servicios
indispensables de una manera diferente y eficiente. Los y las expertas afirman que aprender a
programar también permite el desarrollo de las capacidades como el pensamiento lógico, la
creatividad y el ingenio. Estas se potencian y facilitan la resolución de problemas y la automatización
de tareas a partir de una computadora. Estas características no solo resultan fructíferas para el
ámbito laboral, sino que pueden aplicarse al crecimiento personal de los individuos.

La demanda no está puesta solo en programadores/as o en especialistas en tecnología, sino en


profesionales que puedan aplicar su pensamiento en distintas áreas de trabajo.

En este punto es imprescindible un mayor compromiso educativo que permita formar a más jóvenes
y adultos en el área IT y así respaldar la creciente demanda laboral.

“APRENDER A PROGRAMAR IMPLICA APRENDER A PENSAR DIFERENTE”

159
BIBLIOGRAFÍA

▪ Quetglás, Gregorio; Toledo Lobo, Francisco; Cerverón Lleó, Vicente (1995). Fundamentos
de informática y programación. Valencia: Editorial V.J.
▪ Wicham, Hadley (2019). Advanced R. Florida: Editorial Chapman and Hall/CRC.
▪ Cerrada Somolinos, José y Collado Machuca, Manuel (2015). Fundamentos De
Programación. Madrid: Editorial Universitaria Ramón Areces.
▪ Casale, Juan Carlos (2012). Introducción a la Programación. Buenos Aires: Editorial Fox
Andina.
▪ Martínez López, Pablo (2013). Las bases conceptuales de la Programación: una nueva
forma de aprender a programar. La Plata: Editorial de la Universidad Nacional de Quilmes.
▪ Ada Lovelace - Wikipedia.
▪ Difference engine - Wikipedia.
▪ Generaciones de las computadoras.
▪ Generaciones de ordenadores.
▪ Historia de la programación - Wikipedia.
▪ Konrad Zuse - people.idsia.ch.
▪ Los huesos de Napier, la multiplicación árabe y tú.
▪ Significado de computación.

160

También podría gustarte