0% encontró este documento útil (0 votos)
69 vistas75 páginas

Notas Programación I

Cargado por

snrocket
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
69 vistas75 páginas

Notas Programación I

Cargado por

snrocket
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

Benemérita Universidad Autónoma de Puebla

Facultad de Ciencias de la Computación

Notas

Materia de Programación I
Profesor

M.C. Yolanda Moyao Martínez

Fecha

Enero 2017

1
Índice
Introducción
Arquitectura functional de una computadora
Componentes de una computadora
Memoria de una computadora
Lenguajes de programación y Traductores
Ensambladores y macroensambladores
Compiladores
Interpretes
Cargadores
Sistema operativo
Programación y pruebas
Técnicas de Programación
Lenguaje c
Identificadores
Palabras reservadas
Estructura de un programa
Elementos Básicos
Datos y expresiones
Estructura secuencial
Estructura selectiva
Estructura de repetición
Arreglos
Funciones
Apuntadores
Archivos

2
Introducción
El lenguaje C es un lenguaje estructurado, en el mismo sentido que lo son otros lenguajes de
programación tales como el lenguaje Pascal, el Ada o el Modula-2, pero no es estructurado por
bloques, o sea, no es posible declarar subrutinas (pequeños trozos de programa) dentro de otras
subrutinas, a diferencia de como sucede con otros lenguajes estructurados tales como el Pascal.
Además, el lenguaje C no es rígido en la comprobación de tipos de datos, permitiendo fácilmente la
conversión entre diferentes tipos de datos y la asignación entre tipos de datos diferentes.
La programación en C tiene una gran facilidad para escribir código compacto y sencillo a su misma
vez. En el lenguaje C no tenemos procedimientos como en otros lenguajes solamente tenemos
funciones los procedimientos los simula y esta terminante mente prohibido escribir funciones ,
procedimientos y los comandos en mayúscula todo se escribe en minúsculas (a no ser las constantes
J ) Los archivos en la C se escriben en texto puro de ASCII del Dos si se escribe en WORD por
ejemplo el mismo incluye muchos códigos no entendidos por el compilador y generara errores ;una
vez escrito se debe pasar a compilar el archivo; los archivos tienen 2 Extensiones archivo.C que es el
archivo a compilar el que contiene todas los procedimientos funciones y código de nuestro programa
yarchivo.h que es las librerías que contienen las funciones de nuestro programa.

3
I. Arquitectura funcional de una computadora

Un Programa es una secuencia ordenada, finita e inequívoca de pasos a seguir para resolver un
determinado problema. Es importante el hecho de que sea una secuencia ordenada porque cuando
queremos resolver un determinado problema, tenemos que efectuar los pasos en un cierto orden a no
ser que queramos obtener un resultado totalmente diferente al esperado. Por ejemplo, en una receta,
que es un algoritmo para preparar un determinado platillo, si se altera el orden de los pasos, es muy
probable que no obtengamos el platillo deseado. Por otro lado, también es importante recalcar que es
una secuencia finita de pasos, ya que un algoritmo debe terminar en algún momento determinado,
ya que de poco nos servirá un algoritmo que resuelva el problema en un tiempo tan largo que no
podamos
Aprovechar los resultados que éste entregue. Existen varias formas de expresar o transmitir un
algoritmo, como se discutirá posteriormente con más amplitud. Por ejemplo, una receta se transmite
por lo general en forma oral, lo cual puede dar lugar a ambigüedades.
Cuando es una computadora la encargada de ejecutar un algoritmo, éste deberá ser expresado en
forma de un programa de computadora, el cual consiste de un conjunto de instrucciones ésta pueda
entender y posteriormente ejecutar. Para esto uno debe usar un lenguaje de programación para
escribir el programa. A la actividad de expresar un algoritmo en forma de programa se le denomina
programación.
A los programas se les denomina empleando el término SOFTWARE, y al equipo físico se le
denomina usando el término HARDWARE. Existen ya programas o software previamente
desarrollado y del cual se puede hacer uso en un sistema de cómputo, pero también gran parte del
software tiene que ser desarrollado por los programadores con fines específicos.
En el caso de programas que están destinados a alguna aplicación específica se les conoce como
PAQUETES DE APLICACIÓN como es el caso de Excel, Word, Mathematica, Matlab, etc. Sin
embargo, cuando se desea hacer algo para lo cual no existe un paquete, uno tiene que escribir sus
propios programas para resolver el problema.
Existen además otros programas que son los encargados de proporcionar servicios vitales para que
un usuario pueda interactuar con un sistema de cómputo; éstos reciben el nombre de SOFTWARE
DEL SISTEMA, del cual, un elemento muy importante es el SISTEMA OPERATIVO. El SISTEMA
OPERATIVO es un conjunto de programas que nos facilitan el uso de los recursos de la máquina.
Por ejemplo, mandar a imprimir por una impresora, cargar un programa en la computadora, desplegar
un texto en pantalla, etc.

1.1 COMPONENTES DE UNA COMPUTADORA TÍPICA.

La UNIDAD DE CONTROL es el componente básico de un sistema de cómputo, y con mucho, el


más importante, ya que está encargada del control de la operación de todos los demás componentes.

El segundo componente básico es la UNIDAD ARITMETICO-LOGICA (ALU) que es en donde,


como su nombre lo indica, se efectúan todas las operaciones aritméticas como la suma, resta, etc., y
las operaciones lógicas como por ejemplo, la comparación de dos valores.

A la combinación de la Unidad de Control y el ALU se le conoce como CPU (CENTRAL


PROCESSOR UNIT) o UNIDAD de PROCESO CENTRAL. Por ejemplo, tenemos los procesadores
de INTEL como el PENTIUM (Pentium IV, Celerón y Xeón), los procesadores de Motorola como el
68000 y el PPC; y de la familia AMD el Athlon y el Duron. Todo sistema de cómputo debe contar
además con dispositivos de entrada y salida que le permitan precisamente establecer contacto con el

4
mundo exterior. Tenemos como ejemplo de estos al teclado, el monitor, el ratón, las impresoras y el
CD-ROM.

Cada computadora tiene una determinada cantidad de almacenamiento interno denominado


MEMORIA PRINCIPAL. Esta memoria es la que opera a mayor velocidad. Para que un programa
pueda ser ejecutado, éste debe ser almacenado en la memoria principal, la cual está formada por
multitud de celdas o posiciones (palabras de memoria) de un determinado número de bits y numeradas
en forma consecutiva. A la numeración de las celdas se le denomina dirección de memoria y es
mediante esta dirección que se puede acceder en forma directa a cualquiera de ellas. Decimos por ello
que la memoria principal es una memoria de acceso directo.

Existen tres tipos de memoria interna: la memoria ROM (Read Only Memory), en la que solo se
permite leer y es permanente, es decir, al apagar la máquina no se pierde la información que ésta
tiene. En algunos casos, el contenido de esta memoria está permanentemente grabado desde que se
fabricó, pertenecen a este grupo las memorias programables de sólo lectura o PROM (Programmable
Read Only Memory), las cuales pueden borrarse y programarse de nuevo si se cuenta con el equipo
indicado.

1.2 MEMORIA DE UNA COMPUTADORA

El segundo tipo de memoria es la RAM (Random Access Memory) o de acceso aleatorio, la cual, al
momento de ser apagado el equipo pierde la información que almacenaba.
Y el tercer tipo es la memoria FLASH, la cual se ha hecho popular recientemente. Esta se puede leer
y escribir de manera directa y no es volátil, es decir al interrumpirse la energía en el sistema de
cómputo mantiene su contenido. Ésta fue inicialmente utilizada en computadoras dedicadas como las
dedicadas a las comunicaciones en redes y ahora hace no mucho tiempo a equipos de fotografía y
audio. La velocidad de acceso a éste tipo de memoria
No es muy rápido, pero es suficientemente bueno para fines específicos de permanencia.

Por otro lado está la MEMORIA SECUNDARIA O MEMORIA EXTERNA, la cual permite resolver
las deficiencias de la memoria principal en cuanto a volatilidad y pequeña capacidad, ya que aunque
la memoria interna es muy rápida, no tiene gran capacidad. Tenemos aquí los

5
al de la memoria interna. correctas del lenguaje), y una semántica (reglas que permiten determinar el
significado de cualquier construcción del lenguaje).
El CPU opera con las instrucciones de control que proporciona un
programador, las cuales, como ya hemos dicho, deben residir en memoria Ya hemos dicho que para que una computadora pueda ejecutar un
principal. El CPU es el encargado de hacer que los datos necesarios para la programa escrito en un determinado lenguaje de programación, es necesario
ejecución de un programa sean leídos mediante los dispositivos de entrada, que dicho programa sea traducido a un lenguaje que la computadora entien-
almacenados en memoria, llevados y operados en el ALU y mostrar los da, es decir a LENGUAJE DE MAQUINA, el cual está totalmente apega-
resultados en algún dispositivo de salida. do a los circuitos (Hardware) de la máquina y muy alejado del lenguaje que
los seres humanos utilizan. Aunque el Lenguaje de Máquina hace posible
El CPU puede entender solamente instrucciones en lenguaje de crear programas que utilicen la totalidad de los recursos de la máquina y así
máquina el cual es por excelencia binario, esto es, en términos de ceros y obtener programas muy eficientes en cuanto a tiempo de ejecución y uso de
unos. Cada CPU tiene circuitos especialmente diseñados para ejecutar cier- memoria, resulta muy difícil programar en él. Por eso se desarrollaron otros
tas instrucciones en particular. La dificultad para programar en lenguaje de tipos de lenguajes como lo vamos a discutir a continuación.
máquina incentivó el desarrollo de estructuras más simples y accesibles, que
se conocen como LENGUAJES DE PROGRAMACION. Los lenguajes de programación se pueden clasificar de la siguiente
manera, utilizando el criterio de proximidad del lenguaje con la máquina o
Y así surgen los LENGUAJES DE ALTO NIVEL (Fortran, Pas- con el lenguaje natural:
cal, C, Algol, Basic, etc.), los cuales permiten programar sin necesidad de
conocer el funcionamiento interno de la máquina ni su arquitectura, por lo 1. Lenguajes de bajo nivel: Lenguajes de máquina.
cual, no están sujetos a ninguna máquina en particular, lo que permite su
portabilidad. Estos lenguajes están más próximos al usuario y a la notación 2. Lenguajes de nivel medio: Ensambladores y Macroensamblado-
de sus problemas y resulta por lo tanto mucho más fácil programar en ellos. res.
De aquí que en el caso de un Lenguaje de Alto Nivel se necesite de un pro-
grama traductor tal que dado un programa en dicho lenguaje, sea capaz de 3. Lenguajes de alto nivel, como Pascal, Fortran, C, C++, Lisp, Ba-
encontrar su equivalente en lenguaje de máquina, el cual pueda ser entendi- sic, Prolog, Algol, etc.
do por el CPU.
A estos últimos se les puede también clasificar por el tipo de pro-
blemas que nos permiten resolver con más facilidad.

I.3. LENGUAJES DE PROGRAMACION Y TRADUCTORES. 1. Aplicaciones científicas, en donde predominan operaciones numé-
ricas propias de algoritmos numéricos. Aquí tenemos a Fortran y
Pascal, donde particularmente destaca Fortran.

Un lenguaje de programación es un conjunto de símbolos, junto 2. Procesamiento de datos, como COBOL y SQL.
con un conjunto de reglas para combinar dichos símbolos que se usan para
3. Tratamiento de textos como C.
expresar programas. Los lenguajes de programación, como cualquier len-
guaje, se componen de un léxico (conjunto de símbolos permitidos o voca- 4. Inteligencia artificial, como aplicaciones en sistemas expertos,
bulario), una sintaxis (reglas que indican cómo realizar las construcciones

-3-
juegos y visión artificial. Aquí tenemos a LISP y PROLOG. dor, el direccionamiento también es simbólico, es decir, en lugar de utilizar
direcciones binarias absolutas para accesar a los datos, éstos pueden ser
5. Programación de Sistemas: Software que permite la interfaz entre identificados usando nombres como SUMA; X, A, B, etc. Además se permi-
el hardware y el usuario. Tenemos a ADA, MODULA-2 y C te el uso de comentarios, lo cual hace que los programas sean más entendi-
bles.
Otra clasificación sería por el estilo de programación que fomentan.
Un programa llamado ENSAMBLADOR traduce las instrucciones
1. Lenguajes imperativos o procedurales. Estos establecen cómo en lenguaje ensamblador a lenguaje de máquina. A la entrada de un progra-
debe ejecutarse una tarea, dividiéndola en partes y especificando ma ensamblador se le conoce como programa fuente y a la salida como
las subtareas asociadas. Se fundamentan en el uso de variables para programa objeto.
almacenar valores y el uso de instrucciones para indicar operacio-
nes a realizar con los datos. La mayoría de los lenguajes de alto ni- Sin embargo, este tipo de lenguajes presenta la mayoría de los in-
vel son de este tipo: Fortran, Pascal, C y Basic. convenientes del lenguaje de máquina, ya que su conjunto de instrucciones
es muy reducido y rígido. No hay portabilidad ya que hay una fuerte depen-
2. Declarativos. Los programas se construyen mediante descripcio- dencia con el hardware de la computadora. La ventaja, como ya hemos
nes de funciones o expresiones lógicas que indican las relaciones dicho, es que permite el uso óptimo de los recursos de la máquina.
entre determinadas estructuras de datos (PROLOG y LISP).
Para resolver las limitaciones de este tipo de lenguajes desarrollan
3. Lenguajes orientados a Objetos. Se centran más en los datos y su unos ensambladores especiales, los macroensambladores.
estructura. Un programa consiste de descripciones de unidades de-
nominadas objetos que encapsulan a los datos y las operaciones
que actúan sobre ellos (C++, SmallTalk, Java).
I.3.2. MACROENSAMBLADORES.
4. Lenguajes orientados al problema. Diseñados para problemas
específicos. Son generadores de aplicaciones que permitan automa- Al hacer un programa en lenguaje Ensamblador se encuentra uno a
tizar la tarea de desarrollo de software de aplicaciones (G y Auto- veces con la necesidad de repetir algunas partes del código. Se llaman MA-
Lisp) CROINSTRUCCIONES (o simplemente MACROS) a las abreviaturas
para un grupo de instrucciones. Una sola instrucción representa un bloque
Se hablará entonces ahora de los traductores para los diferentes tipos de de código.
lenguajes de programación, de acuerdo con su proximidad al lenguaje de
máquina o al lenguaje natural. Un MACROENSAMBLADOR es un programa que traduce un
lenguaje de macroinstrucciones a lenguaje de máquina.
I.3.1. ENSAMBLADORES.
Con el fin de hacer la programación independiente de la máquina
El lenguaje ENSAMBLADOR es un primer intento de sustituir el en la que se esté programando, surgen, como ya se ha dicho, los lenguajes
lenguaje de máquina por uno más cercano a nosotros, los humanos. Cuando de alto nivel. Estos usan frases relativamente fáciles de entender y están más
se asocia un mnemónico a una instrucción de máquina, tenemos lo que se apegados al lenguaje de los problemas que se quiere resolver.
conoce como LENGUAJE ENSAMBLADOR. En un lenguaje ensambla-

-4-
Un lenguaje de alto nivel, como ya se ha dicho anteriormente, es terpretado. Un INTERPRETE es un programa que traduce, al igual que un
independiente de la arquitectura de la máquina y entonces, al igual que ocu- compilador, programas escritos en un lenguaje de alto nivel a lenguaje de
rre incluso con los lenguajes ensambladores y macroensambladores, se máquina; sin embargo, en este caso no existe independencia entre la fase de
necesita de un traductor que traduzca las instrucciones en un lenguaje de traducción y la de ejecución. Un intérprete traduce una instrucción o bloque
alto nivel a lenguaje de máquina. En este caso, una instrucción en lenguaje lógico de un programa escrito en un lenguaje de alto nivel a lenguaje de
de alto nivel, da lugar a varias instrucciones en lenguaje de máquina. Se máquina e inmediatamente se ejecuta; a continuación se ejecuta la siguiente
suele también incluir instrucciones de uso frecuente como por ejemplo fun- instrucción o bloque de manera continua hasta llegar al final del programa
ciones matemáticas de uso común (seno, coseno, logaritmo, etc.). Existe una fuente. Como ejemplo tenemos los muy difundidos intérpretes de BASIC y
gran cantidad de lenguajes de alto nivel y para su traducción se requiere de ASP.
compiladores o intérpretes.
Un intérprete no traduce todo el programa en un solo paso, sino
I.3.3. COMPILADORES que traduce y ejecuta cada instrucción o bloque lógico antes de traducir y
ejecutar la siguiente.
Es un programa que acepta un programa fuente en un lenguaje de
alto nivel y produce su correspondiente programa objeto (programa ya en I.3.5. CARGADORES.
lenguaje de máquina).
Un CARGADOR es un programa que carga un programa objeto a
Algunos compiladores traducen sólo programas completos, mien- memoria principal y lo prepara para su ejecución.
tras que otros traducen partes de un programa. Se puede, en este caso, divi-
dir un programa en MODULOS, donde un módulo es la unidad más peque-
ña de software que resuelve un subproblema del problema general que se
I.4. SISTEMAS OPERATIVOS.
quiere resolver. El programa principal controla todo lo que sucede y los
submódulos o subprogramas (como entrada y salida, manipulación de datos,
control de otros módulos, combinación de los anteriores) se ejecutan, devol-
viendo el control al programa principal. Cada submódulo es independiente y
Un SISTEMA OPERATIVO es un conjunto de programas que
solamente tiene acceso directo al módulo al que llama y sus submódulos.
permiten utilizar los recursos de la máquina. Esto es, sirve como un enlace
Cada módulo puede compilarse (e incluso probarse) de manera independien-
entre el hardware y el usuario.
te.
Como ejemplos de sistemas operativos tenemos MS-DOS, OS/2,
Se necesita entonces de un LIGADOR que una los módulos tradu-
UNIX (y sus diferentes versiones como SOLARIS, IRIX, LINUX, etc.),
cidos en un sólo programa.
WINDOWS-NT, Windows 2000, Windows XP, VMS (Vax) y MAC-OS así
como los sistemas operativos de red (Novell) y sistemas operativos distri-
buidos (MOSIX, Amoeba y Mach).
I.3.4. INTERPRETES.
Los sistemas operativos de red son una ampliación de los sistemas
operativos convencionales que permiten el control de una red de computa-
Un lenguaje de alto nivel, además de ser compilado, puede ser in-
doras. Disponen de programas de control de interfaz con la red y permiten

-5-
establecer una sesión de trabajo con un sistema remoto, transferir archivos b) TRANSFERIR INFORMACION.
entre computadoras, intercambiar correo, etc.
Un sistema operativo debe ser capaz de permitir transferir información
Los sistemas operativos distribuidos controlan el procesamiento de memoria principal a memoria secundaria, y viceversa. También debe
distribuido. Este implica la conexión en paralelo de varias computadoras poder permitir sacar respaldos de información a discos u otros medios ex-
ejecutando funciones concurrentemente y comunicándose entre si. Estos ternos.
resultan complejos, pero obedecen a la necesidad de centralizar y compartir
recursos. La información en un disco está organizada mediante ARCHIVOS. Un
archivo es una colección de información relacionada entre sí y es compara-
Un sistema operativo debe ser ble a una o varias hojas de papel en un archivero convecional. Todos los
programas, textos, imágenes, etc., en un disco, residen en archivos.
1. Eficiente, es decir, no debe desperdiciar tiempo útil y debe realizar
sus funciones de una manera rápida. Un sistema operativo deber ser capaz de desplegar los nombres de los
archivos almacenados en un disco, así como sus contenidos. Debe poder
2. Fiable, ya que un fallo de él, puede causar que el sistema se ''cai- permitir el borrado de archivos que ya no se utilicen. También debe permitir
ga''. mandar a imprimir el contenido de un archivo, etc.

3. Deben ser de tamaño pequeño. c) EJECUTAR PROGRAMAS.


Un sistema operativo debe contar con programas de apoyo que permi- Mediante el sistema operativo debe ser posible el ejecutar un programa
tan realizar operaciones como: que ya se encuentre traducido a lenguaje de máquina. El programa, como ya
hemos dicho, debe ser cargado a memoria principal antes de ser ejecutado.
a) EDITAR.
Otras tareas de los sistemas operativos son por ejemplo el mantenimien-
Durante el desarrollo de un programa, por lo general, resulta necesario to de una contabilidad del gasto de recursos que realiza cada uno de los
efectuar correcciones, agregar módulos, etc. Para evitar el tener que volver a usuarios. Claro que esto tiene sentido cuando un sistema tiene varios usua-
teclear grandes porciones se acostumbra mantener el programa en almace- rios (sistemas operativos multiusuario). Generalmente se desea sobre todo
namiento secundario. Al programa que se utiliza para introducir un progra- contabilizar el tiempo de procesador consumido por cada proceso y la canti-
ma por primera vez, y en general un texto cualquiera como manuales o dad de disco que utiliza cada usuario entre otras tareas.
cartas, y realizar correcciones, recibe el nombre de EDITOR.
Existen entonces además de los sistemas operativos monousuario tra-
Un editor nos permite efectuar operaciones como: dicionales, otras categorías de sistemas operativos:
1. Eliminar partes. 1. Sistemas operativos multitarea (o multiprogramados), los cuales
2. Reemplazar partes. son capaces de ejecutar más de un programa a la vez. Estos se ba-
san en técnicas de multiprogramación y son los más extendidos en
3. Insertar partes. la actualidad.

-6-
2. Sistemas operativos multiusuario, los cuales son sistemas que
permiten que más de un usuario acceda al sistema de manera si-
multánea. Naturalmente dicho sistema debe ser también multitarea
ya que cada usuario podrá ejecutar varios programas a la vez.
UNIX es un ejemplo de este tipo de sistemas.

3. Sistemas operativos multiprocesador: existen sistemas que tienen


dos o más procesadores interconectados, trabajando simultánea-
mente. En este caso, el sistema operativo debe ser capaz de admi-
nistrar el reparto del trabajo entre los distintos procesadores para
sacar provecho del paralelismo existente. (LINUX, UNIX y WIN-
DOWS-NT, MAC-OS).

-7-
II.1. REQUISITOS, DISEÑO, PROGRAMACIÓN Y PRUEBAS.

II
ALGORITMOS
Pueden ser identificadas dos etapas en el proceso de resolución de pro-
blemas:

1.
2.
Fase de solución
Fase de implementación (realización) en algún lenguaje de
programación.

La fase de solución incluye, a su vez el análisis del problema, el diseño y la


verificación del algoritmo.

El primer paso es el análisis del problema, aquí se debe examinar cuidado-


samente la situación a resolver con el fin de obtener una idea clara de lo que
se quiere hacer y determinar cuales son los datos que se necesitan para re-
solver el mismo.

Este primer paso se conoce como “Análisis de Requerimientos”, en este


proceso la persona que plantea el problema (cliente) expone sus necesidades
a quien realizará el programa (analista - programador), esto se lleva a cabo
por medio de diferentes técnicas, tales como: entrevistas, cuestionarios y
observación.

Una vez que se han definido los requerimientos, se continúa con el proceso
de “Diseño”, el cual es una actividad esencialmente creativa. Esta es la
forma mediante la cual se pueden traducir con precisión los requerimientos
del cliente a un producto o programa terminado.

En este proceso se obtiene el “Algoritmo”, el cual puede ser definido como


la secuencia ordenada de pasos, no ambiguos, que conducen a la solución
La primera fase en la construcción de programas del problema planteado.
la determina el algoritmo a utilizar, que nos indi-
ca una serie de pasos ordenados y lógicos para re- Todo algoritmo debe ser:
solver un problema dado.
Preciso. Indicando el orden de realización de cada uno de los pasos.
Definido. Si se sigue el algoritmo varias veces proporcionándole los mis-
mos datos, se deben obtener siempre los mismos resultados.

-7-
Finito. Al seguir el algoritmo, éste debe terminar en algún momento, es • Recursos abstractos. En cada descomposición de una acción com-
decir, debe ejecutarse en un número finito de pasos hasta llegar a la solución pleja se supone que todas las partes resultantes están ya resueltas,
del problema. posponiendo su realización para el siguiente refinamiento.

Para diseñar un algoritmo se debe comenzar por identificar las tareas más • Estructuras básicas. Los algoritmos deberán ser escritos utilizando
importantes y disponerlas en el orden en que han de llevarse a cabo. Los únicamente tres tipos de estructuras básicas: secuenciales, decisión
pasos en esta primera descripción de actividades deberán ser refinados, e iteración, las cuales se describen más adelante.
añadiendo más detalles a los mismos e incluso, algunos de ellos pueden
requerir un refinamiento adicional antes de que se pueda obtener un algo- TEOREMA DE BÖHM Y JACOPINI
ritmo claro, preciso y completo. Este método de diseño de los algoritmos en Para que la programación sea estructurada, los programas han de ser pro-
etapas, donde se va de los conceptos generales a los detalles a través de pios. Un programa se define como propio si cumple las siguientes caracte-
refinamientos sucesivos, se conoce como método descendente (Top-down). rísticas:

Existe otro método, que no es recomendable y al contrario del Top-down, • Tiene un solo punto de entrada y uno de salida
consiste en ir de lo particular hacia lo general. Este método se conoce como • Toda acción del algoritmo es accesible, es decir, existe al menos
Bottom-up. un camino que va desde el inicio hasta el fin del algoritmo, se pue-
de seguir y pasa a través de dicha acción.
Una vez que se tiene el algoritmo definido, se pasa a la Fase de Implemen- • No posee lazos o bucles infinitos.
tación, en ésta, se lleva a cabo la “Codificación” del mismo (traducción del
algoritmo a algún lenguaje de programación), luego sigue la ejecución y El teorema de Böhm y Jacopini dice que: “un programa propio puede
comprobación del programa. ser escrito utilizando únicamente tres tipos de estructuras: secuencial,
selectiva y repetitiva”. De este teorema se deduce que se han de diseñar
El paso de comprobación es muy importante, en este, se ejecuta el programa los algoritmos empleando exclusivamente dichas estructuras, las cuales,
varias veces, con distintos datos, para verificar que se obtengan los resulta- como tienen un único punto de entrada y un único punto de salida,
dos que se esperaban. harán que nuestros programas sean intrínsicamente propios.

II.2. TÉCNICAS DE PROGRAMACIÓN ALGORITMICA II.3. ELEMENTOS BÁSICOS


PROGRAMACIÓN ESTRUCTURADA

Un algoritmo puede ser escrito en lenguaje natural, pero esta des-


La programación estructurada es un conjunto de técnicas para desarro- cripción puede ser ambigua, por lo que se utilizan diferentes métodos de
llar algoritmos fáciles de escribir, verificar, leer y modificar. Utiliza: representación, que permiten evitar dicha ambigüedad y al mismo tiempo
que sean fácilmente codificables. Los métodos más usuales para la repre-
• Diseño descendente. EL cual consiste en diseñar los algoritmos en sentación de algoritmos son:
etapas, partiendo de los conceptos generales hasta llegar a los deta- • Descripción narrada
lles. El diseño descendente se verá complementado y ampliado con • Diagrama de flujo
la modularización. • Pseudocódigo

-8-
DESCRIPCIÓN NARRADA

Es la forma más sencilla de describir o expresar un algoritmo. Consiste


en hacer un relato de la solución en lenguaje natural.
Líneas de flujo
Por ejemplo Algoritmo en descripción narrada para la suma de 2 núme-
ros.
Conector
1. obtener los números a sumar
2. sumar los números
3. anotar el resultado De manera general un diagrama de flujo esta constituido de la siguiente
manera: inicia, recibe datos, realiza el procesamiento, muestra resultados y
El uso del lenguaje natural provoca frecuentemente que la descripción finaliza.
sea imprecisa y poco confiable, por lo que este tipo de representación
no es recomendable.
Inicio
DIAGRAMA DE FLUJO

Es la representación gráfica de un algoritmo. Utiliza símbolos normali-


zados, con los pasos del algoritmo escritos en el símbolo adecuado y los
símbolos unidos por flechas, denominadas “líneas de flujo”, que indican
el orden en que los pasos deben ser ejecutados. Los símbolos principa-
les son:

Inicio y fin del algoritmo

Proceso

Entrada

Salida

Decisión
Fin

-9-
PSEUDOCÓDIGO Repetitición:
mientras <condición>hacer
acciones
El pseudocódigo en un lenguaje de especificación de algoritmos que utiliza fin_mientras
palabras reservadas y exige la indentación, o sea, sangría en el margen iz-
quierdo, de algunas líneas. Se concibió para superar las dos principales repetir
desventajas de los diagramas de flujo: Lento de crear y difícil de modificar acciones
sin un nuevo proceso de redibujo. Es una herramienta muy efectiva para el hasta <condición>
seguimiento de la lógica de un algoritmo y para transformar con facilidad
los algoritmos a programas. para <Variable de control> Å <valor_inicial> hasta
<valor_final> hacer
Las distintas estructuras de control se representan de la siguiente forma: acciones
fin_para
Secuenciales: Leer (Lista_de_variables)

Escribir (Lista_de_resultados)
II.4. DATOS Y EXPRESIONES
Decisión
simple: si <condición > entonces Dato es la expresión general que describe a los elementos con los
acción_si cuales opera un programa. Los datos pueden estar expresados como Varia-
fin_si bles o como Constantes.

doble: si <condición> entonces CONSTANTES


acción_si
si_no Las constantes son elementos cuyo valor no cambia durante todo el desarro-
acción_no llo del algoritmo. Pueden ser literales o simbólicas. Las constantes simbóli-
fin_si cas tienen un valor asignado y se identifican por un nombre. Una constante
literal es un valor que se utiliza como tal.
múltiple: según <expresión> sea
<valor1> : acción1 Ejemplo de constantes simbólicas:
<valor2>: acción2
........... PHI (tiene el valor asignado 3.1416)
<valorn>: acción n
[si_no Ejemplos de constante literal:
acción_sino]
fin_según 2.012
230
‘A’.

-10-
Las constantes pueden ser: EXPRESIONES

• Numéricas enteras: En el rango de los números enteros posi- Una expresión es una combinación de operadores y operandos. Los operan-
tivos o negativos. dos pueden ser constantes, variables u otras expresiones. Los operadores
Ejemplos: 0, 2, -3, -8 pueden aritméticos, lógicos, orientados al bit o relacionales.
• Numéricas reales: En el rango de los números reales positivos
o negativos. Los operadores aritméticos son:
Ejemplos: 3.1416, 0.5, -4.3
Operador Significado Prioridad
• Lógicas: con valores True o False únicamente. - operador unario menos 3
* producto 2
• Carácter: Alfabético (´a´, ´b´, ..., ´z´) en mayúscula o minús- / cociente 2
cula, Numérico (´0´,´1´,...,´9´) o Carácter especial (´+´,´?´, + suma 1
‘#’, ‘$’). - resta 1

• Cadena: Sucesión de caracteres encerrados entre comillas do- La evaluación de las expresiones se realiza de izquierda a derecha cuidando
bles. la prioridad de los operadores, los de prioridad mayor se evalúan primero.
Ejemplo: “Cadena de ejemplo” La evaluación de los operadores con la misma prioridad se realiza siempre
de izquierda a derecha. Si una expresión contiene subexpresiones encerrada
VARIABLES s entre paréntesis, dichas expresiones se evalúan primero.

Las variables son elementos cuyo valor puede cambiar durante el desarrollo Ejemplo:
del algoritmo. Se identifican por un nombre y un tipo. El tipo determina el Si A=2, B=3 y C=4,
conjunto de valores que la variable puede tomar. A+B*C=14 y (A+B)*C=20
Lo referente a los operadores lógicos, orientados al bit y relacionales será
Ejemplos: tratado más adelante.

Variable Valor Tipo II.5. ESTRUCTURAS SECUENCIALES


A 2 Entero
B 5 Entero Se caracterizan porque una acción se ejecuta detrás de la otra. El flujo
Radio 2.5 Real del programa coincide con el orden físico en el que se han ido colocando las
Carac1 ‘a’ caracter instrucciones. Es decir, es una secuencia lineal de acciones, donde se ejecuta
Carac2 ‘c’ caracter primero la acción uno, después la dos, luego la tres, etc. Dichas acciones
pueden consistir en acciones simples tales como:

Las variables pueden ser de tipo: entero, real, carácter, lógico o cadena. • como leer datos
• realizar operaciones
Las constantes y variables se utilizan para la formar expresiones. • escribir resultados

-11-
Estas estructuras se representan de la siguiente forma: Se leen los datos a sumar A y B, se suman y el resultado se coloca en C
(note el uso del símbolo que significa asignación ). Finalmente se
Diagrama de Flujo Pseudocódigo muestra C.

Acción1 Acción1 Ejemplo: Para calcular e imprimir el sueldo de un empleado.


Acción2

Acción2 Diagrama de Flujo Pseudocódigo

Funcionamiento
1. Se lleva a cabo la Acción 1 Inicio
2. Se lleva a cabo la Acción 2 Leer (nombre,horas,cuota)
sueldo horas * cuota
Escribir (nombre,sueldo)
Ejemplo: Para sumar 2 números. Fin

Diagrama de Flujo Pseudocódigo


Se lee el nombre del trabajador, las horas laboradas y la cuota por hora, se
Inicio obtiene el sueldo y finalmente se muestra el nombre y el sueldo calculado.
Inicio Es importante observar que el nombre solo es empleado para mostrarse
Leer (A,B) junto con el resultado y no ha sido empleado para el cálculo lo cual es váli-
C A+B do.
Escribir (C)
A,B Fin
II.6. ESTRUCTURAS SELECTIVAS

C A+B Permiten controlar la ejecución de acciones que requieran ciertas


condiciones para su realización, es decir, se ejecutan unas acciones u otras
según se cumpla o no una determinada condición.

Estas estructuras son utilizadas cuando:


C
• Se tienen acciones que son “excluyentes”, es decir, que sólo
tienen que ejecutarse una o la otra, pero no ambas.
• Cuando es necesario elegir la acción a realizar de entre un con-
Fin
junto de acciones existentes.

-12-
• Cuando es necesario verificar que lo datos sean válidos para la Ejemplo:
aplicación en cuestión, por ejemplo: no es posible dividir entre Para dividir 2 números considerando que el divisor no puede ser 0 (cero).
0, la cuota por hora que se le paga a un trabajador no puede
ser negativa, etc. Diagrama de Flujo Pseudocódigo

Las estructuras selectivas pueden ser: simples, dobles o múltiples. Inicio


Inicio
Leer (A, B)
A,B Si B ≠ 0 entonces
SIMPLES. C A/B
Escribir (C)
Se evalúa la condición y si ésta da como resultado verdad se ejecuta una Fin_si
determinada acción o grupo de acciones; en caso contrario no se ejecuta B≠0 Fin
dicho grupo de acciones y se continúa con el flujo. si no

Esta estructura se representa de la siguiente forma: C A/B

Diagrama de flujo Pseudocódigo C

Condición Si <condición> entonces Fin


si no acción
Fin_si Se leen los datos a emplear A y B, y como se quiere dividir A/B, se
“válida” el valor de B a través de la condición B≠0, si la condición se
Accion cumple (si la evaluación de la condición da verdad) entonces se realiza la
división y se muestra el resultado, en otro caso se va al final sin efectuar
acción alguna.

DOBLES.

Cuando el resultado de evaluar la condición es verdad se ejecutará una


determinada acción o grupo de acciones y si el resultado es falso se
ejecutará otra acción o grupo de acciones alternativas. En ambos casos la
sentencia podrá ser simple o compuesta.

-13-
Esta estructura se representa de la siguiente forma: evaluación de la condición da verdad) entonces se realiza la división y se
muestra el resultado, en otro caso se escribe un mensaje de “Error” (note el
Diagrama de flujo Pseudocódigo uso de ‘’ para colocar el mensaje a escribir) y se dirige el flujo al final sin
efectuar la división y enviando el mensaje de “Error”.

si Condición no Si <condición > entonces


acción_si Ejemplo 2: Para determinar el mayor de dos números, considerando el
accion_si accion_no sino hecho de que sean iguales.
acción_no
Fin_si Diagrama de Flujo Pseudocódigo

Inicio Inicio
Ejemplo 1: Al dividir 2 números considerar que el divisor no debe ser 0. Leer (A,B)
Si A = B entonces
Diagrama de Flujo Pseudocódigo A,B Escribir ‘son iguales’
sino
Inicio Si A > B entonces
Inicio si no Escribir (‘A Mayor’)
Leer (A,B) A=B sino
A,B Si B ≠ 0 entonces Escribir (‘B Mayor’)
C A/B Fin_si
Escribir (C) Fin
si no sino ‘son iguales’
B≠0 Escribir (‘Error !!’) si no
Fin_si A>B
Fin
‘A Mayor ’ ‘B Mayor’
C A/B ‘Error !!’

Fin

Fin

Se leen A y B para verificar si son iguales, si es así, entonces se escribe el


Se leen los datos a emplear A y B y como se va a dividir A/B, se “valida” mensaje ‘Son iguales’ y se va al final, si no son iguales, entonces se verifica
el valor de B a través de la condición B≠0, si la condición se cumple (si la

-14-
si A > B, si es así entonces se escribe ‘A Mayor’, si no es así, entonces B es
mayor, se escribe el mensaje correspondiente y se va al final. Diagrama de flujo Pseudocódigo
Es importante resaltar en este ejemplo la existencia de estructuras selectivas
anidadas, introduciendo unas dentro de otras, en este caso se ha introducido Inicio Inicio
otra estructura de selección dentro de la rama del sino de la primera estruc- Escribir ‘Proporcione A y B’
tura selectiva (A=B). Leer (A y B)
Escribir ‘Opciones:’
´Proporcione A y B:’ Escribir ‘ 1.- Suma’
MÚLTIPLES. Escribir ‘ 2.- Resta’
Escribir ‘ 3.- Producto’
Las estructuras selectivas múltiples permiten controlar la ejecución de ac- Escribir ‘ 4.- División’
ciones cuando se tienen más de dos opciones alternativas de selección. Aquí Escribir ‘ Opción ?’
se ejecutarán unas acciones u otras según el resultado que se obtenga al A,B Leer Opción
evaluar una expresión. Según Opción sea
1: C A+B
Cada grupo de acciones se encuentra ligado con un valor o una serie de Escribir ‘Suma=’,C
valores expresados mediante: una constante, varias constantes separadas por ‘ Opciones: 2: C A-B
comas, un rango expresado como valor_inicial...valor_final, o una mezcla 1.- Suma Escribir ‘Resta=’,C
de constantes y rangos. 2.- Resta 3: Si B ≠ 0 entonces
3.- Producto C A /B
Cuando el valor obtenido al evaluar la expresión no está presente en ningu- 4.- División Escribir ‘División=’,C
na lista de valores se ejecutarán las acciones establecidas en la cláusula sino sino
(si existiese dicha cláusula). opcion? ’ Escribir ‘Error !!’
Fin_si
4: C AxB
Diagrama de flujo Pseudocódigo Escribir ‘Producto =’,C
Fin_según
Fin
Según <expresión> sea
Expresión <valorl>:Acción1 Opción
<valor2>:Acción2
.
.
[sino
Acción 1 Acción 2... Acción n Acción n] 1
fin_según

Ejemplo: Para realizar alguna de las siguientes operaciones: suma, resta,


multiplicación o división, según la elección del usuario.

-15-
Las Expresiones Lógicas Simples se forman relacionando operandos (varia-
1
4 bles y/o constantes) mediante operadores relacionales. Así, tienen la si-
C Å AxB guiente forma:
1
Opción Operando1 Operador Relacional Operando2
3

2 Los operadores relacionales son:

C A+B C A-B ‘Multiplicación=’, C Operador Significado


> Mayor que
< Menor que
= Igual a
‘Suma=’,C ‘Resta=’,C B≠0 ≠ diferente de
>= Mayor o igual que
<= Menor o igual que

Ejemplos:
CÅA/B ‘Error ¡ ‘ A>B
B≠0
Las Expresiones Lógicas Compuestas se forman utilizando operandos boo-
leanos (expresiones lógicas que proporcionan un valor verdadero o falso)
‘División=’,C con operadores lógicos. Éstas tienen la siguiente forma:

Operando Booleano1 Operador Lógico Operando Booleano2

Los operadores lógicos básicos son:


Operador Significado
Not (no) Negación
FIN And (y) Conjunción
Or (o) Disyunción

Para terminar con esta sección, es importante mencionar que las estructuras Ejemplo:
selectivas simples y dobles emplean Expresiones Lógicas que sirven para (A ≠ B) y (B > C)
plantear condiciones, que dan como resultado un valor booleano verdadero
o falso, es decir se cumple o no se cumple la condición.

Las expresiones lógicas se pueden clasificar en : Simples y Compuestas.

-16-
II.7. ESTRUCTURAS DE REPETICIÓN

Iterar o ciclar es repetir una tarea: hacer algo y luego regresar y hacerlo una
y otra vez hasta terminar la tarea, la condición de terminación debe estar Diagrama de Flujo y Pseudocódigo
bien definida. Las aplicaciones típicas de la computadora que requieren
iteración son:
• La introducción de muchos datos, uno tras otro, para efectuar di-
versos cálculos (por ejemplo obtener el promedio de calificaciones
de un alumno).
• La clasificación periódica de una gran colección de datos (por I Å ValorInicial
ejemplo la clasificación de cheques procesados por sucursal banca-
ria, y para cada sucursal por número de cuenta del cliente cada día
de la semana).
• La búsqueda de un dato en una gran colección de ellos (por ejem-
plo encontrar el precio actual de un articulo o el estado de una F
cuenta de depósito). Sale del ciclo
condicion
• Y muchas formulas científicas que sólo se pueden calcular por
aproximaciones sucesivas (reduciendo el error de la estimación en
cada ciclo).

Existen tres clases de mecanismos de iteración: V


1. Para todos los valores de la progresión.
2. Mientras se valida una condición. Acción
3. Repetir- hasta que se satisfaga una condición.
Veamos cada uno de ellos:

PARA.
Es usado cuando se conoce de antemano el número de veces que
debe repetirse una instrucción o conjunto de ellas. Es un ciclo in-
Incremento
condicional, que abarca todos los valores de una progresión, em-
pieza con el primer valor y termina con un último de ellos, los va- para <Variable de control> Å <valor_inicial> hasta <valor_final>
lores de la progresión deben ser asignados a una variable, la cual se hacer
denomina variable de control. acción 1
.
.
.
acción n
fin_para

-17-
Después de lo anterior, llega al fin el cual remite el control al inicio
del para, actualizando el valor del contador de acuerdo con el
Otra representación para el Diagrama de Flujo incremento o decremento.

Ejemplo. Para sumar los 5 primero enteros positivos:

Inicio
Inicio suma Å 0
para j Å 1 a 5 hacer
salida suma Å suma + j
fin_para
Incremento o escribir(suma)
decremento Fin

Aquí a la variable de control j se le asigna originalmente el valor 1.


La variable SUMA, que antes de entrar al ciclo tenía un 0, aumen-
Accion tará por el valor de j. En la segunda pasada j tendrá un 2, y SUMA,
aumentará a 3. En la tercera vuelta j llegará a 3, y esto incrementa-
rá SUMA a 6, y así sucesivamente hasta que j se le asigne el últi-
mo valor de la progresión: 5, después de los cual SUMA contendrá
la suma de los 5 primeros enteros positivos, es decir, 15.

Funcionamiento CICLO PARA ANIDADO.


Al igual que todas las estructuras de control, es posible que un ciclo
1. Se inicia la condición de control, se verifica la condición de PARA contenga anidado otro ciclo y éste a otro; veamos, el si-
paro si no se cumple entra al ciclo y ejecuta la acción. guiente ejemplo:
2. Al llegar al fin regresa el control al encabezado de ciclo, actua-
lizando el valor del contador de acuerdo al incremento, decre- Ejemplo. Algoritmo que ilustra el uso de un PARA anidado.
mento o modificación especificada de la variable de control.
3. Al volver el control del encabezado se pregunta si la variable inicio
de control llegó al valor final: para I Å 1 a 5 hacer
a. Si se cumple, entonces se sale del ciclo, dirigiéndose escribir (‘i =’,I)
a la siguiente instrucción después del fin. para J Å 1 a 3 hacer
b. Si no ha tomado el valor final, entra al ciclo a ejecutar escribir (‘j =’,J)
la instrucción. fin_para
fin_para
fin

-18-
Se trata de un ciclo controlado por I, dentro del cual se imprime el mientras <condición>hacer
valor de I; además, contiene anidado un ciclo Para controlado por <acciones>
J, donde se imprime el valor de J. fin_mientras
Por cada una de las veces que entre en el primer ciclo Para (el más
externo), ejecutará 3 veces al ciclo interno; esto significa que por 5
veces que entrará en I, lo hará 3 veces en J. Ejemplo: Elaborar un algoritmo que calcule e imprima el sueldo de varios
empleados utilizando el ciclo MIENTRAS
Obsérvese el par inicio-fin porque hay más de una instrucción de-
ntro del ciclo. inicio
escribir ( ‘¿hay otro empleado (s/n)?’)
MIENTRAS. leer (otro)
La instrucción Mientras... hacer continuará repitiéndose mientras mientras otro = ‘s’ hacer
la condición sea siendo válida (es decir, su valor de verdad sea ver- escribir (‘proporcione nombre, número de horas tra-
dadero). bajadas y cuota’)
leer (nombre,hrstrab,cuotahr)
Diagrama de Flujo y Pseudocódigo sueldo Å hrstrab*cuotahr
escribir (nombre, sueldo)
MIENTRAS...HACER escribir( ‘¿desea procesar otro empleado (s/n)?’)
leer (otro)
fin_mientras
fin
La condición
es falsa
Condición

La condición
es verdadera

Acción a
repetir

-19-
REPETIR Vemos que en el MIENTRAS...HACER la condición se evalúa primero, y si
la prueba falla (el valor de verdad de la condición es FALSO), entonces el
La instrucción Repitir...hasta continuará repitiéndose mientras no ciclo no se lleva a cabo de ninguna manera. En el ciclo REPITIR...HASTA
se satisfaga la condición (su valor de vedad sea falso). la prueba se realiza al final (es decir la condición se evalúa luego de ejecu-
tarse las sentencias que este engloba) y si el valor de la condición es VER-
Esta instrucción tiene el siguiente diagrama de flujo: DADERO, entonces se abandona el ciclo después de realizarlo por lo menos
una vez.
Diagrama de Flujo y Pseudocódigo
Ejemplo: Elaborar un algoritmo que calcule e imprima el sueldo de varios
REPETIR ... HASTA empleados utilizando el ciclo REPETIR

inicio
repetir
escribir (‘proporcione nombre, número de horas trabajadas y
Acción a cuota ‘)
repetir leer (nombre,hrstrab,cuotahr)
sueldo ←hrstrab*cuotahr
escribir (nombre, sueldo)
escribir ( ‘¿desea procesar otro empleado (s/n)?’)
leer (desea)
hasta desea = ‘n’
La condición fin
es verdadera
Condición

II.8. DISEÑO DESCENDENTE


condición aun
no satisfecha

El diseño descendente es la técnica que permite diseñar la solución


de un problema con base en la modularización, o segmentación dándole un
enfoque de arriba abajo (Top Down Design). Esta solución se divide en
módulos que se estructuran e integran jerárquicamente, como si fuera el
organigrama de una empresa.
repetir
<accion> Ejemplo: Programa ALGO
hasta <condición>

Módulo UNO Módulo DOS Módulo TRES

-20-
En el diagrama anterior se muestra la estructura del programa lla- control, que son los que se encargarán de distribuir el trabajo de los demás
mado ALGO, que se auxilia de tres módulos subordinados, cada uno de los módulos. De esta manera se puede diseñar un organigrama que indique la
cuales ejecuta una tarea especifica. En su momento, el módulo principal estructura general de un programa.
ALGO invocará o llamará a los módulos subordinados, es decir, dirigirá su
funcionamiento. En el diagrama anterior se tiene un módulo directivo llamado AL-
GO, que dirige el funcionamiento de tres módulos subordinados que son:
¿QUE ES UN MÓDULO? MODULO UNO, MODULO DOS Y MODULO TRES.

Es un segmento, rutina, subrutina, subprograma que puede ser definido


dentro de un programa con el propósito de ejecutar una tarea específica,
pudiendo ser llamado o invocado desde el programa principal cuando se PROCESO DE MODULARIZACIÓN.
requiera una o muchas veces.
El proceso de modularización consiste en hacer una abstracción de
¿CUÁNDO ES ÚTIL LA MODULARIZACIÓN? un problema, del cual se tiene inicialmente un panorama general, en seguida
se procede a “desmenuzar” o “dividir”. El problema en partes pequeñas y
Este enfoque de segmentación o modularización es útil en dos casos al me- simples, como se muestra:
nos:
1. Cuando existe un grupo de instrucciones o una tarea especifica que Ejemplo: Se necesita elaborar un programa que calcule el sueldo
debe ejecutarse en más de una ocasión de forma condicional o in- de varios empleados, similar a los algoritmos vistos en estructuras de repeti-
condicional. ción, sólo que ahora utilizando descomposición modular y controlando los
2. Cuando un problema es complejo o extenso, la solución se “divide” saltos de página.
o ”segmenta” en módulos que ejecutan “partes” o tareas específicas
El proceso es el siguiente:
Las principales razones de la estructura de módulos se deben a que los
programas son más fáciles de: 1. El proceso es el siguiente: leer el monto del salario mínimo,
para cada empleado se solicitarán sus datos, se calculará su sa-
• Escribir, lario y se escribirán estos datos y salario. Además, cada 57
• Comprender, empleados se debe imprimir el encabezado que ocupa tres lí-
• Modificar, neas. Este proceso termina cuando ya no se desean agregar
• y de Usar. empleados.

Dicha solución es organizada de forma similar a como lo hacen las em- Aplicación:
presas cuando se estructuran con base en las funciones para realizar sus Aplicar lo anunciado en este punto; y, si se considera que se trata
actividades; en otras palabras, el trabajo se divide en partes que sean fácil- de un programa que ayudará a calcular la nómina tenemos el módulo princi-
mente manejables y que, lógicamente, pueden ser separadas; así, cada una pal siguiente:
de estas partes se dedica a ejecutar una determinada tarea, lo que redundará PROGRAMA NOMINA
en una mayor concentración, entendimiento y capacidad de solución a la
hora de diseñar la lógica de cada una de éstas. Dichas partes son los módu-
los o segmentos del programa, algunos de ellos son módulos directivos, o de

-21-
2. Se toma este módulo y se busca la forma de dividirlo en otros módu- En caso de no ser así, es decir, que el módulo datos, por ejemplo,
los más pequeños, que ejecuten tareas o funciones específicas. Las requiera otros módulos subordinados, la estructura general del programa
mismas funciones que se desea que ejecute el programa, nos darán la sería la siguiente:
pauta para definir los módulos y así hacer una segmentación de la solu-
ción del problema en partes más manejables.
Algoritmo NOMI-
NA
Aplicación: 1
Si nos referimos al ejemplo anterior, tenemos que se deben llevar a
cabo tres tareas o funciones claramente definidas: encabezado, datos, cálcu-
los de ahí que necesitamos un módulo para cada una de las tareas, las cuales 2 3 7
deberán estar subordinadas al módulo principal. La estructura que se tiene, Módulo ENCA- Módulo Módulo CALCU-
entonces, es la siguiente: BEZADO DATOS LOS

Algoritmo
NOMINA 1
4 5 6
Modulo R1 Modulo R2 Modulo R3

Modulo Modulo Modulo


ENCABE- DATOS CALCULOS
Como se puede ver, la numeración sufre ciertas alteraciones, es decir, cuan-
ZADO do se ejecuta el módulo datos, se enumera todo lo que dependa de éste, para
después continuar con él de cálculos, que es el siguiente en el orden. En este
2 3 4
caso, el módulo de datos se convierte a su vez en un módulo directivo que
controla la ejecución de sus módulos subordinados.
Nota: Los módulos se enumeran de arriba hacia abajo y de izquierda a dere-
cha
II.9. PASOS PARA PROGRAMAR
3. Se repite el paso 2 para cada módulo nuevo definido, hasta llegar
a un nivel de detalle adecuado, es decir, hasta hacer que cada mó- Desarrollar un programa es un proceso lógico lineal. Si se considera el
dulo ejecute una tarea específica, que esté claramente definida y tiempo requerido y sigue el proceso de principio a fin, se conseguirá tener
que el diseño y la codificación de la lógica del mismo, resulte fácil. éxito en la programación.

Aplicación: 1. Diseñar el programa


En el problema que estamos analizando, se revisan los módulos en-
cabezado, datos y cálculos. Se considera que estos módulos tienen un nivel
2. Escribir el programa
de detalle adecuado, porque cada módulo hace una tarea muy simple, clara y 3. Compilar el programa
específica y, en consecuencia, se pueden diseñar fácilmente. 4. Ligar el programa
5. Probar el programa

-22-
DISEÑAR EL PROGRAMA COMPILAR EL PROGRAMA

Esta es la parte más importante, pues aquí se definirán los rasgos y Después de grabar el archivo con el código fuente, utilice el compi-
características del programa a desarrollar, lo primero es hacer un lador para crear el archivo objeto inmediato. Aquellas instrucciones
bosquejo del programa con tanto detalle como sea posible. La ma- que el compilador no puede entender generan avisos preventivos
yoría de los programas siguen un patrón llamado IPO, para Input del compilador o mensajes de error. Un aviso preventivo (WAR-
(Entrada), Processing (Procesamiento), Output (Salida). NING) significa que hay un problema potencial pero que el compi-
lador puede continuar generando el código objeto. Un mensaje de
Por ejemplo se requiere un programa que obtenga una media de error (ERROR normalmente detendrá el proceso de compilación.
una muestra aleatoria. ¿Qué necesita hacer el programa?. Considere Si aparece un mensaje de error, se requiere volver a cargar, por
las entradas. Se requieren los datos que proporcionan información medio de un editor, el archivo con el programa fuente, y corregir el
acerca de las características de lo censado, por ejemplo el costo, la error. Por lo general estos son errores de sintaxis, equivocaciones
durabilidad, o simplemente se desea obtener un promedio de califi- en la escritura, puntuación o en la redacción de un comando C o
caciones de un semestre, en este caso se emplean las calificaciones una función.
como entradas.
LIGAR EL PROGRAMA
A continuación se determina el proceso. En este caso se requiere
calcular la suma de las calificaciones y posteriormente dividirlas Una vez que no haya errores de compilación, se liga (encadena) el
entre el número de estas. Finalmente, considere la salida. El resul- archivo objeto con las bibliotecas para crear un programa ejecuta-
tado de los cálculos deberá ser desplegado o impreso para presentar ble. Se obtendrán mensajes de error si el ligador no puede encon-
un reporte o hacer un análisis. trar la información requerida en las bibliotecas. Deberá analizarse
el código fuente para estar seguros de que se están empleando los
Entrada. Indicar al usuario del programa que ingrese el número de archivos de biblioteca correctos.
calificaciones. Aceptar por el teclado cada una de las calificaciones
Proceso. Sumar las calificaciones y el total dividirlo en el número PROBAR EL PROGRAMA
de datos solicitados.
Salida. Mostrar el promedio en pantalla o impreso en papel Ahora se puede proceder a ejecutar el programa. Si todo se realizo
correctamente, el programa correrá sin problemas. Sin embargo,
podrán presentarse dos tipos de errores.

Error en el tiempo de ejecución


ESCRIBIR EL PROGRAMA Errores de lógica

Se utiliza un editor para escribir el programa. Un editor es un pro- Un error en tiempo de ejecución se presenta cuando un programa
grama similar a un procesador de texto, excepto que no requiere la incluye una instrucción que no puede ser ejecutada. Aparecerá un
capacidad de dar formato a los caracteres o a los párrafos. En reali- mensaje en la pantalla y el programa se detendrá. Los errores de
dad, el archivo del código fuente no deberá contener ningún código tiempo de ejecución con frecuencia están asociados con archivos o
de formato especialel compilador no los entenderá y los tratará co- con dispositivos del equipo
mo errores.

-23-
Los errores de lógica ocurren cuando el programa puede continuar Primer Segundo Tercer Cuarto Quinto Sexto Séptimo
con la ejecución de las instrucciones pero estas son incorrectas; es- Elemento Elemento Elemen- Elemento Elemen- Elemen- Elemen-
to es, cuando producen resultados erróneos. Estos son los proble- to to to to
mas más difíciles de detectar porque puede ser que se ignore su
existencia. Se deberá analizar los resultados y las salidas del pro-
grama para verificar su exactitud. Los vectores se pueden representar como filas de datos o como columnas de
datos.
II.10 ARREGLOS
Los elementos de un arreglo unidimensional o vector V de 5 elementos se
muestran a continuación:
Un arreglo es un conjunto finito e indexado de elementos homogéneos, que
se referencian por un identificador común (nombre). La propiedad indexado
significa que el elemento primero, segundo, hasta el n-ésimo de un arreglo
pueden ser identificados por su posición ordinal. La propiedad homogéneo
significa que todos los elementos de un arreglo son del mismo tipo.

Los arreglos se clasifican en:

• Unidimensionales (Vectores).
• Bidimensionales (Tablas o Matrices)
• Multidimensionales.

ARREGLOS DE UNA SOLA DIMENSIÓN O VECTORES

Un arreglo de una dimensión o vector es un conjunto finito y ordenado


de elementos homogéneos.
Los elementos del vector V se representan con la siguiente notación:
El subíndice o índice de un elemento [1, 2, ..,i, i+1, ,, n] designa su posición
en el orden del vector. Por ejemplo un arreglo denominado Coches, que V[1], V[2], V[3], ..., V[N]
consta de 7 elementos, se puede representar con un vector de longitud 7 de
la siguiente manera: Es decir, todos los elementos tienen el mismo nombre (V) y se referencian a
través del subíndice que indica la posición que ocupan en el arreglo. Dichos
elementos se manipulan como variables individuales. De esta manera se le
puede asignar un valor a un elemento, por ejemplo V[1]= 3 u obtener el
Vector Coches valor de un elemento y almacenarlo en otra variable, por ejemplo,
Jetta Pontiac Seat Chevy Jeep Peugeot Mustang Aux = V[4].

En un arreglo unidimensional o vector se distinguen tres elementos:


• El Nombre del vector

-24-
• La Longitud o rango del vector <NombreVector>[subíndice] Å <Valor>
• Los Subíndices del vector
Así la instrucción V[1] = 8, le asigna el valor 8 al elemento 1 del vector V.

Ejemplos:

V[1] Å 8

MiVector[4] Å 16

Nombres[12] Å ‘México’

MiVector[1] Å MiVector[1] + 1

MiVector[2] Å MiVector[1] / 2

V[2] Å V[3] / 4 + V[4] * 3

Los subíndices de un vector pueden ser enteros, variables o expresiones


enteras. Esto es,
OPERACIONES BÁSICAS CON VECTORES
Si i ← 2 entonces
Las operaciones que se pueden realizar con vectores son:
• Asignación V[ i ] representa el 2do. elemento del vector
• Lectura/Escritura V[ i + 1 ] representa el 3er. elemento del vector
• Actualización V[ i + 3 ] representa el 5to. Elemento del vector
• Recorrido o acceso secuencial
• Ordenamiento
• Búsqueda Así, si el objetivo es asignar valores a todos los elementos de un vector,
entonces se pueden utilizar las estructuras repetitivas (Para-Hasta-Hacer,
En general las operaciones con vectores implican el procesamiento de los Mientras-Hacer, Repite-Hasta)
elementos individuales del vector.
Ejemplo: Asignar el valor 0 a todos los elementos del vector A de longitud
100.
ASIGNACIÓN
Para x ← 1 hasta 100 hacer
La asignación de valores a un elemento del vector se realiza con la instruc- A(X) ← 0
ción de asignación: Fin_para

-25-
LECTURA/ESCRITURA subíndices del vector (por ejemplo, V(i)). El incremento de la variable de
control produce el tratamiento sucesivo e individual de los elementos del
La lectura y escritura de datos de arreglos se realizan con estructuras repeti- vector.
tivas, o utilizando los elementos individuales si ese es el caso.
Ejemplo: Cálculo de la suma y promedio de los primeros 10 elementos
enteros de un vector W

Ejemplo: Leer los datos del arreglo M de longitud 50 y mostrarlos por pan- Inicio
talla, uno a uno. Suma ← 10
Para i ← 1 Hasta 10 Hacer
Escribir(‘Los valores del arreglo son : ‘) Leer(W[i])
Para i ← 1 Hasta 50 Hacer Fin_para
Leer(Mi] Para i ← 1 Hasta 10 Hacer
Escribir(M[i]) Suma ← Suma + W[i]
Fin_para Fin_para
Promedio ← Suma/10
Escribir(Suma, Promedio)
Los elementos de un vector se pueden leer también con ciclos Mientras o Fin
Repite.

Ejemplo:
i←1
Mientras i <= 50 Hacer ACTUALIZACIÓN
Leer(M[i])
Escribir(M[i]) La actualización del vector consiste en la asignación de valores a los ele-
i ← i +1 mentos del vector ya sea de manera individual o a través del procesamiento
Fin_mientras general del vector.

Ejemplo 1: Almacenar en el arreglo M de longitud 20, los valores leídos por


teclado.
RECORRIDO O ACCESO SECUENCIAL
Inicio
Se accede a los elementos de un vector para introducir datos en él (asignar Para x ← 1 hasta 20 hacer
valores ó leer) y para ver su contenido (escribir). A la operación de efectuar Leer(valor)
una acción general sobre todos los elementos de un vector se le denomina M[x] ← valor
recorrido del vector. Estas operaciones se realizan utilizado estructuras Fin-para
repetitivas, cuyas variables de control (por ejemplo, i) se utilizan como Fin

-26-
ORDENAMIENTO BÚSQUEDA

El ordenamiento de un vector es el acomodo de los valores de los elementos Es el proceso que localiza la posición (subíndice) del elemento que contiene
del vector de acuerdo a un criterio específico. el valor deseado o requerido. Se puede utilizar para determinar si un valor
dado se encuentra o no en un vector.
Ejemplo:
• Ordenar los valores del arreglo NUM de 20 elementos de tipo ente- Ejemplo 1: Búsqueda del elemento “Manzana” dentro del vector FRUTAS.
ro de menor a mayor. Imprimir si se encuentra o no y dado el caso su posición.

• Ordenar los elementos de arreglo ALUMNOS en orden alfabético Inicio


Encontrado = Falso
Para resolver estos problemas, se puede utilizar el método de ordenamiento // Lectura del valor a buscar
por selección, el cual consiste en encontrar el elemento más pequeño de la Leer(fruta)
lista y colocarlo en la primera posición, luego se encuentra el siguiente ele- //Búsqueda del valor en el vector
mento más pequeño y se lleva a la segunda posición. Se continúa el proceso Para i ← 1 Hasta 10 Hacer
hasta llegar a la posición penúltima del vector. Si frutas[i] = fruta entonces
Para obtener el elemento más pequeño se compara el primer valor con cada Encontrado Å Verdadero
uno de los restantes y cada vez que se encuentra un valor más pequeño se Posición Å i
intercambian los valores. Fin_si
Fin_para
Ejemplo: // Notificación de los resultados de la búsqueda
Si Encontrado = Verdadero Entonces
Inicio Escribir(‘Fruta encontrada en la posición: ‘, posi-
// Encontrar la posición del menor valor cion)
// Se utilizan dos índices: J para el elemento fijo y Sino
// K para recorrer los elementos que se comparan. Escribir(‘Fruta no encontrada‘)
Para J ← 1 Hasta 4 Hacer Fin_si
Para K ← J + 1 Hasta 5 Hacer Fin
Si Num[K] < Num[PosMenor] Entonces
// Intercambiar valores en el
vector
aux Å Num[J]
Num[J] Å Num[k]
Num[k] Å aux ARREGLOS BIDIMENSIONALES O MATRICES
Fin_si
Fin_ Para Un arreglo bidimensional (de dos dimensiones) es un vector de vectores.
Fin_Para Es un conjunto de elementos, todos del mismo tipo, en los que el orden de
Fin los componentes es significativo y en el que se necesitan dos subíndices

-27-
para definir cualquier elemento. Un arreglo bidimensional se denomina • Asignación
también tabla o matriz. • Lectura/Escritura
• Actualización
Los arreglos bidimensionales se referencian con dos subíndices. El pri- • Recorrido o acceso secuencial
mero se refiere a la fila y el segundo se refiere a la columna. Así en una • Ordenamiento.
matriz M de dimensión 3 x 4 (3 filas por 4 columnas), una representación
sería: Ejemplo 1: Recorrido de una matriz A de 3x4 de tipo entero para inicializar
sus elementos con el valor 0.

Inicio
para i ← 1 hasta 3 hacer
para J ← 1 hasta 4 hacer
A[i,j] Å 0
Fin_para
Fin_para
Fin

Ejemplo 2: Inicializar los elementos de una matriz M de 5x7 de tipo entero


con el valor de la suma de los subíndices que determinan su posición, es
decir, M[i,j] = i + j.

Donde: Inicio
El elemento M[1,1] se refiere al elemento situado en la fila 1 columna 1 Para i ← 1 hasta 5 hacer
Para j ← 1 hasta 7 hacer
El elemento M[3,2] se refiere al elemento situado en la fila 3 columna 2 M[i,j] Å i + j
Fin_para
El elemento M[2,3] se refiere al elemento situado en la fila 2 columna 3 Fin_para
Fin
La matriz M almacena hasta 12 [3x4] elementos.
Ejemplo 3: Recorrer una Tabla de 100x200 de tipo real para determinar la
posición del elemento más grande.

Inicio
OPERACIONES CON MATRICES Max Å Tabla[1,1]
imax Å 1
Las operaciones que se pueden realizar sobre las matrices son básica- jmax Å 1
mente las mismas que con los vectores, es decir: Para i ← 1 hasta 100 hacer

-28-
Para j ← 1 hasta 200 hacer Ejemplo: Inicializar un arreglo multidimensional MulDim de 3x4x7x12 de
Si Tabla[i,j] > Max entonces tipo entero asignando a cada elemento el valor 0.
Max Å Tabla[i,j]
imax Å i Inicio
jmax Å j Para i ← 1 hasta 3 hacer
fin_si Para j ← 1 hasta 4 hacer
Fin_para Para k ← 1 hasta 7 hacer
Fin_para Para l ← 1 hasta 17 hacer
Escribir(‘El elemento mayor es : ‘) MultiDim(i,j,k,l) = 0
Escribir(‘Tabla(‘,imax, ’,‘, imax,‘)= ‘,Max) Fin_para
Fin Fin_para
Fin_para
ARREGLOS MULTIDIMENSIONALES Fin_para
Fin
Los arreglos multidimensionales son aquellos que tienen tres o mas
dimensiones. En general un arreglo multidimensional es un conjunto de
elementos, todos del mismo tipo, en los que el orden de los componentes es
significativo y en el que se necesitan tantos subíndices como dimensiones
tenga para definir cualquier elemento.

OPERACIONES CON ARREGLOS MULTIDIMENSIONALES

Las operaciones que se pueden realizar sobre los arreglos multidimensiona-


les son básicamente los mismos que con los vectores y las matrices, es de-
cir:

• Asignación
• Lectura/Escritura
• Actualización
• Recorrido o acceso secuencial
• Ordenación

-29-
HISTORIA

III En 1970 Ken Thompson de los laboratorios Bell se había propuesto desarro-
llar un compilador para el lenguaje Fortran que corría en la primera versión
del sistema operativo UNIX tomando como referencia el lenguaje BCPL; el
resultado fue el lenguaje B (orientado a palabras) que resulto adecuado para
la programación de software de sistemas. Este lenguaje tuvo la desventaja
de producir programas relativamente lentos.
EL LENGUAJE DE PROGRAMACIÓN C En 1971 Dennis Ritchie, con base en el lenguaje B desarrolló NB que luego
cambio su nombre por C; en un principio sirvió para mejorar el sistema
UNIX por lo que se le considera su lenguaje nativo. Su diseño incluye una
sintaxis simplificada, la aritmética de direcciones de memoria (permite al
programador manipular bits, bytes y direcciones de memoria) y el concepto
de apuntador; además, al ser diseñado para mejorar el software de sistemas,
se busco que generase códigos eficientes y uno portabilidad total, es decir el
que pudiese correr en cualquier máquina. Logrados los objetivos anteriores,
C se convirtió en el lenguaje preferido de los programadores profesionales.

En 1980 Bjarne Stroustrup de los laboratorios Bell de Murray Hill, New


Jersey, inspirado en el lenguaje Simula67 adiciono las características de la
programación orientada a objetos (incluyendo la ventaja de una biblioteca
de funciones orientada a objetos) y lo denomino C con clases. Para 1983
dicha denominación cambio a la de C++. Con este nuevo enfoque surge la
nueva metodología que aumenta las posibilidades de la programación bajo
El lenguaje C reúne características de programa- nuevos conceptos.
ción intermedia entre los lenguajes ensamblado-
res y los lenguajes de alto nivel; con gran poderío
basado en sus operaciones a nivel de bits (propias
de ensambladores) y la mayoría de los elemen-
tos de la programación estructurada de los len-
guajes de alto nivel, por lo que resulta ser el len-
guaje preferido para el desarrollo de software de
sistemas y aplicaciones profesionales de la pro-
gramación de computadoras.

- 31 -
1.1. IDENTIFICADORES ESTANDAR

Los identificadores son nombres dados a constantes, variables, tipos, fun-


ciones y etiquetas de un programa.

1
ELEMENTOS DEL LENGUAJE C
Un identificador es una secuencia de letras (mayúsculas y/o minúsculas),
dígitos (0,1,...,9) y el caracter especial de subrayado ( _ ). El primer caracter
de un identificador debe de ser un caracter letra o el carácter de subrayado.

Las letras pueden ser mayúsculas o minúsculas y se consideran como carac-


teres diferentes.

Por ejemplo:
Suma
Calculo_numeros_primos
ab123
_ordenar
i

1.2 PALABRAS RESERVADAS DEL LENGUAJE C (ANSI-C)

Las palabras reservadas son identificadores predefinidos que tienen un signi-


ficado especial para el compilador C. Un identificador definido por el usua-
rio, no puede tener el mismo nombre que una palabra reservada.

auto continue else for long sizeof


typedef wile break default num
goto register static union main
case do extern if return
struct unsigned char double float
Un programa en C se conforma como una colec- int short switch void signed
ción de procedimientos (a menudo llamadas fun-
ciones, aunque no tengan valores de retorno). Es- Algunas versiones de compiladores pueden tener palabras adicionales, asm,
tos procedimientos contienen declaraciones, sen- ada, fortran, pascal, etc. Cabe hacer mención que el lenguaje que analizare-
tencias, expresiones y otros elementos que en mos es el ANSI C, y éste debe de compilarse en cualquier compilador y
conjunto indican a la computadora que realice cualquier plataforma, que soporte el ANSI C (LINUX, UNIX, MS-DOS,
cierta acción. etc.).

- 32 -
1.3 ESTRUCTURA DE UN PROGRAMA Todo programa en C debe contener una función nombrada main(), donde el
programa comienza a ejecutarse. Las llaves ({}) que incluyen el cuerpo de
Como en todos los lenguajes siempre es bueno comenzar con un programa, esta función principal, definen el principio y el final del programa.
simple y sencillo.
Un programa C, además de la función principal main(), consta generalmente
/* Un primer programa en C*/ de otras funciones que definen rutinas con una función específica en el pro-
#include <stdio.h> grama.
void main(void)
{ • Estructura general de un programa en C:
printf(''Hola Puebla”); • Directrices para el preprocesador
return; • Definición de constantes
} • Definición de variables globales
• Declaración de funciones (función prototipo o declaración forward)
Explicación: • Función main
La primera línea dice que se debe de incluir un archivo de cabece-
ra, este archivo de cabecera contiene todas las funciones de entra- Los comentarios en C son cadenas arbitrarias de símbolos coloca-
da y salida (por ejemplo el printf, es una función que imprime da- dos entre los delimitadores /* y */ .
tos y/o letreros en pantalla), la segunda línea de código es el inicio
que todo programa en C debe de tener (función main), la tercera
línea imprime en pantalla el letrero hola Puebla, y después finaliza Ejemplos:
el programa, en las dos líneas finales se da por concluido el pro- /* Comentarios */
grama en C, la palabra return se utiliza para regresar un valor, en /* Este es un comentario
este caso es el término de la función main y no se regresa ningún muy largo ya que ocupa mas de un renglón */
valor.
Ejemplo de la estructura general de un programa en C:
Un programa en C está formado por una secuencia de caracteres que inclu-
yen: #include <stdio.h> /* Directrices del preprocesador */
Letras Minúsculas : a, b, ...., z #include <stdlib.h>
Letras Mayúsculas : A, B, ..., Z #define SU 100 /* Definición de constantes */
Dígitos : 0, 1, ..., 9 int x,y; /* Variables globales */
Caracteres Especiales : “, !, #, ”, $, %, &, /, (, etc. main() /* Programa principal */
{ /* Inicia el programa principal */
A partir de estos podemos generar cualquier programa en C, hay que tener float real; /* Variables locales */
cuidado por que algunos caracteres, tiene significados distintos, es decir, /* Acciones */
depende del contexto donde se utilizan. printf (“\n Dame dos numeros enteros: ”);
scanf(“%d%d”, &x,&y) ;
Un programa fuente C es una colección de cualquier número de directrices real=SU + x/y;
(inclusión de archivos), declaraciones, definiciones, expresiones, sentencias printf(“\n Resultado: %f”,real);
y funciones. } /* Fin del programa principal */

- 33 -
1.4. TIPOS DE DATOS ESTÁNDAR DEL LENGUAJE C
Combinaciones
Los tipos básicos del lenguaje son:
Carácter: Este tipo de dato se declara con la palabra reservada char y ocu-
pa un byte en memoria, con un byte se pueden representar 256 símbolos char 8 bits ASCII -128 a 127
posibles. unsigned char 8 bits ASCII 0 a 255

Real: Este tipo de datos se declara con la palabra reservada double o float, signed char 8 bits ASCII -128 a 127
si se utiliza la primera, entonces la variable que se declare ocupa 8 bytes de int 16 bits -32768 a 32767
memoria y si se utiliza la segunda entonces la variable que se declare utiliza
4 bytes de memoria. unsigned int 16 bits 0 a 65535
signed int 16 bits -32768 a 32767
Entero: Este tipo de datos se declara con la palabra reservada int y tiene
típicamente la misma longitud en bits que los registros del procesador de short int 16 bits -32768 a 32767
cada máquina. Por ejemplo, ocupa 2 bytes de memoria para equipos de 16
bis (8088, 80286) y 4 bytes en equipos de 32 bits (80486, Pentium, Celeron , unsigned short int 16 bits 0 a 65535
Xeon, Athlon, Duron). signed short int 16 bits -32768 a 32767
En la Tabla 1 se muestran todos los tipos de datos estándar en el lenguaje C.
long int 32 bits -2147483648 a 2147483647
1.4.1. Acerca de los tipos de datos reales ( flotantes ) signed long int 32 bits -2147483648 a 2147483647
unsigned long int 32 bits 0 a 4294967295
C proporciona los tipos flotantes float y double para manejar números de
la forma 1.7, 0.0001, 3.14159. También existe una forma exponencial para float 32 bits 6 dígitos de precisión 3.4E-38 a 3.4E+38
representar un número, por ejemplo, 1.092332e5. La correspondiente nota-
ción científica de este número es: double 64 bits 12 dígitos de precisión 1.7E-308 a 1.7E+308
long double 64 bits 12 dígitos de precisión 1.7E-308 a 1.7E+308
1.092332e5 = 1.092332*10*10*10*10*10
= 1.092332*100000 Tabla 1. Tipos de datos estándar
= 109233.2
1.4.2. Acerca del tipo de datos char
De forma similar se tiene el número 1.092332e-3, esto significa que el punto
decimal se desplaza 3 lugares a la izquierda y se tiene el siguiente valor Las constantes y las variables de tipo char se usan para representar caracte-
0.001092332. res y cada carácter se almacena en un byte.
El número 333.777e.22 se puede descomponer de la siguiente forma: Un byte esta compuesto de 8 bits, el cual es capaz de almacenar 2 a la 8 o
256 valores diferentes, pero solo un grupo pequeño de ellos es realidad
Parte entera = 333 representa a un conjunto de caracteres imprimibles.
Parte fraccionaría = 777
Parte exponencial = e-22

- 34 -
A continuación se muestran algunas constantes enteras y sus valores enteros Las variables y las constantes son los objetos que manipulan un pro-
correspondientes. grama. En general se deben declarar las variables antes de usarlas.

Constante de tipo char Valor entero correspondiente 1.5.1. Declaración de variables


‘a’ 97
‘b’ 98 Una variable en C se declara de la siguiente manera:
....
‘z’ 117 tipo identificador [, identificador , ...., identificador] ;
donde ,
‘0’ 48 tipo :determina el tipo de la variable (char, int, ...).
‘1’ 49 identificador: indica el nombre de la variable. Los corchetes ([ ])
‘2’ 50 indica que se pueden definir en línea mas de una variable del mis-
... ... mo tipo separadas por coma (,) y terminando con punto y coma (;).
‘9’ 57
Por ejemplo:
int i,j,k;
1.4.3. Acerca de las cadenas float largo, ancho;
char c;
Una cadena es una secuencia de caracteres entre comillas “ ”.Obsérvese que
“ es un solo caracter y no dos. Si el caracter (“) tiene que aparecer en una El inicio de un programa en C se ve de la siguiente manera:
cadena, éste debe de ir precedido por el carácter \.
main ( )
Ejemplos: {
“Una cadena de texto”
“ ” declaración de variables;
“z”
“x-x-0-.1-basura” proposiciones;
“Una cadena con \” comillas”
“a+b=suma; x=cos(y)” return;
“” /*cadena nula*/
}
1.5. DECLARACIÓN DE VARIABLES Y CONSTANTES
Las llaves ‘{‘ y ‘}’ encierran un bloque de proposiciones y se usan
Una variable es un identificador que tiene asociado un valor que puede para enmarcar declaraciones y proposiciones. Si hay declaraciones, enton-
cambiar a lo largo de la ejecución del programa. ces estas deben de ir antes de las proposiciones. Las declaraciones tiene
dos objetivos:
Las constantes en C se refieren a valores fijos que no pueden ser alterador
por un programa y pueden ser de cualquier tipo. 1. Piden al compilador que separe la cantidad de memoria necesaria
para almacenar los valores asociados con las variables.

- 35 -
1.6.1 Operadores
2. Debido a que se especifican los tipos de datos asociados con las va-
riables, éstas permiten al compilador instruir a la máquina para que Un operador es un símbolo que indica al compilador que se lleven a cabo
desempeñe correctamente ciertas operaciones. específicas manipulaciones matemáticas o lógicas. El C tiene tres clases de
operadores: aritméticos, relacionales y lógicos y de bits. Además de otros
1.5.2. Declaración de CONSTANTES operadores especiales.

Las constantes en C pueden ser: 1.6.2.Asignación simple

Números reales Números enteros Cadenas Carácter El signo de igualdad (=) es el operador básico de asignación en C. Un
3.10 1234 “hola C.U.” ‘a’ ejemplo de una “expresión” de asignación es: i = 7. A la variable i se le
0.987 -10 “” ‘#’ asigna el valor de 7 y la expresión como un todo toma ese valor.

Una constante (cualquier tipo de constante) en C se define de la siguiente Las proposiciones de asignación simples tiene la siguiente sintaxis:
manera:
variable = expresión;
#define identificador valor
donde,
identificador es el nombre de la constante
valor es el valor asociado a la constante 1.6.3 Proposiciones
Ejemplo:
Cuando la expresión va seguida de un punto y coma (;) se convierte en una
#define entero 10 proposición.
#define real 1.09982
#define cad “Estoy definiendo una constante que se llama cad “ Ejemplo de proposiciones:
#define car ‘a’
i=7;
x=3.1+sin(10.8);
1.6 EXPRESIONES, PROPOSICIONES Y ASIGNACIONES printf(“hola”);

Las expresiones son combinaciones de constantes, variables, operadores y Las siguiente proposiciones son válidas pero no tienen ningún significado
llamados a funciones. útil:

Algunos ejemplos de expresiones son: 3.10;


tan(1.8) a+b;
a+b*3.0*x-9.3242
3.77+sen(3.14*98.7)

- 36 -
1.6.4. Operadores Aritméticos Operadores Asociatividad
-(unuario) derecha a izquierda
Los operadores aritméticos binarios se muestran en la siguiente tabla 2. *,/,% izquierda a derecha
+,- izquierda a derecha
Operador Operación = derecha a izquierda
Tabla3. Prioridad de los operadores aritméticos
+ Suma. Los operandos pueden ser enteros o reales
- Resta. Los operandos pueden ser enteros o reales Los operadores de una misma línea como *, /, %, tienen la misma prioridad
* Multiplicación. Los operandos pueden ser enteros o reales y ésta es mayor que la prioridad de las líneas inferiores. La regla de asocia-
/ División. Los operandos pueden ser enteros o reales. Si ambos tividad que rige a los operadores con la misma prioridad se muestra en la
operandos son enteros el resultado es entero. En el resto de los columna de la derecha
casos el resultado es real.
% Módulo o resto de la división entera. Los operandos tienen que Ejemplo:
ser enteros.
-(unario) Menos unario. Los operadores pueden ser enteros o reales. Encontrar la expresión equivalente y el valor de la expresión, utilizando las
Tabla 2. Principales operadores aritméticos siguientes declaraciones y asignaciones. También se debe de utilizar la tabla
de prioridad mencionada anteriormente.
Ejemplos:
int a=10, b=3, c; int a, b, c, d; /*Se declaran 3 variables de tipo entero*/
float x=2.0, y;
a=2; b=-3; c=7; d=-19;
y = x +a; /* El resultado es 12.0 de tipo float */
c = a / b; /* El resultado es 3 de tipo int */ Expresión Expresión Equivalente Valor
c = a % b; /* El resultado es 1 de tipo int */ a/b (a / b) 0
a = -b; /* El resultado es –3 */ b/b/a (b / b) / a -1
c%a (c%a) 1
1.6.4.1. Prioridad de los operadores aritméticos a%b (a%b) ?
d/b%a ((d/b)%a) 0
-a*d (-a)*d 38
Los operadores tiene reglas de prioridad y asociatividad, estas reglas deter- a%-b*c A%-(b*c) 14
minan la forma de evaluar las expresiones. Al evaluarse en primer lugar las 9/c+-20/d (9/c)+ ( (-20)/d) 2
expresiones que se encuentran entre paréntesis (), éstas pueden emplearse -d%c-b/a*5+5 (((-d)%c)-((b/a)*5))+5 15
para aclarar o cambiar el orden de ejecución de las operaciones que se de- 7-a%(3+b) 7-(a%(3+b) Error
sean realizar. ---a - (- (- a)) -2
A= b= c= -33 A= (b= (c= -33)) a=-33 y b=-33
La tabla 3. muestra las reglas de prioridad y asociatividad para los operado-
res aritméticos vistos hasta este momento.

- 37 -
1.6.5. Operadores de Relación y Lógicos Operador Operación Ejemplo
&& AND. Da como resultado el valor lógico 1 (z<x) && (y>w)
Al igual que los operadores anteriores, los operadores de relación y lógicos si ambos operandos son distintos de 0. Si
tienen reglas de prioridad y asociatividad que determinan de forma exacta la uno de ellos es cero el resultado es el valor
evaluación de las expresiones que los incluye. lógico 0. Si el primer operando es igual a
cero, el segundo operando no es evaluado.
Un operador relacional se refiere a la relación entre unos valores con otros, || OR. El resultado es cero si ambos operan- (x= =y) || (z!=p)
y un operador lógico se refiere a las formas en que estas relaciones pueden dos son 0. Si uno de los operandos tiene un
conectarse entre sí. valor distinto de 0, el resultado es 1. Si el
primer operando es distinto de 0, el segun-
Los Operadores de Relación son binarios (tabla 4). Cada uno de ellos toma do operando no es evaluado.
dos expresiones como operando y dan como resultado el valor int 0 o el ! NOT. El resultado es 0 si el operando tiene !a
valor int 1 (tómese en cuenta que en el lenguaje C cualquier valor distinto de un valor distinto de cero, y 1 en caso con-
0 es verdadero y el cero es falso). trario. El resultado es de tipo int. El ope-
rando puede ser entero, real o un apunta-
dor.
Operador Operación Ejemplos Tabla 5. Operadores lógicos
< Primer operando menor que el segundo a<3
Ejemplo:
> Primer operando mayor que el segundo b>w Operador de Negación
<= Primer operando menor o igual que el -7.7<=-99.335
segundo Expresión Valor
>= Primer operando mayor o igual que el -1.3>=(2.0*x+3.3) !5 0
segundo !a Depende del valor de a
== Primer operando igual que el segundo c= =’w’ !’z’ 0
!= Primer operando distinto del segundo x!=-2.77 !(x+7.7) Depende del valor de x
Tabla 4. Operadores de Relación Los operandos pueden ser de tipo entero, !!5 1
real o apuntador.

Los Operadores Lógicos (tabla 5) al igual que los operadores anteriores Ejemplo:
cuando se aplican a expresiones producen los valores int 0 o int 1. La nega-
ción lógica es aplicable a una expresión arbitraria. Los operadores lógicos Operadores Lógicos. Supóngase que se tienen las siguientes decla-
binarios && y || también actúan sobre expresiones. raciones y asignaciones:

char c;
int i,j,k;
double x,y;

c=’w’; i=j=k=3; x=0.0; y=2.3;

- 38 -
Expresión Expresión Equivalente Valor Ejemplo:
i && j && k (i && j) && k 1 Multiplicación y división mediante operaciones de desplazamientos
X && i || j-3 (x && i) || j-3 0
X || i && j-3 (x|| i) && (j-3) 0 char X; X después de cada Valor de X
I<j && x<y (i<j) && (x<y) 0 ejecución
I<j || x<y (i<j) || (x<y) 1 X=7; 00000111 7 (Asignación)
I= =j && x<=y (i= =j) && (x<=y) 1 X << 1; 00001110 14 (X * 2)
I= = 2 || j= = 4 ||k= =6 (i= = 2) || (j= = 4) ||(k= =6) 0 X << 3; 01110000 112 (X * 8)
X << 2; 11000000 192 (X * 4, con pérdida del bit más signi-
ficativo)
X >> 1; 01100000 96 (X / 2)
1.6. 6 Operadores de manejo de bits X >> 2; 00011000 24 (X / 4)

Los operadores (tabla 6) para este tipo de operaciones tienen que ser de tipo
entero de uno o dos bytes o char, no pueden ser reales.
1.6.7. Operadores de asignación
Operador Operación
~ Complemento a 1. El operando tiene que ser entero Lista de operadores de asignación
& AND a nivel de bits
| OR a nivel de bits Operador Operación
^ XOR a nivel de bits ++ Incremento
<< Corrimiento (desplazamiento) a la izquierda -- Decremento
>> Corrimiento (desplazamiento) a la derecha
= Asignación simple
Tabla 6. Operadores para el manejo de bits
+= Suma más asignación
Ejemplo: -= Resta más asignación
|= Operación OR sobre bits más asignación
int a=0777, m=2;
a=a & 0177; /* Pone a cero todos los bits de a excepto los 7 bits de &= Operación AND sobre bits más asignación
menor peso */ >>= Corrimientos a la derecha más asignación
<<= Corrimientos a la izquierda más asignación
a=a | m; /* pone a uno todos los bits de a que están a 1 en m */
a = a & ~077; /* pone los 6 bits de menor peso de a, a 0 */ *= Multiplicación más asignación
/= División más asignación
%= Módulo más asignación
Tabla 7. Operadores de asignación

- 39 -
Los operadores de incremento ++ y decremento -- son unarios y tienen la 1.6.8. Tabla final de prioridad y orden de evaluación
misma prioridad que el operador unario - , éstos se asocian de derecha a
izquierda. Tanto ++ como -- se pueden aplicar a variables, pero no a cons- Una expresión entre paréntesis, siempre se evalúa primero. Los paréntesis
tantes o a expresiones. Además pueden estar en la posición de prefijos o tienen mayor prioridad y son evaluados de más internos a más externos.
sufijos, con diferentes significados posibles.
Incremento: ++ añade 1 a una variable El operador coma (,) hace que las expresiones se evalúen de izquierda a
Decremento: - - resta 1 a una variable derecha.
Ejemplo:
Operadores Asociatividad
A+=3 es equivalente a A=A+3
() Izquierda a derecha
k*=3+x es equivalente a k=k*(3+x)
-(unario), ++, --, ~, !, *, &(los últimos dos como Derecha a izquierda
x = x+1; equivalente a ++x; operadores apuntadores)
x = x-1; equivalente a - -x; *,/,% Izquierda a derecha
+,- Izquierda a derecha
Estos operadores pueden ir antes o después de la variable. <,<=,>,>= Izquierda a derecha
x = x+1; ++x; x = x-1; - -x; = =, != Izquierda a derecha
x++; x - -; & Izquierda a derecha
^ Izquierda a derecha
| Izquierda a derecha
• Antes de la variable: Si el operador ++ o - - aparece antes del ope- && Izquierda a derecha
rando, entonces el operando se incrementa o decrementa antes de || Izquierda a derecha
que se evalúe la expresión. =, +=, -=, *=, <<=, >>=, %= Derecha a izquierda
, (operador coma) Izquierda a derecha
Ejemplo: Tabla 8. Tabla final de todos los operadores en C, así como su prioridad y
x = 10; su asociatividad
y = ++x; ==> y = 11;
Los operadores que se encuentran en las líneas superiores tiene más priori-
• Después del operando: Si el operador ++ o -- aparece después del dad que los operadores de las líneas inferiores y los operadores que se en-
operando, entonces primero se evalúa la expresión con el valor ac- cuentran en la misma línea tiene la misma prioridad y si existen operadores
tual del operando y posteriormente se incrementa o decrementa el con la misma prioridad en una expresión, éstos se asocian según la columna
operando. de la derecha de la tabla anterior.
Ejemplo:
x = 10;
y = x++; ==> y =10;
en ambos casos x = 11;

- 40 -
1.6.8.1. Otros operadores formato bajo el cual se requiere la salida de la información
(datos) hacia pantalla
El operador de indirección (*) accede a un valor indirectamente a través de
un apuntador. El resultado es el valor direccionado por el operando. lista de argumentos
representa el valor o valores a escribir en la pantalla. Una
El operador de dirección-de (&) indica la dirección de su operando. Este especificación de formato está compuesta por:
operador no se puede aplicar a un campo de bits perteneciente a una estruc-
tura o a un identificador declarado con el especificador register. % [flags] [width] [.prec] [F|N|h|l|L] tipo_de_dato

Cada uno de los datos que se desee mandar a imprimir de-


be de ir antecedido por el caracter % y después debe de
1.7. INSTRUCCIONES DE ENTRADA Y SALIDA venir (en este orden) lo siguiente (no es necesario poner
todo, lo que se encuentra entre corchetes es opcional ) :
Las operaciones de entrada y salida no forman parte del conjunto de senten- Componente Que se especifica
cias del lenguaje C, sino que pertenecen al conjunto de funciones de la libre- [flags] (Opcional) Justificación, etc.
ría estándar de entrada y salida de C. Por ello, todo programa que deberá [width] (Opcional) Número de dígitos significativos parte entera
contener la línea (o líneas) iniciales: [.prec] (Opcional) Número de dígitos significativos parte real
[F|N|h|l|L] (Opcional) Modificadores de salida
#include < stdio.h > N = near apuntador h = entero corto
F = far apuntador l = entero largo
Esta línea le dice al compilador que incluya la librería stdio.h en el progra- L = real largo
ma permitiendo así la entrada y salida de datos. tipo_de_dato (requerido), el tipo de dato puede ser:
c = imprime un carácter
Las siguientes funciones son algunas de las más utilizadas para entrada y d = imprime un entero
salida de datos. e = notación cientifica
s = imprime una cadena
printf, scanf, getch, getchar, puts, gets, f = decimal en punto flotante
Todas y cada una de ellas tiene una sintaxis que las identifica. Ejemplo:
1.7.1 Salida de datos utilizando la función printf ( ) printf("hola Puebla son las %d \n", tiempo);
Explicación:
printf(cadena de control, lista de argumentos) en este caso se pone el letrero “hola Puebla son las” (cadena de
control) y se indica una salida de tipo entero (%d), después se im-
cadena de control prime la variable (lista de argumentos, en este caso solo hay un
especifica como va a ser la salida. Es una cadena delimita- argumento o variable la cual se llama tiempo), después de impri-
da por comillas (“ “), formada por caracteres ordinarios, mir el valor de la variable tiempo hará un cambio de línea ( se-
secuencias de escape (ver tabla 9) y especificaciones de cuencia de escape \n).

- 41 -
Ejemplo: esta formada por códigos de formato de entrada, que están
n1=5; precedidas por un signo % y encerrados entre comillas “ “
n2=6.7; dobles. Ver tabla 10.
printf(“El dato 1 es: %d y El dato 2 es: %f \n”,n1,n2); Código Significado
c Lee un único carácter
d Lee un entero decimal base 10
Explicación: i Lee un entero en base 10, 16 u 8
En este ejemplo el primer formato %d corresponde a un número f Lee un número en punto flotante
entero (n1) y el %f corresponde a un número real (n2), insertándo- e Lee un número en punto flotante
se un cambio de línea al final (\n).
h Lee un número entero corto
Salida: El dato 1 es: 5 y El dato 2 es: 6.700000
s Lee una cadena de caracteres
o Lee un entero en octal
Secuencia Nombre
x Lee un número hexadecimal
\n Nueva línea
Tabla 10. Códigos de formato de scanf()
\t Tab horizontal
\v Tab vertical (solo para impresora)
lista de argumentos
\b Backspace (retroceso) representa el valor o valores a escribir en la pantalla.
\r Retorno de carro
\f Alineación de página (solo para impresora) Una especificación de formato esta compuesta por:
\a Bell (sonido) Símbolo Significado
\´ Comilla simple * Un asterisco a continuación de % suprime la
\” Comilla doble asignación del siguiente dato en la entrada.
\0 Nulo Ancho Máximo numero de caracteres a leer de la entra-
\\ Backslash (barra hacia atrás) da. Los caracteres en exceso no son tenidos en
\ ddd Carácter ASCII. Representación Octal cuenta.
\ xdd Carácter ASCII. Representación hexadecimal f Indica que se quiere leer un valor apuntado por
Tabla 9. Secuencias de escape en lenguaje C una dirección far(dirección segmentada).
N Indica que se quiere leer un valor apuntado por
1.7.2. Entrada de datos utilizando la función scanf( ) una dirección near (dirección dada por el valor
offset).
La función scanf( ) es una rutina de entrada de propósito general, que per- F y N no pertenecen al C estándar.
mite leer datos formateados y convertir automáticamente la información H Se utiliza como prefijo con los tipos d, i, n, o y x,
numérica a enteros o a flotantes por ejemplo. El formato general de esta para especificar en el argumento es short int, o
función es: con u para especificar un short unsigned int.
scanf (cadena de control, lista de argumentos); L Se utiliza como prefijo con los tipos d,i,n,o, y x,
cadena de control para especificar que el argumento es long int.
También se utiliza con los tipos e,f y g para
especificar un double.

- 42 -
Tipo El tipo determina si el dato de entrada es inter- Para leer datos de tipo cadena no lleva el operador de dirección &. Y tene-
pretado como un carácter, como una cadena de mos que cambiar el formato %s por %[^\n].
caracteres o como un número.

Ejemplo: Ejemplo: char nombre[40];


printf(“Da un numero : ”); scanf(“%[^\n]”, nombre);
scanf(“%d ”, &n); printf(“%s”,nombre);

Explicación: Entrada: Francisco Javier


La función scanf() lee un dato de tipo entero y es almacenado en la
variable n. El & es necesario para leer datos de tipo entero y real. Salida: Francisco Javier

Cuando se especifica mas de un argumento, los valores correspon- Si en lugar de especificar el formato %[^\n] se hubiera especifica-
dientes en la entrada hay que separarlos por uno o mas espacios en do el formato %s , el resultado hubiera sido: Francisco.
blanco (’ ’),tabuladores(\t) y cambios de línea(\n).

La función scanf() devuelve un entero correspondiente al número 1.7.3. Entrada de caracteres getchar( )
da datos leidos de la entrada.
Lee un carácter de la entrada estándar y avanza la posición de lectura al
Ejemplo: siguiente carácter a leer
Main()
{ int getchar(void);
int a,r;
float b; Ejemplo:
char c; car = getchar();
printf(“Introducir un valor entero, un real y un carácter \n => “);
r=scanf(“ %d %f %c \n”,a,b,c); Resultado: Lee un caracter y lo almacena en la variable car.
printf(“Numero de datos leidos: %d \n”,r);
printf(“ Datos leídos: %d %f %c \n”,a,b,c); 1.7.4. Salida de caracteres putchar( )
}
Escribe un carácter en la salida estándar en la posición actual y avanza a la
Salida: siguiente posición de escritura.
Introducir un valor entero, un real y un carácter
=> 12 3.5 x int putchar(int ch);
Numero de datos leidos: 3 Ejemplo:
Datos leídos: 12 3.500000 x putchar(ch);

Salida: escribe en pantalla el carácter contenido en la variable car

- 43 -
En el lenguaje C se incluyen las siguientes estructuras condicionales: if y
switch Y las sentencias de repetición : for, while y do/while.

Utilizamos indistintamente Proposiciones, Acciones y Sentencias


para referirnos al mismo concepto.

2
ESTRUCTURAS DE CONTROL DE PROGRAMAS
2.1. PROPOSICIÓN if

Una proposición if es una construcción de la forma:


if (expresión)
{
propocisiones; /* bloque */
}
proposición_siguiente;
donde:
expresión
debe ser una expresión numérica, relacional o lógica.
proposiciones
si se tiene solo una proposición entonces no es necesario poner lla-
ves {}, si tenemos varias acciones (proposiciones) a realizar cada
una de estas será separada por punto y coma (;).

Si el resultado de la expresión es verdadera (cualquier valor distinto de ce-


ro), se ejecutara la proposición o proposiciones (bloque).
Los programas que se suelen redactar en la prac-
tica incluyen algún tipo de elementos de control Si el resultado es falso entonces no se realiza ninguna acción y continua el
lógico, es decir, aparecen comprobaciones de flujo del programa a la siguiente línea de código después del if (proposición
condiciones que se sean ciertas o falsas (selección _siguiente).
o decisión). Además, los programas pueden re-
querir que un grupo de instrucciones se ejecute Ejemplos:
repetidamente un determinado número de veces o if (grado>=90)
hasta que satisfaga alguna condición lógica (ciclo printf(“\n FELICIDADES”):
de repetición).
printf(“\nSu grado es %d”, grado);

Explicación:
Se evalúa la expresión (grado >=90) si es verdadera se muestra el
letrero FELICIDADES y escribe “Su grado es : x“. Si la expresión
es falsa entonces solo se muestra el letrero “Su grado es : x”.

- 44 -
2.2. PROPOSICIÓN if-else 2.2.1. Anidamiento de sentencias if

Una proposición if-else es una construcción de la forma: Las sentencias if-else pueden estar anidadas. Esto quiere decir que como
proposión1 o proposición2, de acuerdo al formato anterior, puede escribirse
if (expresión) otra sentencia if.
{
proposición_1 /* bloque 1*/ if (expresion1)
} Sentencias1;
else { else if(expresión2)
proposición_2 /* bloque 2*/ Sentencias2;
} else if(expresión3)
proposición_siguiente; sentencia3;
….
Se evalua la expresión si es verdadera entonces se ejecuta el bloque 1 que else
puede estar formado por una proposición (no usar llaves {}) o un conjunto sentenciasN;
de proposiciones (usar llaves {}).
Si se cumple la expresion1, se ejecuta las sentencias1, si no se cumple se
Si la expresión es falsa entonces se ejecuta la proposición 2 o el bloque 2. examinan secuenciales las expresiones siguientes hasta el else, ejecutándose
las sentencias correspondientes al primer else if, cuya expresión sea cierta.
Si todas las expresiones son falsas, se ejecutan las sentenciasN.
Ejemplo:
if (x<=y) El if se puede anidar indistintamente después del if o después del else y
min=x puede ser en cada una de estas una sentencia o un conjunto de sentencias.
else
min=y; Ejemplo
if (a>b)
Expliación: printf(“%d es mayor que %d”,a,b);
En este segmento del programa se asigna a la variable min el me- else if (a<b)
nor de x y y. printf(“%d es menor que %d”,a,b);
else
Ejemplos: printf(“%d es igual a %d”,a,b);
if (a>=0)
printf("\el numero es positivo"); Cuando en una línea de programa aparecen anidadas sentencias if-else, la
else regla para diferenciar cada una de estas sentencias, es que cada else se co-
printf("\el numero es negativo"); rresponde con el if más próximo que no haya sido emparejado.

- 45 -
2.3. LA PROPOSICIÓN switch Ejemplo:

Esta proposición permite ejecutar una de varias acciones, en función del char ch;
valor de una expresión. ch=getchar();
switch (ch)
El formato de esta proposición es: {
case ‘0’:
switch (expresión-test) case ‘1’:
{ case ‘2’:
case constante1: sentencia; case ‘3’:
case constante2: sentencia; case ‘4’:
case constante3: sentencia; case ‘5’:
... case ‘6’:
default : sentencia case ‘7’:
} case ‘8’:
case ‘9’: printf(“\n Es un digito “);
donde: break;
case ‘ ‘:
expr-test case’\n’:
es una constante entera, una constante de caracteres o una expre- case’\t’: printf(“\n Es un separador”);
sión constante. El valor es convertido a tipo int. break;
sentencia default: printf(“\n Otro”);
es una sentencia simple o compuesta (bloque). break;
}
La sentencia switch evalúa la expresión entre paréntesis y compara su valor
con las constantes de cada case, si se cumple la expresión-test con alguna Explicación:
constante entonces se ejecutaran todas las sentencias después de la igualdad. Se almacena un caracter en ch y se evalua en el switch si este ca-
Usualmente se utiliza la sentencia break para romper la sentencia switch. rácter esta entre ‘0’ ..’9’ entonces se dice que es un digito y termi-
na el switch con el break. Si el carácter es un separador se indica
En el caso de que ninguna de las constantes coincida con la expresión-test con un letrero, pero si no es ninguno de los anteriores, entonces se
entonces se ejecuta la opción default. La sentencia switch puede incluir dice que es “otro”.
cualquier número de cláusulas case y opcionalmente la cláusula default.

- 46 -
2.4. PROPOSICIÓN for Ejemplo: Imprimir los múltiplos de 7 que hay entre 7 y 112
for (k = 7 ; k <= 112 ; k = k+7)
Cuando se desea ejecutar una acción simple o propuesta, repetidamente un Printf(“%d”,k)
número de veces conocido, es recomendable utilizar la proposición for.
Ejemplo: codificación de la suma de 10 números (del 1 al 10).
for (inicialización ; condición ; incremento)
{ suma=0;
sentencia1; for(i=0; i<=10; i++)
sentencia2; suma+=i;
... Explicación:
sentencian; Se inicializa la variable suma en 0 para ir acumulando la suma de
} los valores de i que van desde 0 hasta 10.

donde: Ejemplo: Se imprimen los números del 9 al 1.


inicialización: for (a=9 ; a >= 1 ; a--)
es una proposición de asignación que se utiliza para esta- Printf(“%d”,a);
blecer la variable de control. Se pueden utilizar varias va-
riables de control en un ciclo de repetición for.
condición: 2.5. PROPOSICIÓN while
es una expresión relacional o lógica que determina cuando
terminara el ciclo de repetición. Ejecuta una sentencia simple o compuesta ({}), cero o más veces, depen-
diendo del valor de una expresión.
incremento:
define como cambiara la variable de control o las variables while (expresión)
de control cada vez que cambia éste. {
sentencia1;
Estas tres partes tienen que estar separadas por puntos y comas (;). Si la sentencia2;
acción a repetir es solo una no es necesario incluir las llaves{}. sentencia3;
...
Ejemplo: Imprimir los números del 1 al 100. sentencian;
}
for (i =1 ; i <= 100 ; i++)
printf(“%d”,I); expresión:
es cualquier expresión numérica, relacional o lógica.
Literalmente dice: desde I igual a 1, mientras I sea menor o igual que 100, sentencia_i:
con incrementos de 1, escribir el valor de i. es una sentencia (no es necesario las llaves({}) o un con-
junto de sentencias.

- 47 -
Una proposición while se ejecuta mientras la expresión sea verdadera (cual- {
quier valor distinto de cero), en el momento en que se convierte en falsa la /* calcular la parte entera (z) de la raiz cuadrada */
expresión entonces se ejecuta la siguiente línea después del fin del while. z = sqrt(x *x + y * y);
while (y <= 50 && z <=50)
Ejemplo: {
char ca; /* comprobamos si z es suma de dos cuadrados perfectos*/
ca=0; if(z*z == x*x + y*y)
while (ca!=’A’) printf(“\n %10d %10d %10d”,z,x,y);
{ y++;
ca=getchar(); z = sqrt(x*x + y*y);
putchar(ca); }
} x++;
y = x;
Explicación: }
Se puede ver que ca se inicializo con cero, de esta forma podemos
iniciar el while, entonces se lee un carácter con la función get-
char() y se manda a escribir a la pantalla, a continuación se com- 2.6. PROPOSICIÓN do-while
para este valor de ca con ‘A’ si es distinta entonces vuelve a leer
otro carácter y a escribirlo en pantalla. Se estará entonces pidien- Ejecuta una sentencia o varias una o mas veces, dependiendo del valor de
do caracteres hasta que el carácter ca se igual a ‘A’ (haciéndose una expresión.
falsa la condición).
do
Ejemplo: Realizar un programa que nos imprima los números z, comprendi- {
dos entre 1 y 50, que cumplan la expresión: sentencia1;
sentencia2;
z2 = x2 +y2 sentencia3;
z,x e y son números enteros positivos. ...
sentencian;
/* Cuadrados que se pueden expresar como suma de otros dos cuadrados */ }while (expresión);
#include <stdio.h>
#include <math.h> donde:
main()
{ expresión
unsigned int x,y,z; es cualquier expresión numérica, relacional o lógica.
printf(“%10s %10s %10s \n”,”Z”,”X”,”Y”); Sentencia:
printf(“-----------------------------------------\n”); es una sentencia simple (sin usar llaves {}) o un bloque de senten-
x=1; cias
y=1;
while (x <= 50)

- 48 -
La sentencia do-while se ejecuta de la siguiente manera. Se ejecuta primero scanf(%lf”,&epsilon);
la sentencia o bloque de sentencias dentro del do. Se evalúa la expresión si do
es falsa (igual cero) termina la proposición do-while y si al evaluar la expre- {
sión el resultado es cualquier valor distinto de cero entonces se repite la antaprox = aprox;
sentencia o sentencias dentro del do {}. aprox = (n / antaprox + antaprox) / 2;
}while ( fabs (aprox – antaprox) >= epsilon);
Ejemplo: /* fabs calcula el valor absoluto de una expresión real */
int n; printf(“ \n \n La raíz cuadrada de %.2lf es %.2lf”,n, aprox);
do /* el .2 en el %.2lf nos toma solo dos cifras después del punto */
{ }
printf(“\n Da un número : “);
scanf(“%d”,&n); Entrada:
}while ( n>100); Número: 10
Raiz cuadrada aproximada: 1
Explicación: Coeficiente de error: 1e-6
se leeran números enteros de teclado hasta que se de un número
menor que 100. Salida:
La raiz cuadrada de 10.00 es 3.16
Ejemplo: Calcular la raíz cuadrada de un número n, por el método de New-
ton que dice:
2.7. CICLOS ANIDADOS
ri+1 = (n/ri + ri)/2
La proposición for al igual que el while y el do-while puede colocarse de-
La raíz calculada será válida, cuando se cumpla que: ntro de otro for (while o do-while) y entonces se dice que están anidados. En
abs(ri –ri+1) < = épsilon estos casos el ciclo de repetición más interno se ejecutara primero totalmen-
te, por cada valor del ciclo que lo contiene.
/* Raiz cuadrada de n por el metodo de Newton */
#include <stdio.h> Ejemplo: Escribir un programa que imprima un triangulo construido con
main() caracteres (#).
{
double n; /* número */ #
double aprox; /* aproximación a la raíz cuadrada */ # #
double antaprox; /* anterior aproximación a la raíz cuadrada */ # # #
double epsilon; /* coeficiente de error */ # # # #
printf(“Numero: “); # # # # #
scanf(“%lf”,&n);
printf(“Raiz cuadrada aproximada: “);
scanf(“lf”,&aprox);
printf(“Coeficiente de error: “);

- 49 -
/* construcción de un triangulo de n filas con # */ 2.9. LA FUNCIÓN exit()
#include <stdio.h>
main() Otra forma de terminar un ciclo de repetición desde dentro es utilizar la
{ función exit(). A diferencia con el break, la función exit terminará con la
unsigned int filas, columnas; ejecución del programa y regresara el control al sistema operativo.
unsigned int nfilas;
printf(“ Número de filas del triángulo : “); Ejemplo:
scanf(“%d”,&nfilas);
for (filas =1 ; filas <= nfilas ; filas++) for (i =0 ; i <= 1000 ; i++)
{ {
for ( columnas =1 ; columnas <= filas ; columnas++) printf(“ El valor de I es %d”,I);
printf(“# “); if (I>10) exit();
printf (“\n”); }
}
} Explicación: Aunque se ha elaborado una estructura para que la varable de
control I tome los valores de 0a 100 cuando llega al valor de 11 termina el
programa y solo escribirá de 0 a 10 para el valor de i.
2.8. LA SENTENCIA break

La sentencia break finaliza la ejecución de una proposición switch, for, 2.10. LA SENTENCIA continue
while y do-while en la cual aparece, saltándose la condición normal del
ciclo de repetición. La sentencia continue actúa al revés que la sentencia break: obliga a que
tenga lugar la siguiente iteración, saltándose cualquier código intermedio.
Ejemplo: Un break causará una salida sólo del ciclo más interno.
Ejemplo:
for (t=0;t<100; t++) do {
{ printf (“ Da un número : “);
contador=1; scanf(“%d”,&x);
do{ if (x<0) continue;
printf(“%d “,contador); printf(“ El número es %d”,x);
contador++; }while ( x != 100)
if (contador == 10) break;
}while(1) /* por siempre */ Explicación:
} aquí solo se imprimen los números positivos; introducir un número
negativo provocara que el control del programa se salte a evaluar
Explicación: la expresión x!=100.
se imprimirá 100 veces en la pantalla los números del 1 al 10. Ca-
da vez que se encuentre break, el control se devuelve al ciclo for,
terminando en do-while.

- 50 -
3.1. ARREGLOS

3
TIPOS ESTRUCTURADOS DE DATOS
Un arreglo es una estructura homogénea, compuesta por varias componen-
tes, todas del mismo tipo y almacenadas consecutivamente en memoria.
Cada componente puede ser accedido directamente por el nombre de la
variable del arreglo seguido de un subíndice encerrado entre corchetes ( [ ] )
.

3.1.1. arreglos unidimensionales

Un arreglo unidimensional es simplemente una lista con información del


mismo tipo. La declaración de un arreglo unidimensional es de la siguiente
manera:
tipo nombre [tamaño];
tipo
es uno de los tipos predefinidos por el lenguaje, es decir int, float,
etc.
nombre
es un identificador que nombra el arreglo .
tamaño
es una constante que especifica el numero de elementos del arreglo.

int X[6];
Posición

0 1 2 3 4 5
Muchas aplicaciones requieren el procesamiento X 78 12 8 -20 14 100
de múltiples datos que tienen características co-
munes y es conveniente colocarlos en estructuras Contenido del arreglo X en la posición 3
donde todos los elementos comparten el mismo
nombre. Para el caso de datos del mismo tipo se Explicación:
tienen los arreglos y para datos de tipos diferen- x es un arreglo de números enteros, para acceder a los datos en el
tes tenemos las estructuras. arreglo se hace mediante el nombre y la posición. Por ejemplo
para almacenar el –20 en la posición 3 del arreglo X se hace de la
forma: X[3]=-20; Para obtener algún valor del arreglo: C=X[2];
/* C=8 */

- 51 -
Los arreglo en C siempre inician en la posición 0. 3.1.1.1 Cadenas

Las cadenas en C son arreglos unidimensionales de tipo char. Por conven-


Ejemplos: ción una cadena en C se termina con el centinela de fin de cadena o carácter
nulo ‘\0’.
char x[20]; /* De esta forma se define una cadena de 20 caracteres, que se
manejan desde x[0] hasta x[19] */ Ejemplo: La siguiente es una función que dada una cadena de 4 elementos,
calcula el número de caracteres que contiene dicha cadena.
float z[40]; /* Es un arreglo donde cada uno de los datos es un numero real,
los datos se manejan desde z[0] hasta z[39]*/ main ( )
{
int vector[100]; /* Es una arreglo de enteros, los datos que se manejan son char * cadena ;
desde vector[0] hasta vector[99] */ int tam,i;
printf( “ dame la cadena ” );
Ejemplo: Sumar dos vectores de tamaño n. gets ( cadena );
#include <stdio.h> for ( i = 0; cad [ i ]! = “ \ 0 ”; i + +);
main( ) tam = i; / * tam= largo de una cadena * /
{ printf(“La cadena %s tiene %d elementos”,cadena, tam);
int n; /* donde n<=100 */ };
int a[100], b[100], c[100]; /* Arreglos */
int i; /* indice */
El lenguaje C nos proporciona una variedad de funciones para la
printf (“Numero de elementos a sumar: “); manipulación de las cadenas en la biblioteca string.h.
scanf(“%d”,&n);
printf (“Elementos del vector a \n”);
for (i=0; i<n; i++)
scanf(“%d”,&a[i]);
printf (“Elementos del vector b \n”); 3.1.2. Arreglos bidimensionales
for (i=0; i<n; i++)
scanf(“%d”,&b[i]); A los arreglos bidimensionales generalmente se les llaman tablas o matri-
printf (“Suma de vectores \n”); ces. Para acceder a los elementos de una matriz se utilizan dos índices, uno
for (i=0; i<n; i++) para indicar el renglón y el segundo para indicar la columna.
c[i]=a[i] + b[i];
printf (“Resultados \n”); Declaración:
for (i=0; i<n; i++) Tipo nombre[renglones][columnas];
printf(“%d”,c[i]);
Tipo
} es uno de los tipos predefinidos por el lenguaje, es decir int, float,
etc.

- 52 -
nombre for (r=0 ; r<n;r++)
es un identificador que nombra el arreglo . for(c=0; c<m;c++)
renglones scanf(“%d”,&ma[r][c]);
indica el numero de renglones de la matriz
columnas printf(“Lectura de la Matriz 2: \n”)
indica el numero de columnas de la matriz for (r=0 ; r<n;r++)
for(c=0; c<m;c++)
Ejemplo: scanf(“%d”,&mb[r][c]);

int m[3][4]; printf(“Sumando Matrices \n”)


0 1 2 3 Es el elemento m[1][2]=-8 for (r=0 ; r<n;r++)
for(c=0; c<m;c++)
0 45 3 -1 -1 mc[r][c]=ma[r][c]+mb[r][c];
1 5 45 -8 4
printf(“Resultados : \n”)
2 -4 0 4 -7 for (r=0 ; r<n;r++)
{
for(c=0; c<m;c++)
Explicación: printf(“%d”,mc[r][c]);
m es una matriz de numeros enteros formada por 3 renglones (eti- printf(“\n”);
quetados con las posiciones 0,1 y 2) y 4 columnas(etiquetadas con }
las posiciones 0,1,2 y 3). m[1][2]=-8 coloca el dato en el renglón }
1 y la columna 2. Si hacemos c=m[2][3], obtenemos el valor de –7
que se almacena en la variable c.
3.1.3. Arreglos multidimensionales
Ejemplo: Elaborar un programa que sume dos matrices de n-rengloes y m-
columnas. Los arreglos pueden ser de cualquier dimensión, aunque los más usuales son
de una, dos o hasta tres dimensiones y al igual que los arreglos y las matri-
#include <stdio.h>
ces los índices empiezan en 0.
main()
{
int n,m,r,c; La sintaxis general de un arreglo multidimensional es:
int ma[10][10],mb[10][10], mc[10][10];
printf(“Da el numero de renglones: ”); tipo nombre[tamaño1][ tamaño2].....[ tamaño-n];
scanf(“%d”,&n);
printf(“Da el numero de columnas: ”); tipo
scanf(“%d”,&m); es uno de los tipos predefinidos por el lenguaje, es decir int, float, etc.
printf(“Lectura de la Matriz 1: \n”) nombre
es un identificador que nombra el arreglo .

- 53 -
tamaño1 nombre_estructura
indica el número de elementos de la primera dimensión es un identificador que nombra el nuevo tipo definido, la estructura
tamaño2 variables_estrutura
indica el número de elementos de la segunda dimensión son identificadores para acceder a los campos de la estructura
.
tamaño-n Después de definir un tipo estructura, podemos declarar una variable de este
indica el número de elementos de la n-ésima dimensión tipo de la forma:

Ejemplo: struct nombre_structura variable_estructura1, variable_estructura2,...;


int a[2][3][4][5][3];
char m[10][5][6]; Ejemplo:
Explicación: struct ficha
este ejemplo declara un arreglo denominado a de cinco dimensio- {
nes. El numero de elementos es 2*3*4*5*3 = 360 datos de tipo en- char nombre[20];
tero. El primer elemento es a[0][0][0][0][0] y el ultimo es char apellidos[40];
a[1][2][3][4][2]. También se declara un arreglo m de tres dimen- long int ndi;
int edad;
siones con 10*5*6=300 datos de tipo char, el primer elemento es
}
m[0][0][0], y el ultimo es m[9][4][5].
struct ficha provedor, cliente;
Nota: El lenguaje C no revisa los limites de un arreglo. Es respon-
sabilidad del programador el realizar este tipo de operaciones. Este ejemplo define las variables proveedor y cliente de tipo ficha, por lo
que cada una de las variables consta de los campos: nombre, apellidos, ndi
3.2. ESTRUCTURAS y edad.

Una estructura es una colección de datos elementales (básicos) de diferentes Para asignar datos en la estructura se hace mediante la variable_estructura
tipos, lógicamente relacionados. A una estructura se le da también el nombre y el campo donde se almacenara el valor separados por un punto (.). En el
de registro. Crear una estructura es definir un nuevo tipo de datos. En la ejemplo anterior para almacenar para poner edad en el cliente:
definición de la estructura se especifican los elementos que la componen así
como sus tipos. Cada elemento de una estructura se denomina miembro (o cliente.edad = 22;
campo). Declaración de una estrucura:

struct nombre_estructura 3.2.1 Arreglos de estrucuras


{
tipo nombre_variable;
tipo nombre_variable; Una de las ventajas de las estructuras es utilizarlas como arreglos de estruc-
tipo nombre_variable; turas, donde lo único que tendríamos que aumentar seria definir una varia-
... ble_estructura como un arreglo de tamaño cualquiera.
} variables_estructura;

- 54 -
Ejemplo: De la declaración de la estructura ficha. /* Calcular resultados */
for (I=1ñi< n; i++)
struct ficha cliente[20] ; if (alumnus[i].nota >= 6)
aprobados++;
Ahora Para almacenar la edad en alguno de los clientes. else
cliente[3].edad = 25; reprobados++;
donde se esta asignando la edad 25 al cliente que se encuentra en la posición /* escribir resultados */
3 (recuerde que los arreglos inician desde 0, por lo que en realidad es la printf (“Aprobados %.4f \n”, aprobados/n*100);
posición 4 del mismo). printf (“Reprobados %.4f \n”, reprobados/n*100);
}
Ejemplo: El siguiente programa lee una lista de 10 alumnos y su correspon-
diente nota final de curso, dando como resultado el tanto por ciento de
alumnos aprobados y reprobados. 3.3. UNIONES

#include <stdio.h> La unión es una variable que puede contener, datos de diferentes tipos, de-
#define NA 10 /* número máximo de alumnos*/ nominados miembros o elementos, en una misma zona de memoria.
main()
{ union nombre_union
struct datos {
{ tipo nombre_variable;
char nombre[60]; tipo nombre_variable;
float nota; tipo nombre_variable;
} .....
struct datos alumnos[NA]; /* arreglo se estructuras */ }variables_union;
int n=0,i;
char fin; / apuntador al nombre leído */ nombre_union
float aprobados=0, reprobados=0; es un identificador que designa el nuevo tipo union
variables_union
/* Entrada de datos */ son identificadores para acceder a los campos de la union
printf(“Nombre: ”);
fin = gets(alumnos[n].nombre); La declaración de una unión tiene la misma forma que la de una estructura,
while ( n < NA) excepto que en lugar de la palabra reservada struct se pone la palabra
{ union. Todo lo expuesto para las estructuras es aplicable a las uniones,
printf(“Calificación : “); excepto la forma de almacenamiento de sus elementos. Cuando se define
/* %*c se utiliza para eliminar el retorno de carro */ una estructura cada uno de sus componentes ocupa una localidad de memo-
scanf(“%f%*c”,&alumnus[n++].nota); ria diferente, mientras en una union se utiliza el espacio de memoria igual a
printf(“Nombre: ”); la que ocupa el miembro mas largo de la union.
fin = gets(alumnos[n].nombre);
}

- 55 -
Después de definir un tipo union, podemos declarar una o más variables de
ese tipo de la forma:

union nombre_union variable1, variable2,..., variablen;

Para referirse a un determinado miembro o campo de la union,. Se utiliza la


notación:

variable_union.campo

Ejemplo:
union info
{
char var1;
int var2;
int var3;
}
union info var_union;

Explicación:
en este ejemplo, se declara una variable var_union que representa
a una union llamada info, con tres miembros o campos. La variable
var_union debe ser lo suficientemente grande como para contener
el mayor de los tres campos. Cualquiera de los tres campos puede
asignarse a var_union y utilizar en expresiones. Es responsabilidad
del programador recordar cual es el campo actual que esta en la
union.

El esquema siguiente muestra una union, donde var_union ocupa un tamaño


de memoria igual al tamaño de memoria ocupado por el mayor de sus ele-
mentos.

var union

var1
var2

var3
- 56 -
4.1. FUNCIONES

4
FUNCIONES
Las funciones son bloques con los que se construyen programas C, y en
ellos se lleva a cabo toda actividad del programa. Una vez que una función
ha sido escrita y depurada, puede utilizarse una y otra vez. Este es uno de los
aspectos más importantes del C como lenguaje de programación.

Todo programa en C consta al menos de una función, la función main() que


es donde inicia la ejecución de un programa.

Las funciones nos van a permitir dividir un problema, en subproblemas más


fáciles de realizar, lo que facilitará la realización y el mantenimiento del
programa.

Cuando una función se llama, el control se pasa a la misma para su ejecu-


ción y cuando ésta finaliza, el control es devuelto de nuevo al módulo que la
llamo, para continuar con la ejecución del mismo, a partir de la secuencia
que efectuó la llamada (ver figura siguiente)

main() func2()
{ func1() {
func1(); {
..... func2(); .....
func1() ..... return;
} return; }
El Lenguaje C utiliza funciones de biblioteca con }
el fin de realizar un cierto número de operaciones.
Sin embargo, C permite también al programador Flujo de control del llamdo de funciones
definir sus propias funciones que realicen deter-
minadas tareas. El uso de funciones (procedi- La definición de una función consiste en un encabezado y un cuerpo. De
mientos) definidas por el programador permite manera explicita, se puede decir que es un bloque o una proposición com-
dividir un programa grande en cierto número de puesta. La estructura básica de la definición de una función es:
componentes más pequeñas (modularización),
cada una de las cuales con un propósito único e tipo nombre([,argumentos])
identificable. {
[declaraciones]
proposiciones
[return(expresión);]

- 57 -
}
El siguiente ejemplo es más complicado:
• Encabezado de una función.
void letrero(int i)
tipo: {
indica el tipo del valor devuelto por la función. Puede ser cualquier if (i>0)
tipo básico, estructura o unión. Por defecto es int. Cuando no que- printf("\n i es positivo");
remos que devuelva ningún valor usaremos el tipo void. else
nombre: printf("\n i es negativo");
es un identificador que indica el nombre de la función. Si el nombre return;
va precedido por un *, el resultado devuelto por la función en el re- }
turn será un apuntador. Una función no puede retornar arrays o
funciones pero si puede retornar un apuntador a un array o a una Ejemplo: la siguiente función usa dos argumentos de tipo entero y regresa
función. un valor ( la suma de ambos argumentos) de tipo entero.
[argumentos]:
es una secuencia de declaraciones de parámetros separados por co- int suma(int a, int b)
mas, cada argumento(o parámetro) deberá ir con su tipo correspon- {
diente. Si no se pasan argumentos a la función podemos utilizar la int valor;
palabra reservada void. valor = a+b;
return(valor);
• Cuerpo de una función. }

El cuerpo de la función está formado por una sentencia compuesta que con-
tiene sentencias que definen lo que hace la función. También puede contener • LLamado a una función
declaraciones de variables utilizadas en dichas sentencias. Estas variables,
por defecto son locales a la función. Para llamar a una función se hace mediante su nombre con los argumentos
entre paréntesis. Generalmente se asigna el valor de la función a una varia-
[return(expresion)]: ble del mismo tipo de esta.
se utiliza para devolver el valor de la función el cual debe ser del
mismo tipo declarado en el encabezado de la función. Si la senten- Ejemplo:
cia return no se especifica o se especifica sin contener una expre-
sión, la función no devuelve un valor. #include <stdio.h>
main()
Ejemplos: {
void letrero(void) letrero(); /* llamado a la función letrero definida antes */
{ return;
printf("\n Esta es una función muy simple"); }
return;
}

- 58 -
Ejemplo: Ejemplo:
main()
{ main()
letrero(10); /* llamdo de la segunda funcion con {
un argumento*/ /* declaración de una función prototito */
getch(); double escribir(duble x, int y);
return;
} douible r,a=3.14;
int b= 5 ;
Ejemplo: llamado de la función suma, en el primer llamado se dan los ar- r = escribe(a,b) ; /* llamada a la función */
gumentos constantes y en el segundo llamado se pasan los valores en dos printf(“%.2lf \n”,r);
variables, en ambos casos el resultado de evaluar la función esta en la varia- }
ble res que es del mismo tipo que la función suma.
/* definición de la función */
main() duoble escribir(double x, int y)
{ {
int res; return( x + y * 13 );
int n1=23; }
int n2=55;
res = suma (5,10); Explicación:
printf(“La suma es : %d\n”,res); En este ejemplo. La declaración forward o funcion prototipo es ne-
res = suma(n1,n2); cesaria, ya que se esta llamando en el main() antes de haber sido
printf(“La suma de %d + %d = %d\n”,n1.n2,res); declarada.
}
Si la función se define antes del llamado de ésta en algún lugar del progra-
ma, entonces no es necesario hacer una declaración forward.

4.2. Declaración de la función prototipo

Una función prototipo (declaración forward) permite conocer el nombre, el 4.3. Paso de parámetros
tipo de resultado, los tipos y nombres de los argumentos, pero no se define
el cuerpo de la función. Esta información permite al compilador char los En C existen dos tipos de paso de parámetros en el llamado a una función:
tipos de los parámetros actuales por cada llamada a la función. Una función
prototipo tiene la misma sintaxis que la definición de una función, excepto Paso de parámetros por valor :
que esta, termina con un punto y coma (;). Es necesario hacer una declara- Pasar parámetros por valor, significa copiar los parámetros
ción forward cuando se hace el llamado de la función antes de haberla defi- actuales en sus correspondientes lista de argumentos, ope-
nido. ración que se hace automáticamente, con lo cual no se
modifican los argumentos actuales.

- 59 -
4.4. Reglas básicas de alcance (scope)
Paso de parámetros por referencia :
Pasar parámetros por referencia, significa que lo transferi- La regla básica de alcance consiste en que los identificadores son accesibles
do no son los valores, sino las direcciones de las variables sólo dentro del bloque en el que se declararon, fuera de éste son desconoci-
que contienen esos valores, con lo cual los argumentos ac- dos, por ejemplo:
tuales de la función pueden verse modificados.
{
Cuando se llama a una función, los argumentos especificados en la llamada int a=5;
son pasados por valor, excepto los arrays (arreglos) que se pasan por refe- printf("\n%d", a);
rencia. {
int a=7:
Ejemplo:
#include <stdio.h> printf("\n%d", a);
/* función sumar*/ }
int sumar(int a, int b, int c, int *s) printf("\n%d", ++a);
{ }
b += 2;
*s = a + b + c;
} Obsérvese que se ha declarado la misma variable dos veces, pero
aunque tenga el mismo nombre son variables distintas y por lo
main() tanto sus valores son distintos, en la segunda declaración de la
{ variable a, ésta se destruye cuando alcanza el fin de bloque de
int v = 5, res: proposiciones, primera llave cerrada (“}”).
sumar(4,v,v*2-1,&res) /* llamado a la función */
printf(“%d”,suma);
}
4.4.1 Variables Locales y Variables Globales
Explicación:
la llamada a la función sumar, pasa a esta función los parámetros La regla de alcance es utilizada comúnmente para utilizar variables globales
4, v y v*2-1 por valor y el parámetro res por referencia. Cualquier y locales. Las Variables Globales se declaran al inicio del programa fuera
cambio que sufra el argumento s, sucede también en su correspon- del main() y fuera de cualquier función, en cambio las Variables Locales se
diente parámetro actual res. En cambio, la variable v, no se ve declaran dentro e algún bloque. La diferencia sustancial entre estas dos tipos
modificada, a pesar de haber variado b, ya que ha sido pasada por de variables es el alcance: Las variables globales pueden modificar su valor
valor.
en cualquier parte del programa, mientras que las variables locales solo
pueden ser usadas en el bloque donde fueron definidas.
Nótese el uso del operador de referencia '&' u operador de direc-
ción para pasar un valor por referencia.

- 60 -
Ejemplo:
#include <stdio.h>
int x=20;

void escribe_x()
{
printf(“ El valor de x (Global) es = %d\n”,x); /* x=15 */
}

main()
{
int x=12;
escribe_x(); /* Escribe el Valor de x = 15 */
printf(“ El valor de x (Local) es = %d\n”,x); /* x=12 */
}

- 61 -
5.1. APUNTADORES
Una variable sencilla de un programa se almacena en un número de bytes
(p/e, un entero utiliza dos bytes). El apuntador se usa en programas que

5
APUNTADORES
acceden a la memoria y manipulan direcciones. Ya se han utilizado apunta-
dores (p/e, en la lista de argumentos del scanf...)), aunque de una manera
sencilla y sin saber exactamente como funcionan.

Sea v una variable, entonces &v es la ubicación o bien la dirección en la


memoria. El operador de dirección & es unario y tiene la misma prioridad y
asociatividad (de derecha a izquierda) que los demás operadores unarios.

Para poder usar apuntadores y direcciones de datos se introducen dos nuevos


operadores, el primero es el operador apuntador, que se representa con un *,
el cual permite definir las variables como apuntadores y también acceder a
los datos. El otro nuevo operador, el de dirección (&), que permite obtener
la dirección en la que se halla ubicada una variable en la memoria y es com-
plementario al operador apuntador, ya antes mencionado.

Para definir un apuntador lo primero que se debe tener en cuenta es que todo
apuntador tiene asociado un tipo de dato. Un apuntador se define igual que
una variable normal, salvo que delante del identificador se coloca el opera-
dor apuntador. Por ejemplo:

char *pc; /*apuntador a carácter */

int *pi; /* apuntador a entero */

Normalmente al definir un apuntador se inicializa para que apunte a algún


Dentro de la memoria de la computadora, cada dato alma- dato. Se dispone de tres formas de inicializar un apuntador:
cenado ocupa una o más celdas contiguas de memoria de-
pendiendo del tipo de dato almacenado es el tamaño que • Inicializarlo con la dirección de una variable que ya existe en
ocupa. Los apuntadores son usados frecuentemente en C memoria.
para apuntar a la dirección de memoria lo que incrementa
el desempeño de los programas y permite la devolución de Para obtener la dirección en la que está ubicada una variable se co-
varios datos de una función, entre otras cosas. loca el operador dirección. Por ejemplo:

char *p = &p1;

- 62 -
• Asignarle el contenido de otro apuntador que ya está‚ iniciali- dice que p es de tipo apuntador a un entero. Ejemplos de apuntadores utili-
zado: zando asignaciones (bajo la declaración anterior):

char *p = &p1; p=0; /*P apunta a NULL*/


p=NULL; /* es igual a p=0*/
char *p2 = p; /* p ya está inicializado */ p=&i; /*la dirección de i se le asigna a p */
p=(int *) 1501; /* p apunta a la dirección 1501 de memoria*/
• Inicializarlo con cualquier expresión constante que devuelva un
lvalue. Otros ejemplos.

Los lvalue más frecuentes son una cadena de caracteres, el iden- Supongamos la siguiente declaración:
tificador de un arreglo, el identificador de una función, entre
otros. Este es un detalle importante: los identificadores de fun- double x, y, *p; /* aquí se declaran dos variables simples de tipo double y
ciones y de arreglos son en sí mismos valores por la izquierda una variable que es de tipo apuntador a un double (real) */
(lvalue), por lo que se pueden usar directamente para inicializar
apuntadores. p=&x; /* a p se le pasa la dirección de x */
y=*p; /* a y se le pasa el contenido de p */
Una forma adicional de inicializar apuntadores es darle directamente una y=x; /* a y se le pasa el contenido de x */
posición de memoria. Este método no es portable, ya que depende del siste- y=*&x; /* son operadores unarios *y &y se asocian de de-
ma, pero suele ser muy útil en programación de sistemas, que es uno de los recha a izquierda y dice el contenido de la dirección de x
usos fundamentales del C. asignalo a y */

El operador & sólo se puede aplicar a variables y a elementos de arreglos, Construcciones a las que no se deben de apuntar son las siguientes:
de tal forma que si se tiene la siguiente construcciones: &(x+1) y &3 no son
permitidas dentro de C. &4 /* no se deben de apuntar a constantes */

Por otra parte, un error muy frecuente consiste en no inicializar el apuntador int a[10]; /*se declara un arreglo */
antes de usarlo. Este error frecuentemente lo localiza el compilador y avisa &a /* como a es un arreglo no se debe de hacer referencia a la
de ello. dirección de arreglo ya que por si sola la variable a signifi-
ca una dirección */
Las direcciones que se manejan con los apuntadores son un conjunto de
valores que pueden manipularse. Las variables de apuntadores pueden de- Para ver el uso de los apuntadores dentro de las funciones y como paso de
clararse en los programas y después utilizarse para tomar las direcciones parámetros, a continuación se muestran dos funciones que hacen lo mismo,
como valores. es decir intercambian sus valores, si es que el primer parámetro es mayor
que el segundo.
La declaración:
int *p;

- 63 -
Ordena (int p, int q) La forma de llamar a Ordena desde una función es: Ordena(i,j) y la forma
{ de llamar a Odena1 desde un función es: Ordena(&i, &,j)
int tmp;
if (p>q){ Por último, es importante hacer notar que los apuntadores no son enteros,
tmp=p; puesto que generalmente al hacer una asignación de un apuntador a una
p=q; variable de tipo entero no hay pérdida de información, ni escalado o conver-
q=tmp; sión, pero esto puede ser una práctica peligrosa.
} Una aplicación también muy extendida de los apuntadores corresponde a
return; definir una parte de la memoria para trabajar en ella y manejarla mediante
} un solo objeto, el apuntador a ella. Ésta metodología se llama manejo de
Memoria Dinámica.
Ordena1(int *p, int *q) Ésta técnica permite hacer manipulaciones muy eficientes y flexibles de la
{ memoria, las instrucciones de C que permiten lograr esto son malloc y free,
int tmp; la primera reserva una cantidad de memoria definida por el usuario y la
if (*p>*q){ segunda la libera. Éstas funciones pertenecen a la librería estándar de C.
tmp=*p;
*p=*q; La sintaxis para asignar la memoria es muy simple, en la zona de declara-
*q=tmp; ción de variables se define un apuntador a objetos de cierto tipo (p.e. char
} *p, define un apuntador a caracteres), luego se reserva la memoria requerida
return; mediante malloc(N), donde N indica el número de localidades (definida en
} bytes) deseadas. Para liberar la memoria luego de haber sido utilizada se
utiliza la función free(p).
La diferencia entre la función Ordena y la función Ordena1 es que en la En el caso que la memoria no se pueda asignar malloc regresa típicamente
primer al regresar de la función, los valores que se enviaron en las variables cero. La función sizeof regresa el tamaño en bytes de un tipo de variable.
p y q, no son modificadas puesto que se crearon copias de éstas variables, y
los cambios realizados dentro de la función no se ve reflejada en quien la Ejemplo. El siguiente código reserva 75 localidades de memoria de tipo
llamó. Por otra parte, la segunda función al tener como paso de parámetros entero, observe el uso de la función sizeof, luego se almacenan los primeros
las direcciones de las variables que se envían, en el momento que se regresa 75 números naturales en ella y se enlistan finalmente.
de la función, el cambio se refleja, puesto que se esta trabajando sobre el
mismo espacio en la memoria. main(){
int *p, t;
La forma en que pasa sus valores la función Ordena se le conoce como p = malloc(75*sizeof(int));
paso de parámetros por valor; puesto que se envía a la función los valores de if (p==0){
las variables y a su vez ésta recibe los valores en “nuevas” variables, y a printf(“Memoria insuficiente \n”);exit(0);
Ordena1se le conoce como paso de parámetros por referencia; debido a que }
los que se envía son las direcciones de las variables y se trabaja sobre el for(t=0;t<75;t++) *(p+t) = t+1;
mismo espacio, aunque las variables se “llamen” de manera distinta. for(t=0;t<75;t++) printf(“%d “, *(p+t));
free(p);
}

- 64 -
6.1. ARCHIVOS

Un archivo o fichero es una colección de información que almacenamos en

6
ARCHIVOS
un soporte magnético para poder manipularla en cualquier momento. Esta
información se puede almacenar y leer de las siguientes maneras:

Función
fputc, fgetc
putw, getw
Descripción
Los datos pueden ser escritos y leídos carácter a carácter
Los datos pueden ser escritos y leídos palabra a palabra
fputs, fgets Los datos pueden ser escritos y leídos como cadenas de
caracteres
fprintf, fscanf Los datos pueden ser escritos y leídos con formato
fwrite, fread Los datos pueden ser escritos y leídos como registros o
bloques, es decir como un conjunto de longitud fija, tales
como estructuras o elementos de un arreglo
Tabla 11. Formas de acceder a los datos de un archivo

Un archivo visto como un conjunto de caracteres contiene un carácter espe-


cial de fin de línea (\n) y un carácter de fin de archivo (EOF).

6.1.1 Funciones para abrir y cerrar archivos

Para poder leer o escribir un archivo primero es necesario abrirlo.

fp = fopen ( nombre_archivo, acceso)

Abre un archivo especificado por nombre_archivo. El argumento acceso


Muchas aplicaciones requieren escribir o leer información especifica el tipo de acceso al archivo ver tabla 12. Esta función básicamen-
de un dispositivo de almacenamiento auxiliar, generalmen- te hace dos cosas: abre un archivo en disco para utilizarlo y devuelve un
te en un disco magnético, a este tipo de almacenamiento se apuntador al fichero fp.
le llama Archivo de datos, permitiéndonos almacenar in-
formación de modo permanente y acceder y alterar la
misma cuando sea necesario.

- 65 -
acceso Descripción 6.1.2 Entrada carácter a carácter: fputc y fgetc
“r” Abrir un archivo para leer. Si el archivo no existe o no se encuen-
tra, se obtiene un error. fputc(car,fp);
“w” Abrir un fichero para escribir. Si el archivo no existe se crea y si int car ;
existe su contenido se destruye para ser creado de nuevo. FILE *fp ;
“a” Abrir un archivo para añadir información al final del mismo. Si el
archivo no existe se crea. Esta función escribe un carácter car, en el archivo apuntado por fp, en la
“r+” Abrir un archivo para leer y escribir. El archivo debe existir. posición indicada por el apuntador de lectura/escritura.
“w+” Abrir un archivo para leer y escribir. Si el fichero no existe se crea
y si existe su contenido se destruye para ser creado de nuevo. Ejemplo:
“a+” Abrir un archivo para leer y añadir. Si el archivo no existe se crea. #incluide <stdio.h>
Tabla 12.Tipo de acceso a un archivo. #include <string.h> /* biblioteca de cadenas */

FILE fp; /* declaración de un apuntador a archivo */


Ejemplo: abrir un archivo para lectura con nombre Pre.tex char buffer[81]; /* arreglo de caracteres */
int i=0, longitud;
FILE *fp ; /*Declara una variable de apuntador a un archivo, fp */
fp = fopen( “Pre.tex” ,”r”); main()
{
Sin embargo es más conveniente verificar si existe el archivo, en caso de fp = fopen (“texto.txt”, “w”); /* abrir archivo para escritura */
que no exista, termina el programa. /* copia el letrereo en el buffer */
strcpy(buffer,”Este mensaje es un texto para fputc! \n”);
if((fp=fopen("Pre.tex","r")) == NULL) longitud = strlen(buffer); /* tamaño de la cadena */
{ printf("No se puede abrir el archivo \n"); /* escribir el arreglo en el archivo, la función ferror checa si se ocurre un
exit(o); error al escribir */
} while (¡ferror(fp) && i < longitud)
fputc(buffer[i++], fp);
Es necesario cerrar el archivo al dejar de utilizarlo, esto se realiza de la if (ferror(fp))
siguiente forma: printf(“ \n Error durante la escritura \n”);
fclose(fp); /* cerrar el archivo */
fclose(fp); }

ésta función cierra el archivo apuntado por fp.

- 66 -
fgetc(fp);
FILE *fp; Esta función escribe la lista_de_argumentos, con el formato especificado
en la cadena_de_control, en el archivo apuntado por fp.
La función fgetc devuelve el carácter leido o un EOF si se ocurre un error o
se detecta el final del archivo. Se utiliza la función feof para distinguir si se Ejemplo: suma de dos números escribiendo los resultados en un archivo de
ha detectado el final del archivo. tipo añadir.

Ejemplo: #include <stdio.h>


#include <stdio.h> main()
FILE *fp1; /* declaración de un apuntador a un archivo */ {
FILE *fp; / declaración de apuntador a archivo */
main() int a,b,s;
{ fopen(“salida.dat”,”a”); /* abrir archivo para añadir */
char car; printf(“ Da el valor de a : “);
/* se verifica si se puede abrir el archivo para lectura */ scanf(“%d”, &a);
if((fp=fopen("texto.txt","r")) == NULL) printf(“ Da el valor de b : “);
{ printf("No se puede abrir el archivo \n"); scanf(“%d”, &b);
exit(0); s = a+b ;
} printf(“\n La suma de %d + %d = %d\n”,a,b,s);
car = getc(fp1); /* lectura del primer caracter del archivo */ /* escritura de los datos al archivo */
while (car != eof(fp1)) fprintf(fp,”El valor de a = %d\n”,a);
{ fprintf(fp,”El valor de b = %d\n”,b);
putc(car); /* escribe el carcater en pantalla */ fprintf(fp,”La suma de %d + %d = %d\n”,a,b,s);
car = getc(fp1); /* lectura del siguiente carácter del archivo */ fprintf(fp,”_______________________________\n”);
} fclose(fp);
fclose (fp1); }
}
fscanf(fp, cadena_de_control, lista_de_arcgumentos);

Esta función lee la lista_de_argumentos, con el formato especificado en la


6.1.3 Entrada/Salida con formato: fprintf y fscanf cadena_de_control, desde el archivo apuntado por fp.

Las funciones fprintf y fscanf sirven para hacer escritura y lectura con for- Ejemplo: Lectura de un archivo de números reales (tabla)
mato de un archivo. Las descripción del formato es el mismo que se especi-
fican para printf() y scanf(); #include <stdio.h>
main()
fprintf(fp, cadena_de_control, lista_de_arcgumentos); {
FILE *fp; / declaración de apuntador a archivo */

- 67 -
float a,b,c,d,s; Ejemplo: Ejecución de un programa desde la línea de comandos
/* se verifica si se puede abrir el archivo para lectura */
if((fp=fopen("texto.txt","r")) == NULL) $prog Juan Perez /* El programa fue salvado con el nombre "prog"
{ printf("No se puede abrir el archivo \n"); y los argumentos son "Juan" y "Perez" */
exit(0);
} La siguiente figura describe exactamente a las variables argc y a
argv.
/* Lectura del archivo */
while(!feof(fp))
{
/* lectura de un renglon del archivo de la tabla de 4 columnas*/
fscanf(fp,”%f %f %f %f”,&a,&b,&c,&d);
s = (a+b+c+d)/4.0;
printf(“ El promedio es %f\n”,s);
}
fclose(fp);
} void main(int argc,char *argv[])
{
if (argc!=3) {
6.1.4. Argumentos argc y argv de líneas de comando printf("Número de argumentos no valido \n");
exit(0);
}
Los parámetros argc y argv sirven para trasmitir argumentos al programa else {
desde la línea de comandos cuando se inicia la ejecución de un programa. printf("El nombre es %s\n",argv[1]);
printf("El apellido es %s\n",argv[2]);
argc: }
Es de tipo int, y guarda el número de argumentos que se dieron exit(0);
desde la línea de comandos, y se declara de la siguiente manera: }
int argc;

argv:
Es un arreglo de apuntadores a una cadena de caracteres, donde la
posición 0 apunta a la cadena que tiene el nombre del programa en
ejecución, y las siguientes posiciones apuntan a cada uno de los ar-
gumentos, y se declara de la siguiente manera:
char *argv[]; /* No tiene dimensión */

- 68 -
La programación estructurada se utiliza desde los setenta y es uno de los
métodos más utilizados en el campo de la programación. Uno de los princi-

IV
INTRODUCCIÓN A LA PROGRAMACIÓN
pales conceptos que introduce es la abstracción, que permite concentrarnos
en conocer que tarea realiza un procedimiento, sin preocuparnos en cómo
esta tarea es realizada. Sin embargo a medida que los programas crecen las
estructuras de datos sobre las cuales operan los procedimientos cobran ma-
yor importancia. Los tipos de datos son procesados en muchas funciones
dentro de un programa estructurado y cuando se producen cambios en estos
tipos de datos, deben hacerse modificaciones en cada sentencia que actúa
ORIENTADA A OBJETOS sobre estos tipos dentro del programa. Otro problema es que dado que mu-
chas funciones acceden a datos compartidos, la disposición de los datos no
se puede cambiar sin modificar todas las funciones que los utilizan. En con-
clusión con la programación estructurada podemos empaquetar código en
funciones pero ¿qué sucede con los datos ?.
La programación orientada a objetos surge como un nuevo para-
digma que permite acoplar el diseño de programas a situaciones del mundo
real, las entidades centrales son los objetos, que son tipos de datos que en-
capsulan con el mismo nombre estructuras de datos y las operaciones o
algoritmos que manipulan esos datos. Algunas de las ventajas de esta
aproximación son la reutilización de código, el desarrollo de prototipos en
forma sencilla, desarrollo de interfaces gráficas en forma rápida, bases de
datos más eficientes.

V.1. FUNDAMENTOS DE LA PROGRAMACIÓN ORIENTADA


A OBJETOS.

Este paradigma de programación orientada a objetos se fundamenta


en las siguientes propiedades:
Los lenguajes computacionales han experimenta-
do una impresionante evolución desde que se Abstracción: que permite representar las características esenciales de
construyeron las primeras computadoras. Éstos un objeto, sin preocuparse de las no esenciales.
han permitido escribir programas como una serie
de procedimientos que actúan sobre los datos, Encapsulación: es la propiedad que permite asegurar que el contenido
donde los datos están separados de los procedi- de la información de un objeto está oculto al mundo exterior. La
mientos. La programación Orientada a Objetos encapsulación permite la división de un programa en módulos. Es-
trata a los datos y a los procedimientos que ope- tos módulos se implementan mediante clases (ver sección 5.2), las
ran sobre ellos como un solo objeto. clases representan la encapsulación de abstracciones.

- 67 -
Modularidad: es la propiedad que permite subdividir una aplicación
en partes más pequeñas cada una de las cuales debe ser tan inde- Coche_1
Nombre
pendiente como sea posible.
Matrícula
Jerarquía: es una propiedad que permite ordenar las abstracciones. Marca
Las dos jerarquías más importantes son las clases y los objetos. Las Precio
Atributos
clases se relacionan unas con otras por medio de la relación heren-
cia mediante la cual pueden definirse nuevos objetos a partir de los
existentes. Calcula_precio_actual
Métodos

V.2 CONCEPTOS FUNDAMENTALES DE LA


PROGRAMACIÓN ORIENTADA A OBJETOS
2. Métodos y mensajes: Un programa orientado a objetos consiste en
A continuación se especifican conceptos, cuya comprensión es ne- un número de objetos que se comunican unos con otros llamando a
cesaria dentro de este nuevo paradigma: procedimientos o funciones que reciben el nombre de métodos. Un
1. Objeto: unidad que permite combinar datos y funciones que operan método es el procedimiento o función que se invoca para actuar so-
sobre esos datos. Dentro de un objeto residen los datos (atributos) bre un objeto. Los métodos determinan como actúan los objetos
de los lenguajes tradicionales, tales como números, arreglos, cade- cuando reciben un mensaje. Un mensaje es el resultado de cierta
nas y registros que caracterizan el estado del objeto. Así como fun- acción efectuada por un objeto. El conjunto de mensajes a los cua-
ciones o subrutinas (métodos) que operan sobre ellos. Los métodos les puede responder un objeto se le conoce como protocolo del ob-
dentro del objeto son el único medio de acceder a los datos priva- jeto. Por ejemplo, el protocolo de un icono puede constar de men-
dos de un objeto. No se puede acceder a los datos directamente. sajes invocados por el clic del botón de un ratón cuando el usuario
Los datos están ocultos, y eso asegura que no se pueden modificar localiza sobre el icono el apuntador de dicho ratón. De esta forma
accidentalmente por funciones externas al objeto. Los datos y fun- los mensajes son el único conducto que conectan al objeto con el
ciones asociados se dicen que están encapsulados en una entidad mundo exterior.
única o módulo. Cuando se ejecuta un programa orientado a objetos ocurren tres su-
Ejemplo de objetos: cesos. Primero, los objetos se crean a medida que se necesitan. Se-
a) Objetos físicos: aviones en un sistema de control de tráfico aé- gundo. Los mensajes se mueven de un objeto a otro (o del usuario a
reo, casas, parques. un objeto) a medida que el programa procesa información o res-
b) Elementos de interfaces gráficas de usuario: ventanas, menús, ponde a la entrada del usuario. Tercero, cuando los objetos ya no se
teclado, cuadros de diálogo. necesitan, se borran y se libera la memoria.
c) Animales: animales vertebrados, animales invertebrados
d) Tipos de datos definidos por el usuario: Datos complejos, Pun-
tos de un sistema de coordenadas
e) Alimentos: carnes, frutas, verduras.

La representación gráfica de un objeto se muestra a continuación:

- 68 -
No debe confundirse la relación de los objetos con las clases, con la
Objeto1 Mensaje Objeto2 relación de una clase base con sus clases derivadas. Los objetos
Atributos existentes en la memoria de la computadora expresan las
Atributos
Métodos características exactas de su clase. Las clases derivadas heredan
Métodos
características de su clase base, pero añaden otras características
propias, nuevas.
Objeto3

Atributos
Clase base
Métodos

Característi- Característi-
3. Clase es la descripción abstracta de un conjunto de objetos; consta
de métodos y datos que resumen características comunes del
conjunto de objetos. Se pueden definir muchos objetos de una
misma clase. Es decir una clase es la declaración de un tipo de
objetos. Cada vez que se construye un objeto a partir de una clase
se crea lo que se conoce como instancia de esa clase. Por
consiguiente un objeto es una instancia de una clase. La clase tiene Característi-
dos propositos definir abstracciones y favorecer la modularidad. Característi-
Característi-

Existen ciertas clases que se conocen como clases abstractas, estas Característi-
Característi-
clases no tiene instancias, pueden no existir en la realidad pero son Característi-
Característi-
conceptos útiles, que ocupan un lugar en la jerarquía de clases, Característi-
Característi-
actuando como un depósito de métodos y atributos compartidos Característi-
para las subclases de nivel inferior.

4. Herencia propiedad que permite a los objetos ser construidos a Clases derivadas
partir de otros objetos. Dicho de otra forma la capacidad de un
objeto para utilizar estructuras de datos y métodos presentes en sus
antepasados. El objetivo principal de la herencia es la
reutilización, poder utilizar código desarollado con anterioridad.
La herencia se basa en la división de clases básicas en subclases.
Dicha división se fundamenta en el concepto de jerarquía.
La herencia supone una clase base y una jerarquía de clases que Las clases derivadas pueden a su vez servir como clases base para
contiene las clases derivadas. Las clases derivadas pueden heredar definir nuevas clases y de esta forma enfatizar la reutilización.
el código y los datos de su clase base, añadiendo su propio código Existen dos tipos de herencia:
especial y datos, incluso cambiar aquellos elementos de la clase
base que necesitan ser diferentes.

- 69 -
a) Herencia simple: Una clase puede tener sólo un ascendente. Es ejemplo de esta propiedad ya que el símbolo + cuando se utiliza
decir una subbase puede heredar datos y métodos de una única con operandos enteros representa un conjunto de operaciones de
clase base máquina diferente al conjunto empleado si los operandos son
reales. Otra ilustración sería tener una clase figura que puede
b) Herencia múltiple: Una clase puede tener más de un aceptar los mensajes dibujar, borrar y mover. Cualquier tipo
ascendente inmediato, adquirir datos y métodos de más de una derivado de una figura es un tipo de figura y puede recibir el
clase. mismo mensaje. Cuando se envía un mensaje dibujar, esta tarea
será distinta según que la clase sea un triángulo un cuadrado o una
elipse. Esto el polimorfismo.

Figura Personal

Profesor Investi-
Círcu- Rec- Trián-
lo tángulo gulo

Prof. Inv.

Rectán-
gulo
redon-

Herencia simple Herencia múltiple

La mayor parte de los lenguajes orientados a objetos permiten la


herencia simple no así la herencia múltiple porque pueden surgir
ambiguedades. Al aplicar la herencia múltiple si las clases
utilizadas para definir una clase nueva tienen un método con el
mismo nombre aparecerán problemas de ambigüedad que deberán
resolverse con una operación de prioridad que el lenguaje de
programación deberá soportar y entender.
Cuando se define una subclase a partir de una clase base, la
subclase no tiene que heredar todas las características de la clase
base, puede seleccionarse únicamente las características de
útilidad, esto se conoce como herencia selectiva.

5. Polimorfismo: es el uso de un nombre o un símbolo para


representar o significar más de una acción. Los operadores
aritméticos de los lenguajes de programación tradicionales son

- 70 -

También podría gustarte