Está en la página 1de 32

S.E.P S.E.S D.G.E.S.

NOMBRE DE LA MATERIA:

FUNDAMENTOS DE PROGRAMACION

DOCENTE:

LIC. ISIDRO LOPEZ RUIZ

ESPECIELIDAD:

ING. EN DESARROLLO DE SOFTWARE

PRESENTA:
MARIA ELENA CASTILLO ANTONIO

SEMESTRE
GRUPO

1º “A”

San Pedro Comitancillo Oaxaca, a Noviembre del 2009.


ÍNDICE

4.1 DISEÑO DE METODOS (FUNCIONES).........................................................................................3


4.1.1 TECNICAS DE FORMULACION DE ALGORITMOS............................................................6
4.1.2 TIPOS DE ALGORITMOS.........................................................................................................9
4.1.2.1 ALGORITMOS DETERMINISTICOS............................................................................9
4.1.2.2 ALGORITMOS APROXIMADOS....................................................................................11
4.1.2.3 ALGORITMOS HEURÍSTICOS.......................................................................................11
4.1.2.4 ALGORITMOS VORACES...............................................................................................11
4.1.3 ALGORITMOS PROBABILISTICOS......................................................................................13
4.1.4 IDENTIFICACION DEL PROBLEMA....................................................................................13
4.1.5 PLANTEAMIENTO DEL PROBLEMA..................................................................................14
4.1.6 ANALISIS DEL PROBLEMA.................................................................................................15
4.1.7 DISEÑO DE LA SOLUCION...................................................................................................15
4.1.8 PRUEBAS Y DEPURACION...................................................................................................15
4.1.9 DOCUMENTACIÓN................................................................................................................16
4.2 OPERADORES................................................................................................................................16
4.2.1 ARITMETICOS.........................................................................................................................20
4.2.2 LOGICOS..................................................................................................................................21
4.2.3 JERARQUIA DE OPERADORES............................................................................................25
4.3 EXPRECIONES................................................................................................................................26
4.4 ESTRUCTURAS DE CONTROL....................................................................................................26
4.4.1 SELECTIVAS............................................................................................................................33
4.4.2 ITERATIVAS............................................................................................................................34
4.4.2 ITERATIVAS
CONSTRUCCION DEL COMPORTAMIENTO DE UN
OBJETO

4.1 DISEÑO DE METODOS (FUNCIONES)


Los métodos son funciones que pueden ser llamadas dentro de la clase o por otras clases.
La implementación de un método consta de dos partes, una declaración y un cuerpo. La
declaración en Java de un método se puede expresar esquemáticamente como:
tipoRetorno nombreMetodo( [lista_de_argumentos] ) {
cuerpoMetodo
}
En C++, el método puede declararse dentro de la definición de la clase, aunque también
puede colocarse la definición completa del método fuera de la clase, convirtiéndose en una
función inline.
Los métodos pueden tener numerosos atributos a la hora de declararlos, incluyendo el
control de acceso, si es estático o no estático
La lista de argumentos es opcional, tanto en Java como en C++, y en los dos casos puede
limitarse a su mínima expresión consistente en dos paréntesis, sin parámetro alguno en su
interior. Opcionalmente, C++ permite utilizar la palabra void para indicar que la lista de
argumentos está vacía
Los parámetros, o argumentos, se utilizan para pasar información al cuerpo del método.
La sintaxis de la declaración completa de un método es la que se muestra a continuación
con los items opcionales en itálica y los items requeridos en negrilla:
especificadorAcceso static abstract
final native synchronized tipoRetorno nombreMetodo( lista_de_argumentos )
throws listaEscepciones
especificadorAcceso, determina si otros objetos pueden acceder al método y cómo pueden
hacerlo.
static,
indica que los métodos pueden ser accedidos sin necesidad de instanciar un objeto del
tipo que determina la clase.

Los métodos y funciones en C++ pueden devolver una variable u objeto, bien sea por valor
(se devuelve una copia), por puntero o por referencia. Java no soporta punteros, así que no
puede devolver nada por puntero.

Para devolver un valor se utiliza la palabra clave return. La palabra clave return va seguida de
una expresión que será evaluada para saber el valor de retorno. Esta expresión puede ser
compleja o puede ser simplemente el nombre de un objeto, una variable de tipo primitivo o
una constante.
En C++, si un programa devuelve un puntero a un objeto situado en memoria dinámica y el
valor de ese puntero no se asigna a una variable, la posibilidad de devolver la memoria al
sistema se pierde y se producirá un memory leak, asumiendo que la dirección no está ya
disponible para almacenar ninguna otra variable.
en C++ el tipo del valor de retorno debe coincidir con el tipo de retorno que se ha indicado en
la declaración del método; aunque en Java, el tipo actual de retorno puede ser una subclase
del tipo que se ha indicado en la declaración del método, lo cual no se permite en C++.

En general, se permite almacenar una referencia a un objeto en una variable de referencia


que sea una superclase de ese objeto. También se puede utilizar un interfaz como tipo de
retorno, en cuyo caso, el objeto retornado debe implementar dicho interfaz.
Nombre del Método
El nombre del método puede ser cualquier identificador legal en Java. Java soporta el
concepto de sobrecarga de métodos, es decir, permite que dos métodos compartan el
mismo nombre pero con diferente lista de argumentos, de forma que el compilador pueda
diferenciar claramente cuando se invoca a uno o a otro, en función de los parámetros que se
utilicen en la llamada al método.
En C++, dos versiones sobrecargadas de una misma función pueden devolver tipos
diferentes. En Java, los métodos sobrecargados siempre deben devolver el mismo tipo.
Métodos de Instancia
Cuando se incluye un método en una definición de una clase Java sin utilizar la palabra
clave static, estamos generando un método de instancia. Aunque cada objeto de la clase no
contiene su propia copia de un método de instancia (no existen múltiples copias del método
en memoria), el resultado final es como si fuese así, como si cada objeto dispusiese de su
propia copia del método.
Cuando se invoca un método de instancia a través de un objeto determinado, si este método
referencia a variables de instancia de la clase, en realidad se están referenciando variables
de instancia específicas del objeto específico que se está invocando.
La llamada a los métodos de instancia en Java se realiza utilizando el nombre del objeto, el
operador punto y el nombre del método.
miObjeto.miMetodoDeInstancia();
En C++, se puede acceder de este mismo modo o utilizando una variable puntero que
apunte al objeto
miPunteroAlObjeto->miMetodoDeInstancia();
Los métodos de instancia tienen acceso tanto a las variables de instancia como a las
variables de clase, tanto en Java como en C++.
Métodos Estáticos
Cuando una función es incluida en una definición de clase C++, o un método e incluso en
una definición de una clase Java, y se utiliza la palabra static, se obtiene un método estático
o método de clase.
Lo más significativo de los métodos de clase es que pueden ser invocados sin necesidad de
que haya que instanciar ningún objeto de la clase. En Java se puede invocar un método de
clase utilizando el nombre de la clase, el operador punto y el nombre del método.
MiClase.miMetodoDeClase();
En C++, hay que utilizar el operador de resolución de ámbito para poder invocar a un
método de clase:
MiClase::miMetodoDeClase();
Todas las clases que se derivan, cuando se declaran estáticas, comparten la misma página
de variables; es decir, todos los objetos que se generen comparten la misma zona de
memoria. Los métodos estáticos se usan para acceder solamente a variables estáticas.
class UnaClase {
int var;
UnaClase() {
var = 5;
}
unMetodo() {
var += 5;
}
}
En el código anterior, si se llama al método unMetodo() a través de un puntero a función, no
se podría acceder a var, porque al utilizar un puntero a función no se pasa implícitamente el
puntero al propio objeto (this). Sin embargo, sí se podría acceder a var si fuese estática,
porque siempre estaría en la misma posición de memoria para todos los objetos que se
creasen de la clase UnaClase.
Paso de parámetros
En C++, se puede declarar un método en una clase y definirlo luego dentro de la clase (bajo
ciertas condiciones) o definirlo fuera de la clase. A la hora de declararlo, es necesario indicar
el tipo de argumentos que necesita, pero no se requiere indicar sus nombres (aunque pueda
hacerse). A la hora de definir el método sí tiene que indicarse el nombre de los argumentos
que necesita el método.
En Java, todos los métodos deben estar declarados y definidos dentro de la clase, y hay que
indicar el tipo y nombre de los argumentos o parámetros que acepta. Los argumentos son
como variables locales declaradas en el cuerpo del método que están inicializadas al valor
que se pasa como parámetro en la invocación del método.
En C++, se puede pasar como parámetro un puntero que apunte a una función dentro de
otra función, y utilizar este puntero en la segunda función para llamar a la primera. Esta
capacidad no está directamente soportada en Java. Sin embargo, en algunos casos, se
puede conseguir casi lo mismo encapsulando la primero función como un método de
instancia de un objeto y luego pasar el objeto a otro método, donde el primer método se
puede ejecutar a través del objeto.
Tanto en Java como en C++, los métodos tienen acceso directo a las variables miembro de
la clase. El nombre de un argumento puede tener el mismo nombre que una variable
miembro de la clase. En este caso, la variable local que resulta del argumento del método,
oculta a la variable miembro de la clase.
Cuando se instancia un método se pasa siempre una referencia al propio objeto que ha
llamado al método, es la referencia this.

4.1.1 TECNICAS DE FORMULACION DE ALGORITMOS


Las técnicas para la formulación de algoritmos son tres:

DIAGRAMAS DE FLUJO:
Un diagrama de flujo es la representación gráfica de un algoritmo. También se puede decir que es la
representación detallada en forma gráfica de cómo deben realizarse los pasos en la computadora para
producir resultados.

Esta representación gráfica se da cuando varios símbolos (que indican diferentes procesos en la
computadora), se relacionan entre sí mediante líneas que indican el orden en que se deben ejecutar los
procesos. Los símbolos utilizados han sido normalizados por el instituto norteamericano de
normalización (ANSI):
Símbolo Descripción

Indica el inicio y el final de nuestro diagrama de flujo.

Indica la entrada y salida de datos.


Símbolo de proceso y nos indica la asignación de un
valor en la memoria y/o la ejecución de una operación
aritmética.

Indica la salida de información por impresora.

Conector dentro de página. Representa la continuidad


del diagrama dentro de la misma página.
Conector fuera de página. Representa la continuidad
del diagrama en otra página.

Indica la salida de información en la pantalla o monitor.

Símbolo de decisión. Indica la realización de una


comparación de valores.

Símbolo de Selección Múltiple. Dada una expresión


permite escoger una opción de muchas.

Símbolo del Mientras. Dada una expresión al principio


de la iteración esta es evaluada; si la condición es
verdadera realizará el ciclo, si es falsa la repetición
cesará.
Símbolo del Para. Esta estructura de control repetitiva
se usa generalmente cuando se conoce de antemano el
número de iteraciones.

Símbolo Repita Hasta. funciona igual que la estructura


Mientras, con la diferencia que al menos una vez hará
el grupo de instrucciones y luego evaluará una
condición. Si la condición evaluada es falsa continua
dentro del ciclo y si es verdadera termina la iteración.

Líneas de flujo o dirección. Indican la secuencia en que


se realizan las operaciones.

Recomendaciones para el diseño de Diagramas de Flujo

• Se deben usar solamente líneas de flujo horizontal y/o vertical.


• Se debe evitar el cruce de líneas utilizando los conectores.
• Se deben usar conectores sólo cuando sea necesario.
• No deben quedar líneas de flujo sin conectar.
• Se deben trazar los símbolos de manera que se puedan leer de arriba hacia abajo y de izquierda
a derecha.
• Todo texto escrito dentro de un símbolo deberá ser escrito claramente, evitando el uso de
muchas palabras.
PSEUDOCÓDIGO:

Es un lenguaje de especificación de algoritmos. El uso de tal lenguaje hace el paso de Codificación


final (esto es, la traducción a un lenguaje de programación) relativamente fácil.

El pseudocódigo nació como un lenguaje similar al inglés y era un medio representar básicamente
las estructuras de control de programación estructurada. Se considera un primer borrador, dado
que el pseudocódigo tiene que traducirse posteriormente a un lenguaje de programación. Cabe
señalar que el pseudocódigo no puede ser ejecutado por una computadora.

La ventaja del pseudocódigo es que en su uso en la planificación de un programa, el programador


se puede concentrar en la lógica y en las estructuras de control y no preocuparse de las reglas de
un lenguaje específico. Es también fácil modificar el pseudocódigo si se descubren errores o
anomalías en la lógica del programa, además de todo esto es fácil su traducción a lenguajes como
pascal, COBOL, C, FORTRAN o BASIC.

El pseudocódigo utiliza para representar las acciones sucesivas palabras reservadas en inglés
(similares a sus homónimos en los lenguajes de programación), tales como star,begin, end, stop,
if-then-else, while, repeat-until….etc

DIAGRAMAS ESTRUCTURADOS (NASSI-SCHNEIDERMAN):

El diagrama N-S de Nassi-Schneiderman, también conocido como diagrama de Chapin, es


como un diagrama de flujo en el que se omiten las flechas de unión y las cajas son
contiguas.

Las acciones sucesivas se escriben en cajas sucesivas, y, como en los diagramas de flujo,
se pueden escribir diferentes acciones en una caja.

Los Diagramas Estructurados, son una técnica que permite formular algoritmos mediante
una representación geométrica y de asignación de espacios de un bloque específico.

4.1.2 TIPOS DE ALGORITMOS


La mayoría de los sistemas expertos utilizan algoritmos para el razonamiento. Este planteamiento
tiene una limitación importante: el sistema es capaz de resolver solamente las situaciones
previstas por quien ha diseñado el algoritmo. Por este motivo nadie califica de "inteligente" a un
sistema de estas características. Existen distintos tipos de algoritmos de razonamiento:

Algoritmos estáticos, es decir, algoritmos que funcionan siempre igual, independientemente del
tipo de problema tratado. Por ejemplo, los sistemas basados en el método de resolución.

Algoritmos probabilísticos, es decir, algoritmos que no utilizan valores de verdad booleanos sino
continuos. Por ejemplo, los sistemas basados en lógica difusa.

Algoritmos adaptativos, es decir, algoritmos con cierta capacidad de aprendizaje. Por ejemplo, los
sistemas basados en redes neuronales.

Los Algorítmos permiten resolver problemas computacionales mediante lenguajes de


programación. Como Ejemplo podemos poner dos de los más usuales:

Divide y Vencerás: Consiste en descomponer un problema en subproblemas, resolver cada


subproblema y combinar las soluciones. El resultado, es la solución del problema original. Si los
subproblemas son todavía demasiado grandes, se utiliza la misma táctica con ellos, esto es,
dividirlos a ellos también, utilizando un algoritmo recursivo que vaya dividiendo más el sub-
problema hasta que su solución sea trivial.

Backtracking: El Backtracking o esquema de vuelta atrás, es un esquema que de forma


sistemática y organizada, genera y recorre un espacio que contiene todas las posibles secuencias
de decisiones. Este espacio se denomina el espacio de búsqueda del problema, y se representa
como un árbol sobre el que el algoritmo hace un recorrido en profundidad partiendo de la raíz. Se
conoce de antemano el orden en que se van a generar y recorrer sus nodos, y se continúa
recorriendo el árbol mientras se cumplan las restricciones. Éste método tiene tres posibles
esquemas: encontrar una solución factible, encontrar todas las soluciones factibles, encontrar la
mejor solución factible.

Un algoritmo pueden además ser:


Deterministico, sí en cada paso del algoritmo, es posible predecir la salida para una entrada dada.

No determinísticos, sí existe uno ó más pasos en el algoritmo, para el cual es posible predecir
cuál será la salida.

Por esa razón se tienen los siguiente tipos de problemas:

I) Polinomial: Existe al menos un algoritmo polinomial determinístico que lo resuelve.


II) No -Polinomiales: Solo existen algoritmos polinomiales del tipo no deterministico que los
resuelven.

4.1.2.1 ALGORITMOS DETERMINISTICOS


En Ciencias de la computación, un algoritmo determinístico es un algoritmo que, en
términos informales, es completamente predictivo si se conocen sus entradas. Dicho de otra
forma, si se conocen las entradas del algoritmo siempre producirá la misma salida, y la
máquina interna pasará por la misma secuencia de estados. Este tipo de algoritmos ha sido
el más estudiado durante la historia y por lo tanto resulta ser el tipo más familiar de los
algoritmos, así como el más práctico ya que puede ejecutarse en las máquinas
eficientemente.
Un modelo simple de algoritmo determinístico es la función matemática, de esta forma se
puede establecer el siguiente paralelismo: la función extrae la misma salida para una
entrada dada, al igual que los algoritmos determinísticos. La diferencia es que un algoritmo
describe explícitamente como la salida se obtiene de la entrada, mientras que las funciones
definen implícitamente su salida.
Formalmente los algoritmos determinísticos se pueden definir en términos de una máquina
de estado: un estado describe que está haciendo la máquina en un instante particular de
tiempo. Justo cuando se produce la entrada, la máquina comienza en su estado inicial y,
posteriormente, si la máquina es determinística, comenzará la ejecución de la secuencia de
estados predeterminados. Una máquina puede ser determinística y no tener límite temporal
para la ejecución o quedarse en un bucle de estados cíclicos eternamente.

QUÉ HACE A UN ALGORITMO NO DETERMINÍSTICO


Una variedad de factores puede ser la causa de que un algoritmo determinístico se comporte
como de una forma no determinística:
• Si emplea en la ejecución de la secuencia de estados otro estado "externo" como
entrada del proceso, como por ejemplo: una entrada de un usuario, una variable
objetivo, un valor de un temporizador de hardware, un valor aleatorio, etc.
• Si al operar se encuentra con concurrencia de estados, por ejemplo si tiene múltiples
procesadores escribiendo al mismo tiempo en un fichero. En este caso el orden
preciso en el que cada procesador escribe el dato puede afectar a la salida y no está
pre-planificado su valor inicial.
• Si un error (cuyo origen puede deberse al hardware o al software) causa un
inesperado cambio en la secuencia de ejecución de estados.
Aunque los programas reales rara vez son puramente determinísticos, es más fácil que los
seres humanos así como otros programas determinar sobre la esencia de lo que realmente
son. Por esta razón, la mayoría de los lenguajes de programación y especialmente aquellos
que entran dentro de la categoría de programación funcional son lenguajes que hacen un
esfuerzo en prevenir eventos que se ejecutan sin control. Por esta razón este tipo de
restricciones fuerzan el carácter determinístico, a los algoritmos determinÍsticos se les
denomina purely functional.
Problemas con los algoritmos determinanticos
Para algunos problemas es muy difícil implementar un algoritmo determinístico. Por ejemplo,
existen eficientes y simples algoritmos probabilísticos que pueden determinar si un número
entero es primo o no, pero tienen una pequeña posibilidad de equivocarse. Algunos de ellos
son muy conocidos desde 1970 (véase, por ejemplo, el Test de primalidad de Fermat);
solamente tras otros 30 años de investigación focalizada en investigar se ha encontrado un
algoritmo determinístico similar, pero mucho más lento.
Otro ejemplo puede encontrarse en los problemas NP-completos. Dentro de esta categoría
puede encontrarse la mayoría de los problemas prácticos; este tipo de problemas puede
resolverse rápidamente empleando de forma masiva y paralela una máquina de Turing no
determinística, pero no se ha encontrado aún un algoritmo eficiente para esta tarea, al
menos ahora sólo encuentran soluciones aproximadas en casos especiales.
Otro problema sobre el planteamiento de algoritmos determinísticos es que a veces no es
"deseable" que los resultados sean completamente predecibles. Por ejemplo, si se es un
jugador de blackjack, un algoritmo puede mezclar una serie de Generador de números
Pseudoaleatorios y, de esta forma, un apostador espabilado podría averiguar los números
del generador y determinar las cartas sobre la mesa de juego permitiendo engañar durante
todo el tiempo al croupier (esto ocurre actualmente). Problemas similares pueden
encontrarse en criptografía, donde las claves privadas a menudo se crean mediante uno de
estos generadores. Este tipo de problemas se evita mediante el empleo de un generador
criptográfico seguro de números Pseudoaleatorios.

4.1.2.2 ALGORITMOS APROXIMADOS


Un algoritmo de aproximación es un algoritmo que entrega una solución con una garantía
teórica de cercanía al óptimo. Más aun, es frecuente que estos algoritmos posean un
desempeño práctico muy superior a su garantía teórica. En las últimas décadas, los
algoritmos de aproximación han sido (y continúan siendo) un tema central de investigación
en computación teórica y su aplicabilidad es cada vez más evidente.

4.1.2.3 ALGORITMOS HEURÍSTICOS


En computación, dos objetivos fundamentales son encontrar algoritmos con buenos tiempos
de ejecución y buenas soluciones, usualmente las óptimas. Una heurística es un algoritmo
que abandona uno o ambos objetivos; por ejemplo, normalmente encuentran buenas
soluciones, aunque no hay pruebas de que la solución no pueda ser arbitrariamente errónea
en algunos casos; o se ejecuta razonablemente rápido, aunque no existe tampoco prueba de
que siempre será así. Las heurísticas generalmente son usadas cuando no existe una
solución óptima bajo las restricciones dadas (tiempo, espacio, etc.), o cuando no existe del
todo.
A menudo, pueden encontrarse instancias concretas del problema donde la heurística
producirá resultados muy malos o se ejecutará muy lentamente. Aún así, estas instancias
concretas pueden ser ignoradas porque no deberían ocurrir nunca en la práctica por ser de
origen teórico. Por tanto, el uso de heurísticas es muy común en el mundo real.
4.1.2.4 ALGORITMOS VORACES
Un algoritmo voraz (también conocido como ávido o devorador) es aquel que, para
resolver un determinado problema, sigue una metaheurística consistente en elegir la opción
óptima en cada paso local con la esperanza de llegar a una solución general óptima. Este
esquema algorítmico es el que menos dificultades plantea a la hora de diseñar y comprobar
su funcionamiento. Normalmente se aplica a los problemas de optimización.
Esquema
Dado un conjunto finito de entradas C, un algoritmo voraz devuelve un conjunto S
(seleccionados) tal que y que además cumple con las restricciones del problema
inicial. Cada conjunto S que satisfaga las restricciones se le suele denominar prometedor, y
si éste además logra que la función objetivo se minimice o maximice (según corresponda)
diremos que S es una solución óptima.
Elementos de los que consta la técnica
• El conjunto C de candidatos, entradas del problema.
• Función solución. Comprueba, en cada paso, si el subconjunto actual de candidatos
elegidos forma una solución (no importa si es óptima o no lo es).
• Función de selección. Informa de cuál es el elemento más prometedor para
completar la solución. Éste no puede haber sido rechazado o escogido con
anterioridad. Cada elemento es considerado una sola vez. Luego, puede ser
rechazado o aceptado y pertenecerá a .
• Función de factibilidad. Informa si a partir de un conjunto se puede llegar a una
solución. Lo aplicaremos al conjunto de seleccionados unido con el elemento más
prometedor.
• Función objetivo. Es aquella que queremos maximizar o minimizar, el núcleo del
problema.
Funcionamiento
El algoritmo escoge en cada paso al mejor elemento posible, conocido como el
elemento más prometedor. Se elimina ese elemento del conjunto de candidatos (
) y, acto seguido, comprueba si la inclusión de este elemento en el conjunto
de elementos seleccionados ( ) produce una solución factible.
En caso de que así sea, se incluye ese elemento en S. Si la inclusión no fuera factible, se
descarta el elemento. Iteramos el bucle, comprobando si el conjunto de seleccionados es
una solución y, si no es así, pasando al siguiente elemento del conjunto de candidatos.
Una vez finalizado el bucle, el algoritmo comprueba si el conjunto S es una solución o no,
devolviendo el resultado apropiado en cada caso. El algoritmo se muestra a continuación:
// Esquema general de un algoritmo voraz

función
//C es el conjunto de candidatos//

mientras y no solución(S) hacer


si entonces

si solución(S) entonces
devolver //S es una solución//
si no
devolver //No hay soluciones//

4.1.3 ALGORITMOS PROBABILISTICOS


Un algoritmo probabilista (o probabilístico) es un algoritmo que basa su resultado en la
toma de algunas decisiones al azar, de tal forma que, en promedio, obtiene una buena
solución al problema planteado para cualquier distribución de los datos de entrada. Es decir,
al contrario que un algoritmo determinista, a partir de unos mismos datos se pueden obtener
distintas soluciones y, en algunos casos, soluciones erróneas.
Se puede optar por la elección aleatoria si se tiene un problema cuya elección óptima es
demasiado costosa frente a la decisión aleatoria. Un algoritmo probabilista puede
comportarse de distinta forma aplicando la misma entrada.
• A un algoritmo determinista nunca se le permite que no termine: hacer una división
por 0, entrar en un bucle infinito, etc.
• Si existe más de una solución para unos datos dados, un algoritmo determinista
siempre encuentra la misma solución (a no ser que se programe para encontrar varias
o todas).
• Un algoritmo probabilista puede encontrar soluciones diferentes ejecutándose varias
veces con los mismos datos.
• A un algoritmo determinista no se le permite que calcule una solución incorrecta para
ningún dato.
• Un algoritmo probabilista puede equivocarse siempre que esto ocurra con una
probabilidad pequeña para cada dato de entrada.
• Repitiendo la ejecución un número suficiente de veces para el mismo dato, puede
aumentarse tanto como se quiera el grado de confianza en obtener la solución
correcta.
• El análisis de la eficiencia de un algoritmo determinista es, en determinadas
ocasiones, difícil.
• El análisis de los algoritmos probabilistas es, a menudo, muy difícil.
4.1.4 IDENTIFICACION DEL PROBLEMA
Te vas a preguntar ¿Y que tiene que ver esto con la identificación de un problema?, lo más
importante es el que identifiques ¿quienes son (posibles usuarios) y como se puede
presentar este problema?
Cuando detectamos que la solución se puede dar por medio del Diseño, háblese del Diseño
Gráfico, Industrial o Arquitectónico y no por otro tipo de alternativas de solución como puede
ser por medio de una nueva propuesta administrativa, o una solución médica como si se
tratara de algún padecimiento que se resuelve con un fármaco o una terapia, o un nuevo
proceso en alguna actividad que no se esta bien realizada, entonces es un problema que a
nosotros nos interesa y que podemos buscarle una solución.
La identificación de quien es el que tiene el problema puede ser cualquier persona grupo
social o empresa, el como se presenta este problema es labor de nosotros como
diseñadores el tratar de buscar el medio o proceso para llegar a dar una respuesta al mismo.
Un ejercicio sencillo es el que te presento a continuación y que te permite tener un
panorama amplio de las posiblidades de detección del problema.
Primero, toma un pedazo de papel y, en la parte superior izquierda escribe lo siguiente:
"QUIEN ES EL QUE PADECE EL PROBLEMA". Enlista 7 cosas sobre el mismo.
"COMO SE PRESENTA EL PROBLEMA", cosas que identifiquen las causas del problema.
Una vez que hayas completado tu lista, enumera cada uno de estos aspectos por orden de
importancia. Del otro lado del papel, enlista las cosas en las que creas que pueden ser los
factores que den una solución al problema
Cuando hayas terminado, dibuja (boceta) o escribe una idea debajo de ambas listas y
pregúntate: "Si hubiera de tres a cinco productos o servicios que pudieran mejorar ese
problema, ¿cuáles y cómo serían?".
4.1.5 PLANTEAMIENTO DEL PROBLEMA
Cuando nos encontramos delante de un problema así lo que nos podemos plantear, en un
principio, es cómo se finaliza la ejecución del programa y cuáles son las estructuras e
instrucciones que se repiten.
En este ejemplo, el proceso que se repite es el movimiento de posición en posición, hasta
que se encuentra un bloque con un punto (.). Con lo que nos podemos plantear que todo
nuestro programa estará englobado dentro de esta estructura:
Mientras BloqueEncima <> "." hacer
...
MoverDer
Fin Mientras
Los puntos suspensivos se sustituirán por más instrucciones después de seguir analizando
el problema y la instrucción MoverDer sabemos que también estará ya que nos tenemos
que ir desplazando por las diferentes posiciones.
2.- Después de analizar que es lo que se repite y cómo debe acabar el programa, debemos
pensar en que es lo que se debe hacer en cada repetición, dicho de otra manera, cuáles son
las instrucciones que se deben hacer en cada una de las posiciones.
Veamos lo que realizará el Robot en cada uno de los pasos:
-Mirar qué bloque tiene encima.
-En caso de ser una de las letras (a, e, i, o, u), incrementar en 1 la variable que deberemos
crear para cada una de las letras. A estas variables vamos a llamarlas LetraA, LetraE,
LetraI, LetraO, LetraU que definiremos como siempre al principio del programa. Debemos
acordarnos de definir e inicializar las variables que vamos a utilizar en nuestro ejemplo. Esto
lo haremos al principio del programa, fuera del bucle ya que sino, las variables siempre se
irían reinicializando y no se incrementarían.
-Una vez mirada la letra del bloque que tenemos encima pasaremos a movernos una
posición hacia la derecha para volver a empezar los pasos hasta ahora indicados.
4.1.6 ANALISIS DEL PROBLEMA
(ALTERNATIVAS DE SOLUCION)
Consiste en establecer una serie de preguntas acerca de lo que establece el problema, para
poder determinar si se cuenta con los elementos suficientes para llevar a cabo la solución
del mismo, algunas preguntas son:
?Con qué cuento? Cuáles son los datos con los que se va a iniciar el proceso, qué tenemos
que proporcionarle a la computadora y si los datos con los que cuento son suficientes para
dar solución al problema.
?Qué hago con esos datos? Una vez que tenemos todos los datos que necesitamos,
debemos determinar que hacer con ellos, es decir que fórmula, cálculos, que proceso o
transformación deben seguir los datos para convertirse en resultados.
?Qué se espera obtener? Que información deseamos obtener con el proceso de datos y de
que forma presentarla; en caso de la información obtenida no sea la deseada replantear
nuevamente un análisis en los puntos anteriores.
Es recomendable que nos pongamos en el lugar de la computadora y analicemos que es lo
que necesitamos que nos ordenen y en que secuencia para producir los resultados
esperados.
4.1.7 DISEÑO DE LA SOLUCION
Una vez definido y analizado el problema, se procede a la creación del algoritmo (Diagrama
de flujo ó pseudocódigo), en el cual se da la serie de pasos ordenados que nos proporcione
un método explícito para la solución del problema.
Es recomendable la realización de pruebas de escritorio al algoritmo diseñado, para
determinar su confiabilidad y detectar los errores que se pueden presentar en ciertas
situaciones. éstas pruebas consisten en dar valores a la variable e ir probando el algoritmo
paso a paso para obtener una solución y si ésta es satisfactoria continuar con el siguiente
paso de la metodología; de no ser así y de existir errores deben corregirse y volver a hacer
las pruebas de escritorio al algoritmo.
4.1.8 PRUEBAS Y DEPURACION
Prueba es el proceso de identificar los errores que se presenten durante la ejecución del
programa; es conveniente que cuando se pruebe un programa se tomen en cuenta los
siguientes puntos:
1. - Tratar de iniciar la prueba con una mentalidad saboteadora, casi disfrutando la tarea de
encontrar un error.
2. - Sospechar de todos los resultados que arroje la solución, con lo cual se deberán verificar
todos.
3. - Considerar todas las situaciones posibles, normales y aún las anormales.
La Depuración consiste en eliminar los errores que se hayan detectado durante la prueba,
para dar paso a una solución adecuada y sin errores.
4.1.9 DOCUMENTACIÓN
Es la guía o comunicación escrita que sirve como ayuda para usar un programa, o facilitar
futuras modificaciones. A menudo un programa escrito por una persona es usado por
muchas otras, por ello la documentación es muy importante; ésta debe presentarse en tres
formas: EXTERNA, INTERNA y AL USUARIO FINAL.
Documentación Interna
Consiste en los comentarios o mensajes que se agregan al código del programa, que
explican las funciones que realizan ciertos procesos, cálculos o fórmulas para el
entendimiento del mismo.
Documentación Externa
También conocida como Manual Técnico, está integrada por los siguientes elementos:
Descripción del Problema, Nombre del Autor, Diagrama del Flujo y/o Pseudocódigo, Lista de
variables y constantes, y Codificación del Programa, esto con la finalidad de permitir su
posterior adecuación a los cambios.
Manual del Usuario
Es la documentación que se le proporciona al usuario final, es una guía que indica el usuario
como navegar en el programa, presentando todas las pantallas y menús que se va a
encontrar y una explicación de los mismos, no contiene información de tipo técnico.

4.2 OPERADORES
Esta es una lista de los operadores de los lenguajes C++ y C. Todos los operadores
listados existen en C++. La tercera columna indica si también está presente en C. También
hay que tener en cuenta que C no permite la sobrecarga de operadores.
Los siguientes operadores son puntos de secuencia en ambos lenguajes (cuando no están
sobrecargados): &&, ||, ?:, y , (el operador coma).
C++ también incluye los operadores de conversión de tipos const_cast, static_cast,
dynamic_cast y reinterpret_cast que no están listados en la tabla por brevedad. El formato
de estos operadores significa que su nivel de precedencia no es importante.
Estos operadores que están en C (con la excepción del operador coma y el operador flecha
también se encuentran en Java, Perl, C# y PHP con la la misma precedencia, asociatividad y
semántica. Con una única excepción: la asociatividad del operador ternario en PHP es de
izquierda a derecha.
Para los objetivos de esta tabla a, b y c representan valores válidos (literales, valores de
variables o valores de retorno), nombres de objetos o valores según el caso.
Operadores aritméticos
Nombre del operador Sintaxis Sobrecargable Incluido en C
Más unitario +a Sí Sí
Suma a + b Sí Sí
Preincremento ++a Sí Sí
Postincremento a++ Sí Sí
Asignación con suma a += b Sí Sí
Menos unitario (negación) -a Sí Sí
Resta a - b Sí Sí
Predecremento --a Sí Sí
Postdecremento a-- Sí Sí
Asignación con resta a -= b Sí Sí
Multiplicación a * b Sí Sí
Asignación con multiplicación a *= b Sí Sí
División a / b Sí Sí
Asignación con división a /= b Sí Sí
Módulo (Resto) a % b Sí Sí
Asignación con módulo a %= b Sí Sí
Operadores de comparación
Nombre del operador Sintaxis Sobrecargable Incluido en C
Menor que a < b Sí Sí
Menor o igual que a <= b Sí Sí
Mayor que a > b Sí Sí
Mayor o igual que a >= b Sí Sí
No igual que a != b Sí Sí
Igual que a == b Sí Sí
Negación lógica !a Sí Sí
AND lógico a && b Sí Sí
OR lógico a || b Sí Sí
Operadores a nivel de bit
Nombre del operador Sintaxis Sobrecargable Incluido en C
Desplazamiento a la izquierda a << b Sí Sí
Asignación con desplazamiento a la izquierda a <<= b Sí Sí
Desplazamiento a la derecha a >> b Sí Sí
Asignación con desplazamiento a la derecha a >>= b Sí Sí
Complemento a uno ~a Sí Sí
AND binario a & b Sí Sí
Asignación con AND binario a &= b Sí Sí
OR binario a | b Sí Sí
Asignación con OR binario a |= b Sí Sí
XOR binario a ^ b Sí Sí
Asignación con XOR binario a ^= b Sí Sí
Otros operadores
Nombre del operador Sintaxis Sobrecargable Incluido en C
Asignación básica a = b Sí Sí
Llamada a función a() Sí Sí
Índice de Array a[b] Sí Sí
Indirección (Desreferencia) *a Sí Sí
Dirección de (Referencia) &a Sí Sí
Miembro de puntero a->b Sí Sí
Miembro a.b No Sí
Desreferencia a miembro por puntero a->*b Sí No
Desreferencia a miembro por objeto a.*b No No
Conversión de tipo (tipo) a Sí Sí
Coma a , b Sí Sí
Condicional ternario a ? b : c No Sí
Resolución de ámbito a::b No No
Puntero a función miembro a::*b No No
sizeof a
Tamaño de sizeof(tipo) No Sí
typeid(a)
Identificación de tipo typeid(tipo) No No
Asignar almacenamiento new tipo Sí No
Asignar almacenamiento (Vector) new tipo[n] Sí No
Desasignar almacenamiento delete a Sí No
Desasignar almacenamiento (Vector) delete[] a Sí No

Extensiones del lenguaje


Nombre del operador Sintaxis Sobrecargable Incluido en C Vendedor
Dirección de la etiqueta && etiqueta No Sí GCC
typeof a
Obtener tipo typeof(expr) No Sí GCC
a <? b
min y max a >? b No No GCC

Precedencia de operadores
La tabla siguiente es una lista que muestra el orden de precedencia y la asociatividad de
todos los operadores del lenguaje de programación C++. Están listados de arriba a abajo por
orden de precedencia descendente y con la misma descendencia en la misma celda
(pueden haber varias filas de operadores en la misma celda). La precedencia de los
operadores no cambia por la sobrecarga.
Una tabla de precendencias, aunque adecuada, no puede resolver todos los detalles. Por
ejemplo el operador ternario permite expresiones arbitrarias como operador central
independientemente de la precedencia del resto de operadores. Así a ? b , c : d es
interpretado como a ? (b, c) : d en vez de (a ? b), (c : d). También hay que tener en cuenta
que el resultado sin paréntesis de una expresión de conversión en C no puede ser el
operando de sizeof. Por eso sizeof (int) * x es interpretado como (sizeof(int)) * x y no como
sizeof ((int) *x).
Operador Descripción Asociatividad
:: Resolución de ámbito (solo C++) Izquierda a
Post- incremento y decremento derecha
++ -- Llamada a función
()
[] Elemento de vector
. Selección de elemento por referencia
-> Selección de elemento con puntero
typeid() Información de tipo en tiempo de ejecución (solo C++)
const_cast Conversión de tipo (solo C++)
dynamic_cast
Conversión de tipo (solo C++)
reinterpret_cast
static_cast Conversión de tipo (solo C++)
Conversión de tipo (solo C++)
++ -- Pre- incremento y decremento Derecha a
+- Suma y resta unitaria izquierda
!~ NOT lógico y NOT binario
(type) Conversión de tipo
* Indirección
&
sizeof Dirección de
new new[]
Tamaño de
delete delete[]
Asignación dinámica de memoria (solo C++)
Desasignación dinámica de memoria (solo C++)
.* ->* Puntero a miembro (solo C++) Izquierda a
*/% Multiplicación, división y módulo derecha
+- Suma y resta
<< >> Operaciones binarias de desplazamiento
< <= Operadores relaciones "menor que", "menor o igual que",
> >= "mayor que" y "mayor o igual que"
== != Operadores relaciones "igual a" y "distinto de"
& AND binario
^ XOR binario
| OR binario
&& AND lógico
|| OR lógico
c?t:f Operador ternario Derecha a
= izquierda
+= -=
*= /= %= Asignaciones
<<= >>=
&= ^= |=
throw Operador Throw (lanzamiento de excepciones, solo C++)
Izquierda a
, Coma
derecha
4.2.1 ARITMETICOS
Los operadores aritméticos nos permiten, básicamente, hacer cualquier operación aritmética, que
necesitemos (ejemplo: suma, resta, multiplicación, etc). En la siguiente tabla se muestran los
operadores de los que disponemos en C y su función asociada.

Tabla: Operadores aritméticos


Operador Acción Ejemplo
Resta x=5 3; // x vale 2
Suma x=2 3; // x vale 5
Multiplicación x = 2 3; // x vale 6

División
x = 6 2; // x vale 3
Módulo x = 5 % 2; // x vale 1

Decremento x = 1; x ; // x vale 0
Incremento x = 1; x ; // x vale 2
4.2.2 LOGICOS
Los operadores lógicos producen un resultado booleano, y sus operandos son también valores lógicos
o asimilables a ellos (los valores numéricos son asimilados a cierto o falso según su valor sea cero o
distinto de cero). Por contra, recuerde que las operaciones entre bits producen valores arbitrarios.
Los operadores lógicos son tres; dos de ellos son binarios, el último (negación) es unario. Tienen una
doble posibilidad de representación en el Estándar C++ actual: la representación tradicional que se
indica a continuación, y la natural introducida recientemente que se detalla más adelante .
• Y lógico && AND
• O lógico || OR
• Negación lógica ! NOT
Las expresiones conectadas con los operadores && y || se evalúan de izquierda a derecha, y la
evaluación se detiene tan pronto como el resultado verdadero o falso es conocido (muchos programas
tienen una lógica que se basa en este propiedad).
&& Operador Y lógico
También denominado por su nombre en inglés (generalmente en mayúsculas) AND lógico. Devuelve
un valor lógico true si ambos operandos son ciertos. En caso contrario el resultado es false.
Sintaxis
expr-AND-logica && expresion-OR-inclusive
Comentario:
La operatoria es como sigue: El primer operando (de la izquierda) es convertido a bool. Para ello, si es
una expresión, se evalúa para obtener el resultado (esta computación puede tener ciertos efectos
laterales). A continuación, el valor obtenido es convertido a bool cierto/falso siguiendo las reglas de
conversión estándar .Si el resultado es false, el proceso se detiene y este es el resultado, sin que en este
caso sea necesario evaluar la expresión de la derecha (recuérdese que en el diseño de C++ prima la
velocidad).
Si el resultado del operando izquierdo es cierto, se continúa con la evaluación de la expresión de la
derecha, que también es convertida a bool. Si el nuevo resultado es true, entonces el resultado del
operador es true. En caso contrario el resultado es false.
Nota: la Norma informa que antes de ser evaluada la expresión derecha, han sucedido todos los
posibles efectos laterales de la expresión izquierda, a excepción de la destrucción de los posibles
objetos temporales que se hubiesen creado.
Ejemplo:
int m[3] = {0,1,2};
int x = 0;
if (m && x) cout << "Cierto.";
else cout << "Falso.";
Salida:
Falso.
El valor m, que es interpretado como un puntero al primer elemento de la matriz, es transformado a un
bool. Como es distinto de cero (no es un puntero nulo) el resultado es cierto. A continuación, el valor x
es convertido también a bool. En este caso la conversión produce falso, con lo que este es el resultado
del paréntesis de la sentencia if.
Ejemplo
#include <iostream.h>

bool alto = true, bajo = false, blanco = true, negro = false;

int main (void) {


if (alto && bajo) { cout << "Uno cierto" << endl; }
else cout << "Uno falso" << endl;
if (alto && blanco) { cout << "Dos cierto" << endl; }
else cout << "Dos falso" << endl;
if (bajo && negro) { cout << "Tres cierto" << endl; }
else cout << "Tres falso" << endl;
}
Salida:
Uno falso
Dos cierto
Tres falso
|| Operador O lógico
Este operador binario devuelve true si alguno de los operandos es cierto. En caso contrario devuelve
false.
Sintaxis
expr-OR-logica || expresion-AND-logica
Comentario
Este operador sigue un funcionamiento análogo al anterior. El primer operando (izquierdo) es
convertido a bool. Para ello, si es una expresión, se evalúa para obtener el resultado (esta computación
puede tener ciertos efectos laterales). A continuación el valor obtenido es convertido a bool
cierto/falso siguiendo las reglas de conversión estándar . Si el resultado es true, el proceso se detiene y
este es el resultado, sin que en este caso sea necesario evaluar la expresión de la derecha (recuérdese
que en el diseño de C++ prima la velocidad).
Si el resultado del operando izquierdo es false, se continúa con la evaluación de la expresión de la
derecha, que también es convertida a bool. Si el nuevo resultado es true, entonces el resultado del
operador es true. En caso contrario el resultado es false.
Nota: el Estándar establece que antes de ser evaluada la expresión derecha, han sucedido todos los
posibles efectos laterales de la expresión izquierda, a excepción de la destrucción de los posibles
objetos temporales que se hubieran creado.
Ejemplo
#include <iostream.h>
bool alto = true, bajo = false, blanco = true, negro = false;

int main (void) {


if (alto || bajo) { cout << "Uno cierto" << endl; }
else cout << "Uno falso" << endl;
if (alto || blanco) { cout << "Dos cierto" << endl; }
else cout << "Dos falso" << endl;
if (bajo || negro) { cout << "Tres cierto" << endl; }
else cout << "Tres falso" << endl;
}
Salida
Uno cierto
Dos cierto
Tres falso
! Operador NO lógico:
Este operador es denominado también negación lógica y se representa en el texto escrito por la palabra
inglesa NOT (otros lenguajes utilizan directamente esta palabra para representar el operador en el
código).
Sintaxis
! expresion-cast
Comentario
El operando expresion-cast (que puede ser una expresión que se evalúa a un resultado es convertido a
tipo bool, con lo que solo puede ser uno de los valores cierto/falso. A continuación el operador cambia
su valor: Si es cierto es convertido a falso y viceversa.
Resulta por tanto, que el resultado de este operador es siempre un tipo bool, aunque al existir una
conversión estándar por la que un cero es convertido a false, y cualquier valor distinto de cero a true
coloquialmente se dice que este operador convierte un operando 0 en 1 y uno no-cero en 0. En otras
palabras: este operador devuelve cierto (true) si la expresión se evalúa a distinto de cero, en caso
contrario devuelve falso (false).
Ejemplo
#include <iostream.h>
bool alto = true, bajo = false;

int main (void) {


if (alto) { cout << "Uno cierto" << endl; }
else cout << "Uno falso" << endl;
if (!alto) { cout << "Dos cierto" << endl; }
else cout << "Dos falso" << endl;
if (!bajo) { cout << "Tres cierto" << endl; }
else cout << "Tres falso" << endl;
}
Salida:
Uno cierto
Dos falso
Tres cierto

Si E es una expresión, !E es equivalente a (0 == E). Como consecuencia, las expresiones que siguen
son equivalentes dos a dos:
if (! valid);
if (valid == 0);
...
if (valid);
if (valid != 0);
Representación explícita
Los operadores lógicos entre valores lógicos &&, ||, !; la relación de desigualdad !=; algunos de los
operadores lógicos entre bits (&, |, ^, ~) y sus expresiones compuestas (&=, |=, ^=), tienen una
representación realmente difícil de leer, con la desventaja adicional que sus símbolos no siempre están
fácilmente accesibles en ordenadores con teclados distintos del estándar USA. Para resolver este
problema, el Estándar C++ ha introducido nuevas formas para su representación; las denominamos
formas explícitas o naturales, en razón de que se parecen más a las palabras correspondientes del
lenguaje natural. Las nuevas formas constituyen palabras-clave, y la tabla de equivalencias es la
siguiente:

Palabra
Símbolo Descripción
clave
and && Operador Y lógico

or || Operador O lógico

not ! Operador negación lógica

bitand & Operador AND entre bits

xor ^ Operador OR exclusivo entre bits

bitor | Operador OR inclusivo entre bits

compl ~ Operador complemento a uno de bits


Asignación compuesta (AND entre
and_eq &=
bits)
Asignación compuesta (XOR entre
xor_eq ^=
bits)
Asignación compuesta (OR entre
or_eq |=
bits)
not_eq != Operador relacional de desigualdad

Nota: ni el compilador Borland C++ 5.5 ni MS VC++ 6.0 soportan esta característica del
estándar, aunque el de Microsoft anuncia en su documentación que pueden utilizarse
"defines". Por ejemplo:
#define bitand &
#define bitor |
#define and_eq &=
#define or_eq |=
#define not_eq !=
Por su parte, el compilador GNU gcc dispone de la opción de compilación -fno-operator-
names, que permite que las palabras-clave and, bitand, bitor, compl, not, y or, no sean
tratadas como sinónimos de los operadores correspondientes.
4.2.3 JERARQUIA DE OPERADORES
Jerarquía de Operaciones:
()
signo
Potencia
Producto y división
Div
Mod
Suma y resta
Concatenación
Relacionales
Negación
And
Or
Datos de tipo entero tienen los operadores +, -, *, /, div, mod, abs, sqr, sqrt, ln, exp, sin, cos,
tan, pow, etc. Los datos de tipo real tienen los mismos operadores enteros y además trunc,
round, int, y otros. La suma y multiplicación de datos de tipo real cumplen la propiedad
conmutativa, pero no siempre la asociativa y la distributiva.
Para resolver una expresión aritmética se deben seguir las siguientes reglas:
· Primero se resuelven las expresiones que se encuentran entre paréntesis.
· Se procede aplicando la jerarquía de operadores.
· Al evaluar una expresión, si hay dos operadores con la misma jerarquía, se procede a
evaluar de izquierda a derecha.
· Si hay expresiones relacionales, se resuelven primero paréntesis, luego se encuentran los
valores de verdad de las expresiones relacionales y por último se aplica jerarquía de
operadores lógicos. En caso de haber iguales, proceder de izquierda a derecha.

4.3 EXPRECIONES
En programación, una expresión es una combinación de constantes, variables o funciones,
que es interpretada (evaluada) de acuerdo a las normas particulares de precedencia y
asociación para un lenguaje de programación en particular. Como en matemáticas, la
expresión es su "valor evaluado", es decir, la expresión es una representación de ese valor.
Ejemplos de expresiones
• Expresión aritmética: 3+2, x+1, ...
• Expresión lógica: x OR y, NOT x, ...
• Expresión con predicados: P(a) AND Q(b), ...

4.4 ESTRUCTURAS DE CONTROL


En programación, las estructuras de control permiten modificar el flujo de ejecución de las
instrucciones de un programa. Con las estructuras de control se puede ejecutar
instrucciones de forma condicionada.
en la programación, se necesitan estrategias para resolver un problema, tan simple como
llevar el peso de los pasajeros de un avión, como uno tan difícil como llevar la base de datos
de un ministerio…
Es por eso que “Las estructuras de control” son las herramientas que nos ayudan a pensar
en grande sin ninguna limitación. Imagina de no existieran, la programación perdería
seguidores.
Ha de mencionarse que hay ramificaciones de estas estructuras y que las mismas usan
variables (para recordar, espero que hallas deducido esto):
å Estructuras Repetitivas.
å Estructuras de Alternativas.
Definámoslas…
å Estructuras Repetitivas: son aquellas estructuras que nos permiten repetir un número
de instrucciones un determinado número de veces.
å Estructuras de Alternativas: son aquellas estructuras que nos dan la posibilidad de
escoger un camino, dependiendo de la opción que tengamos al evaluar una expresión
(al decir expresión, no me refiero a matemáticas, sino; a una evaluación de por
ejemplo si esto es esto, o aquello llego a, etc…¿me expliqué?)
Clasificación:
å Las estructuras repetitivas se clasifican en 3. Estructura, Para, Mientras y Hasta que.
å Las estructuras de Alternativas se clasifican en 3. Estructura Sí-Entonces (condicional
simple), Estructura Sí-Entonces-De lo contrario (condicional doble) y Estructura Caso.
Estructuras Repetitivas
å Estructura Para: la usamos cuando sabemos cuatas veces se van a repetir las
instrucciones o podemos decir, un número de veces conocido.
å Estructura Mientras: esta estructura funciona evaluando una opción. Si esta es cierta,
entra al ciclo de repetición, de lo contrario continúa con el resto del código. Se utiliza
cuando no sabemos cuantas veces se van a repetir.
å Estructura Hasta que: al igual que la otra, utiliza una expresión para entrar al ciclo
repetitivo. Si esta es falsa, el entra, y de lo contrario, continúa con la ejecución del
código. Se utiliza cuando sabemos que se repetirán por lo menos una vez o cada vez
que no sabemos cuantas veces se van a repetir.
Cabe señalar dos cosas: 1. Que es muy importante saber, que las estructuras Mientras y
Hasta que, si trabajan con una expresión para entrar al ciclo, ellas necesitan, POR FUERZA,
una expresión (dentro del código) que modifique a la variable del la expresión (antes de
entrar). 2. Las variables a utilizar en las expresiones de las tres estructuras deben ser POR
FUERZA, enteros, ya que no existe ciclo y medio para decir que la variable es flotante.
Veámoslo en Algoritmo.
Estructura Para.
Formato:
Para (variable1=0; variable1>=número u otra variable; variable1=variable1+1[o dos, o tres])
{
Código a ejecutar;
}
De otra forma:
entero x;
Para (x=0; x>2[puedes usar el igual dependiendo de tú lógica]; x=x+1[es valido: x++])
{
Código a ejecutar;
}
*cuando llega aquí, el regresa para evaluar la opción, para ver si es cierta o falsa, eso para
con las otras dos estructuras.
Explicación: cuando entra por primera vez, pregunta: x>2 (0>2), ¿por que cero?, ya que x
vale 0; esto es cierto, el entra. Termina y vuelve pregunta: x>2 (en este caso será: 1>2, ya
que al entrar la x aumenta en uno y así sucesivamente, hasta hacer la condición cierta (x>2).
Estructura Mientras.
Formato:
Mientras(expresión)
{
Código a ejecutar;
Expresión que modifica a la expresión madre;
}
*cuando llega aquí, regresa para revisar la expresión.
Ejemplo:
entero y;
Mientras(y<5)
{
Imprimir(“Hola@”);
y=y+1; (expresión que modifica, ¿me expliqué con esto?)
}
*cuando llega aquí, regresa a verificar si la expresión es cierta.
Explicación: se declara “y” como entero y toma el valor de 0 por defecto. Cuando llega al
ciclo, pregunta: y<5 y="y">
“Se cuenta de 0 hacia delante. El 0 cuenta, pero si no quieres, puedes decir que comience
en 1. Si realizas una prueba de escritorio con las dos formas, dan los dos, 5 repeticiones (de
0 a 4 y de 1 a 5)
¿Me estoy explicando?
Estructura Hasta que.
Formato:
Hasta que(expresión)
{
Código a ejecutar;
Expresión que modifica a la expresíon madre.
}
*cuando llega aquí, regresa para revisar la expresión.
Ejemplo:
entero k;
Hasta que (k>=2)
{
Imprima(“¿¿¿Estás aprendiendo?????@”);
k++; (esto es válido y modifica a la “k” para utilizar en la expresión)
}
*cuando llega aquí, regresa a verificar si la expresión es falsa.
La explicación es la misma, solo que la exopresión debe ser falsa para entrar.
Estructuras Alternativas
å Estructura Sí-Entonces (condicional simple): se usa cuando, al evaluar una expresión,
si está es cierta, entre a ejecutar un único código de instrucciones.
å Estructura Sí-Entonces-De lo contrario (condicional doble): la usamos cuando al
evaluar una opción, si esta es cierta, ejecuta una serie de instrucciones; de darse que
no es cierta, ejecutará el otro código de instrucciones.
å Estructura Caso: se usa cuando se sabe que se escogerá más de dos opciones.
Podemos pensar que sería como un menú, de hecho, es esta la estructura propicia
para hacer menús. Auque, como la lógica es la que manda, también se pude hacer un
menú con estructuras Sí-Entonces o Sí-Entonces-De lo contrario. Estas estructuras
estarían embebidas (una dentro de la otra). Esta estructura trabaja con una sola
variable que será entera. Dependiendo del valor que tenga, entrará buscando el caso
que conquierde con el valor, cuando lo encuentra, ejecutará el código que esté escrito
dentro del mismo. Cabe señalar que es muy importante que dentro del código debe
estar la sentencias “break;”, que le dice a la estructura, que ya terminó, y que debe
salir, para continuar con el resto del código.
Veamos los formatos.
Estructura Sí-Entonces.
Formato:
Sí (condición)
{
Código a ejecutar;
}
Ejemplo:
Sí(a>5)
{
Imprima (“a tiene un valor mayor que 5, por eso entró, ya es cierto”);
}
Estructura Sí-Entonces-De lo contrario.
Formato:
Sí (condición)
{
Código a ejecutar si la condición es cierta;
}
De lo contrario
{
Código a ejecutar si no se cumple la condición;
}
Ejemplo:
Sí (a<3)
{
Imprima (“a tiene un valor menor que 3”);
}
De lo contrario
{
Imprima (“a tiene un valor mayor que 3”);
}
Si no se cumple, entra a la parte falsa.
Estructura Caso.
Formato:
Caso (variable)
{
Caso 1
{
Código de instrucciones ejecutar si la condición es correcta;
}
Caso 2
{
Código de instrucciones ejecutar si la condición es correcta;
}
Caso 3
{
Código de instrucciones ejecutar si la condición es correcta;
}
Y así sucesivamente…
}*esta es la llave que cierra el cuerpo del caso
Ejemplo:
Caso (a)
{
Caso 1
{
Imprima (“¿Estás aprendiendo?”);
break;
}
Caso 2
{
Imprima (“Si no entiendes, pregúntame!!!”);
break;
}
}*esta es la llave que cierra el cuerpo del caso.
Si la a es 1, entra y realiza lo que está en el bloque uno, si es dos, lo que está en el bloque
dos.
4.4.1 SELECTIVAS
Existen tres tipos de estructuras de control selectivas, estas se basan en una condición o en una opción para
decidir la parte del programa por el que pasará.
a. Simple b)Doble o compuesta c)Múltiple
Selectiva simple.- evalúa una condición, si esta es verdadera ejecuta la acción o acciones especificadas, si es
falsa no realiza ninguna acción.

Nota: Si existe sola una instrucción o sentencia dentro de la condición no es necesario marcarlos con inicio y
fin, en caso contrario si, como se muestra en el diagrama anterior.
Selectiva doble o compuesta.- evalúa una condición, si esta es verdadera ejecuta la acción o acciones
especificadas, si es falsa ejecuta otra acción o acciones.
Nota: Si existe sola una instrucción o sentencia dentro de la condición no es necesario marcarlos con inicio y
fin como en este caso que la condición fue falsa, en caso contrario si, en este ejemplo cuando la condición fue
verdadera.
Ejemplo: Imprimir si un número es positivo o negativo

Nota: las variables no se especifican en el diagrama de flujo, pero si en el pseudocódigo .


4.4.2 ITERATIVAS
En C existen 3 estructuras repetitivas: while, for y do .. while
Estructura While
Sintaxis:
while(condición)
� Acción;
En este caso, la sentencia Acción es ejecutada mientras el condicional condición se evalúa
verdadera (distinta de 0)
En el caso de que el cuerpo del while (acciones a ejecutar en caso de que el condicional se
verifique) posea más de una sentencia, todas ellas son encerradas entre llaves:
while(condición)
{
� Acción1;
� Acción2;
� ...
}
El condicional es una expresion relacional que puede involucrar operadores relacionales (>,
<, >=, <=, ==, !=) y/o operadores logicos (&&, ||, !)
Ejemplo:
/*
Programa que imprime la tabla de conversión de
Fahrenheit a Celsius para F = 0, 20, 40,..., 300
*/
#include <stdio.h>

int main()
{
� int Lower, Upper, Step;
� float Fahr, Celsius;

� Lower = 0;
� Upper = 300;
� Step = 20;
� Fahr = Lower;

� while(Fahr <= Upper)


� {
��� Celsius = (5.0/9.0) * (Fahr - 32.0);
��� printf("%4.0f F -> %6.1f C\n", Fahr, Celsius);
��� Fahr = Fahr + Step;
� } /* fin del while */

��return 0;
} /* fin del main */

NOTAS:

Lazo while(...) { ... }


Lo que se encuentra entre paréntesis es una expresión a evaluar. Mientras el resultado de la
misma sea distinto de cero, se ejecutan las sentencias asociadas que se encuentran
encerradas entre llaves. A este tipo de sentencias se las llama sentencias compuestas. Si el
cuerpo de esta sentencia consiste en una sola sentencia simple, pueden omitirse las llaves.
Las sentencias compuestas no llevan el carácter; como terminador. Para mejorar la
legibilidad del programa, conviene intentar las sentencias compuestas.
Cálculo y asignación:
Celsius = (5.0/9.0) * (Fahr - 32.0)
El punto decimal en los operandos de la división es requerido para que la operación sea
llevada en punto flotante; de lo contrario la misma se efectúa como cociente de números
enteros, truncando por lo tanto el resultado a cifras enteras. En nuestro caso será truncado a
0.
Estructura for
Esta estructura es una generalización de la estructura while usada en el ejercicio anterior.
Su función es ejecutar iterativamente el cuerpo del bloque, que como en el caso del while
puede ser simple o compuesto. La definición de esta estructura de control posee 3 partes
separadas por el carácter ";".
for(a; b; c)
{
� ...
� ...
}
La parte a es la de inicialización, y puede poseer una sentencia, ninguna, o varias separadas
por el carácter ",". Esta parte se ejecuta inmediatamente antes de entrar en el ciclo.
La parte b es el criterio o condición de control de la iteración. Se evalúa antes de entrar a
cada ciclo, inclusive en la primer iteración. Si su resultado es distinto de cero se ejecuta el
ciclo; sino se abandona el ciclo y se sigue con la sentencia posterior al cuerpo del for.
La parte c es la re inicialización, que es ejecutada al final de cada ciclo.
Podemos simular el bloque for con la siguiente lógica:

a;
while(b)
{
� ...
� ...
� c;
}

Ejemplo:
/* Tabla de conversión de grados F a Celsius
utilizando constantes simbólicas y bloque for */
#include <stdio.h>

#define LOWER 0
#define UPPER 300
#define STEP 20

main()
{
int Fahr;

for(Fahr = LOWER; Fahr <= UPPER; Fahr += STEP)


printf("%4.0f F -> %6.1f C\n", Fahr, (5.0/9.0)*
(Fahr - 32));
}
NOTA:
Uso de constantes simbólicas. Cuando se requieran valores numéricos constantes en un
programa, deben definirse como constantes y no usar sus valores numéricos dentro del
programa. C permite definir constantes simbólicas (directiva #define al preprocesador) que
asocian un símbolo (LOWER, UPPER, STEP) con una expresión (0,300 y 20
respectivamente) de tal manera que el preprocesador reemplaza cualquier ocurrencia de
esos símbolos por sus expresiones asociadas
Estructura Do-While
la estructura de control do-while es una variación sobre el bloque while
do
{
Acción1;
Acción2;
}while(condición);
La diferencia esta en que la condición se chequea al final y las acciones son ejecutadas al
menos una vez. Por ejemplo
/*
Programa que pide al usuario un número entero entre 1 y 10.
Se continua pidiendo el valor hasta que cumpla la condición
*/
#include <stdio.h>

int main()
{
� int n, error;

� do {
����� printf("Ingrese un número entero entre 1 y 10: ");
����� scanf("%d", &n);
����� if (error = (n < 1 || n > 10))
�������� printf("\nERROR: Intentelo nuevamente!!\n\n");
�����} while(error);

/* ahora puedo procesar el valor ingresado sabiendo que es


correcto. */

��� return 0;
} /* fin del main */

También podría gustarte