Estructuras Anidadas
Estructuras Anidadas
Estructuras Anidadas
//: C04:Stack.h
// Nested struct in linked list
#ifndef STACK_H
#define STACK_H
struct Stack {
struct Link {
void* data;
Link* next;
void initialize(void* dat, Link* nxt);
}* head;
void initialize();
void push(void* dat);
void* peek();
void* pop();
void cleanup();
};
#endif // STACK_H ///:~
La estructura anidada tiene su propia función initialize(), como todas las estructuras
hasta el momento, para asegurar una inicialización adecuada. Stack tiene tanto función
initialice() como cleanup(), además de push(), que toma un puntero a los datos
que se desean almacenar (asume que ha sido alojado en el montículo), y pop(), que
devuelve el puntero data de la cima de la Stack y elimina el elemento de la cima. (El
que hace pop() de un elemento se convierte en responsable de la destrucción del objeto
apuntado por data.) La función peak() también devuelve un puntero data a la cima de
la pila, pero deja el elemento en la Stack.
void
Stack::Link::initialize(void* dat, Link* nxt) {
data = dat;
next = nxt;
}
void* Stack::peek() {
require(head != 0, "Stack empty");
return head->data;
}
void* Stack::pop() {
if(head == 0) return 0;
void* result = head->data;
Link* oldHead = head;
head = head->next;
delete oldHead;
return result;
}
void Stack::cleanup() {
require(head == 0, "Stack not empty");
} ///:~
Stack::initialize() asgina cero a head, de modo que el objeto sabe que tiene una
lista vacía.
¿Por qué no puede el destructor de Stack responsabilizarse de todos los objetos que el
programador cliente no des-apiló? El problema es que la Stack está usando punteros
void, y tal como se verá en el Capítulo 13 usar delete para un void* no libera
correctamente. El asunto de «quién es el responsable de la memoria» no siempre es
sencillo, tal como veremos en próximos capítulos.
//: C04:StackTest.cpp
//{L} Stack
//{T} StackTest.cpp
// Test of nested linked list
#include "Stack.h"
#include "../require.h"
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
Como textlines se llena, el contenido de line se «clona» para cada push() creando
un new string(line). El valor devuelto por la expresión new es un puntero al nuevo
string que fue creado y al que se ha copiado la información de la line. Si se hubiera
pasado directamente la dirección de line a push(), la Stack se llenaría con direcciones
idénticas, todas apuntando a line. Más adelante en ese libro aprenderá más sobre este
proceso de «clonación».
El nombre del fichero se toma de línea de comando. Para garantizar que hay suficientes
argumentos en la línea de comando, se usa una segunda función del fichero de cabecera
require.h: requireArgs() que compara argc con el número de argumentos deseado e
imprime un mensaje de error y termina el programa si no hay suficientes argumentos.
//: C04:Scoperes.cpp
// Global scope resolution
int a;
void f() {}
struct S {
int a;
void f();
};
void S::f() {
::f(); // Would be recursive otherwise!
::a++; // Select the global a
a--; // The a at struct scope
}
int main() { S s; f(); } ///:~
Sin resolución de ámbito en S::f(), el compilador elegiría por defecto las versiones
miembro para f() y a.
Estructuras Anidadas
Estructuras de decisión anidadas (en escalera)
Las estructuras de selección Si-entonces y si-entonces-si_no implican la
selección de dos alternativas.
Es posible también utilizar la instrucción si para diseñar estructuras de
selección que contengan más de dos alternativas. Una sentencia si-entonces
puede contener otra estructura si-entonces, y esta a su vez puede contener
otra, y así sucesivamente; al mismo tiempo, dentro de cada estructura pueden
existir diferentes acciones.
Las estructuras si interiores a otras estructuras si se denominan anidadas.
Si <condición> entonces
Si < condición2> entonces
Si < condición3> entonces
.
.
.
< acciones>
Fin_si
Fin_si
Fin_si
Anidamiento (informática)
De Wikipedia, la enciclopedia libre
Saltar a: navegación, búsqueda
Debido a que la potencial acumulación de éstos últimos suele hacer que la edición y la
detección de errores se vuelva un proceso engorroso, los entornos de programación
modernos -así como los programas de planilla de cálculo- resaltan en negrita el par
correspondiente a la posición que está editando el programador o usuario en cada
momento. El control (automático) del balance o equilibrio entre los paréntesis de
apertura y de cierre se suele conocer como brace match checking en inglés.
En programación[editar]
En los lenguajes de programación estructurada, el anidamiento está relacionado a la
inclusión de estructuras de control dentro de otras, usualmente indicado mediante la
inclusión de distintos niveles de sangría (llamada indentation en inglés) dentro del
código fuente, como se muestra en el sencillo código BASIC siguiente:
ruta="C:\Probar.csv"
if FileExists(ruta) then
open "C:\Probar.csv" for input as #1
do while not EOF(1)
line input #1, linea
if left(linea, 3)=cod then
'Realizar una acción o varias acciones
End if
loop
close #1
BuscarCodigo=valor_a_devolver
end function
En este simple ejemplo, la estructura condicional if... then... end if ("si... entonces... fin
si") está anidada dentro de otra que la contiene, el ciclo do while... loop ("repetir...
mientras", literalmente "hacer mientras... bucle").
Ups, perdón por este pequeño receso, pero ya estoy listo para la siguiente
lección vamos a hablar más de las instrucciones condicionales, específicamente
de instrucciones de condición anidadas.
Ejemplo 1
Con una comparación con 0 descubrimos si es positivo o no, si lo es, basta con
agregar otro if para compararlo con 10 e indicar si es positivo y mayor que 10
este es el código:
if ( Numero >= 0 ) {
if (Numero > 10) {
stringItem.setText("El Número es positivo y mayor a 10");
}
else {
stringItem.setText("El Número es positivo y menor a 10");
}
}
else
stringItem.setText("El Número es negativo");
Algo importante es la sangría (el espacio que se deja al iniciar las sentencias), se
utiliza para ir agrupando claramente los if, y no confundirse, es altamente
recomendable agregar la sangría a los if.
Ejemplo #2
Solución
Otra vez se requiere varias comparaciones, varios if anidados, por ejemplo para
saber si el triangulo es equilátero, se comparan los lados para saber si son
iguales, como se observa en el código siguiente:
if ( L1 == L2 ) {
if ( L2 == L3)
stringItem.setText("El triangulo es equilatero");
}
Para saber si es el triangulo es isósceles se requieren varias comparaciones para
comprobar las tres opciones posibles, para saber si hay dos lados iguales de la
siguiente forma:
if ( L1 == L2 ) { //Opción 1: cuando L1 es igual a L2 pero diferente a
L3
if ( L3 != L1)
stringItem.setText("El triangulo es isósceles");
}
else {
if ( L1 == L3 ) { //Opción 2: cuando L1 es igual a L3 pero diferente a
L2
if ( L2 != L1)
stringItem.setText("El triangulo es isósceles");
}
else {
if ( L3 == L2 ) {//Opción 3: cuando L3 es igual a L2 pero diferente a
L1
if ( L1 != L2)
stringItem.setText("El triangulo es isósceles");
}
}
}
No lo había mencionado en el blog pero // en Java significa un comentario y se
agrega para explicar el código, hay que tener cuidado con las { } por eso
precisamente se recomienda ampliamente el uso de sangría para identificar
claramente los grupos de instrucciones que van en el if o en el else y cerrar
adecuadamente las llaves.
Operador AND ( Y )
Su tabla de verdad nos muestra cuando dos variables unidas por un AND son
verdaderas o falsas:
Operador 1 Operador 2 Operador 1 AND Operador 2
F F F
F V F
V F F
V V V
Véase la tabla de verdad, solo hay una opción para que el operador AND sea
verdadero: cuando sus dos operadores sean verdaderos.
Con este operador se puede saber si el triangulo es equilátero con un solo if así:
if (( L1 == L2 ) && ( L2 == L3)) {
stringItem.setText("El triangulo es equilátero");
}
Haciendo una analogía con la tabla de verdad, el operador 1 es (L1 == L2), el
operador AND es && y el operador 2 es (L2 == L3) así que, podríamos decir con
el if que “Si L1 es igual que L2 y L2 igual que L3 entonces el triangulo es
equilátero”.
El operador AND funciona con los operadores que sean, siempre recordando
que para que la expresión sea verdadera a fuerzas cada operando tiene que ser
verdadero.
Operador OR ( O )
Su tabla de verdad nos muestra cuando dos variables unidas por un OR son
verdaderas o falsas:
Con este operador basta con que un operador sea verdadero para que la
expresión total sea verdadera.
Por ejemplo para saber si el triangulo es isósceles, se tienen tres opciones que
podemos agrupar con el operador AND.
if (( L1 == L2 ) && ( L3 != L1)) {
}
if (( L1 == L3 ) && ( L2 != L1)) {
if (( L2 == L3 ) && ( L1 != L2)) {
}
Ahora bien las tres opciones se pueden agrupar con un OR, porque basta con
que una de las opciones sea verdadera para que el triangulo sea isósceles, el
código final para saber si el triangulo es isósceles queda con un solo if así:
if ((( L1 == L2 ) && ( L3 != L1)) || (( L1 == L3 )
&& ( L2 != L1)) || (( L2 == L3 ) && ( L1 != L2))) {
CONDICIONES ANIDADAS
• Los estatutos if implementan decisiones que implican una o dos alternativas, un
estatuto if es anidada cuando la sentencia de la rama verdadera o la rama falsa es a su
vez una sentencia if.
• Un estatuto if anidada se puede utilizar para implementar decisiones con varias
alternativas o multi-alternativas
Sintaxis:
if (condición1)
estatuto1
else
if (condición2)
estatuto2
•
•
•
else
if (condiciónn)
estatuton
else
estatutoe
if (condición 1)
if (condición 2)
estatuto;
else // este else pertenece al if de la condición 2, pues se
if (condición 1)
{
if (condición 2)
estatuto;
}
else // con el uso de llaves cerramos el if anidado y el else
estatuto; // pertenece al primer if
Ejemplo:
if (num == 0)
cout << " El número es cero";
else
if (num > 0)
cout << " El número es positivo";
else
cout << " El número es negativo";
Ejemplo I: Programa que lee 3 números enteros diferentes y los despliega de mayor a
menor.
#include <iostream.h>
int main()
if (a > b)
if ( b > c)
cout <<endl<< a << " " << b << " " << c <<endl;
else
if (c > a)
cout <<endl<< c<< " " << a << " " << b<< endl;
else
cout <<endl<< a << " " << c << " " << b <<endl;
if ( a > c) {
if ( b > a)
cout <<endl<< b<< " " << a << " " << c <<endl;
}
else
if ( b > c )
cout <<endl<< b << " " << c << " " << a <<endl;
else
if (c > b) {
if (b > a)
cout <<endl<< c << " " << b << " " << a <<endl;
}
return 0;
CICLOS ANIDADOS
Consiste en usar un ciclo dentro de otro (vamos a usar hasta dos anidamientos). Se puede
anidar de la siguiente forma:
1. Un mientras dentro de un mientras:
I=1
Mientras i <= N haga
J = 1
Mientras J <= N haga
Bloque de instrucciones
Fin mientras
Bloque de instrucciones
Fin mientras
Mientras y para.
Para y mientras.