12/3/10

Código Taller 1

// Stack v2.0.cpp: define el punto de entrada de la aplicación de consola.
//
/********************************************************
* Stack                                                                                                   *
* A set of routines to implement a simple integer                                       *
* stack.                                                                                                   *
* Procedures                                                                                           *
* stack_init -- initalize the stack.                                                               *
* stack_push -- put an item on the stack.                                                  *
* stack_pop -- remove an item from the stack.                                         * 
********************************************************/
//#include "stdafx.h"
#include <assert.h>
#include <cstdlib>
#include <iostream>
using namespace std;
const int STACK_SIZE = 100; // Maximum size of a stack
struct array
{
    double matriz;
    array *proximo;
    array *anterior;
};
// The stack itself
struct stack 
{  
       double count; // Number of items in the stack
       stack *siguiente;    //Punteros de navegacion
       stack *anterior;     //Puntero de navegacion
       array *posicion;     
       /*public:
              stack(){cout<<"\n\tCONSTRUYENDO...";};
              ~stack(){cout<<"\n\tDESTRUYENDO...";};*/
}; 
struct stack *primero;
struct stack *ultimo;


struct array *first;
struct array *last;


void ingreso(int numero, int pila,int guardar, int &x)
{
    array *nuevo = new array;
    stack *atras = new stack;
    int a=0;
    
    if(nuevo==NULL)
    {
        cout<<"Error\n";
    }
else
{
(*nuevo).matriz=numero;
nuevo->proximo=NULL;


   if(first==NULL)
   {
    cout<<"Primer elemento\n";
    first=nuevo;
    first->anterior=NULL;
    last=nuevo;
    last->anterior=first;
   }
   else
   {
//if(pila<2)
//{
last->proximo=nuevo;
nuevo->anterior=last;
last=nuevo;
last->proximo=NULL;
//}
//else
//{


//}
   }
}
//while (x<=guardar)
//{
        if(x==guardar)
   {
            atras->posicion=last;
            atras->siguiente=NULL;
//atras->anterior=NULL;
            
            if(pila<2)
            {     
if(primero==NULL)
{
cout<<"Nuevo registro...\n";
primero=atras;
ultimo=atras;
}
/*else
{
ultimo->siguiente=atras;
atras->anterior=ultimo;
ultimo=atras;
ultimo->siguiente=NULL;
}*/
            }
            else
            {
                ultimo->siguiente=atras;
                atras->anterior=ultimo;
                ultimo=atras;
                ultimo->siguiente=NULL;
            }
        }
        //else
        //{
            //x++;
        //}
    //}
}
/********************************************************
* stack_init -- initialize the stack. *
* *
* Parameters *
* the_stack -- stack to initalize *
********************************************************/
inline void stack_init(struct stack *the_stack)
{
    the_stack->count = 0; // Zero the stack
}
/********************************************************
* stack_push -- push an item on the stack. *
* *
* Warning: We do not check for overflow. *
* *
* Parameters *
* the_stack -- stack to use for storing the item *
* item -- item to put in the stack *
********************************************************/
inline void stack_push(struct stack *the_stack,const int item, int des, int guardar, int k)
{    
    assert(((*the_stack).count >= 0)&&((*the_stack).count<sizeof(first->matriz)/sizeof(first->matriz)));
    ingreso(item,des,guardar,k); 
}
/********************************************************
* stack_pop -- get an item off the stack. *
* *
* Warning: We do not check for stack underflow. *
* *
* Parameters *
* the_stack -- stack to get the item from *
* *
* Returns *
* The top item from the stack. *
********************************************************/
void stack_pop(struct stack *the_stack, int ciclos, int &pila)
{
    //int dato;
    char desicion;
    assert(((*the_stack).count >= 0)&&((*the_stack).count<sizeof(first->matriz)/sizeof(first->matriz)));// Then we return the top value


    struct array *auxiliar = new array;
    struct array *nuevo = new array;
    struct stack *nuevo2= new stack;
    int i=0; 
    
    if(auxiliar==NULL||nuevo==NULL||nuevo2==NULL)
    {
        cout<<"error...\n";
    }
    
nuevo2=primero;
//nuevo2->siguiente=NULL;
do
{
//nuevo=nuevo2->posicion;
nuevo2=nuevo2->siguiente;
pila--;
}
while(nuevo!=NULL&&pila>0);


auxiliar=nuevo2->posicion;
    cout<<"Expulsando...\n";
    system("pause");
    system("cls");
    
    do
    {
        cout<<"\aDesea visualizar los datos? S/N\t";
        cin>>desicion;
        if(desicion=='s'||desicion=='S')
        {
            cout<<"Expect a "<<auxiliar->matriz<<"-> "<<auxiliar->matriz<<"\n";
auxiliar=auxiliar->anterior;
            i++;
            ciclos--;
        }
        else
        {
            auxiliar=auxiliar->anterior;
            i++;
            ciclos--;
        }
    }
    while(auxiliar!=NULL&&ciclos!=0);
    if(i==0)
    {
        cout<<"La lista esta vacia\n";
    }
    //return (salida);

}
int definir_dato()
{
    int datos;
    
    cout<<"Determine el numero total de datos que desea ingresar\n";
    cin>>datos;
    return datos;
}
int* definir_datos1(int ciclos)
{      
    int* datos1=new int[100];


    for(int j=0;j<ciclos;j++)
    {
        cout<<"Ingrese el "<< j+1<<" dato\n";
        cin>>datos1[j];
    }
    return datos1;
}
// A short routine to test the stack


int main(int argc, char *argv[])
{
    int numeros,pilas=1, posicion;
    int n_datos, *datos_1;
    char desicion,pila;


    struct stack a_stack; // Stack we want to use
    struct stack *point= &a_stack;    
    stack_init(point);
    
    n_datos=definir_dato();
    datos_1=definir_datos1(n_datos);
    
    //point->stack_init(point);
    // Push three value on the stack
   
    for(int k=0;k<n_datos;k++)
    {
        numeros=datos_1[k];
        stack_push(point, numeros,pilas,n_datos,k);
           
        //point->stack_push(point, numeros); 
    }
    system("cls");
    /*stack_push(a_stack, 2);
    stack_push(a_stack, 3);*/
    // Pop the item from the stack 
    
    do
    {   
        b:
        cout<<"Que desea hacer?\n";
        cout<<"A-Expulsar una pila\n";
        cout<<"B-Crear otra pila\n";
        cout<<"C-Salir\n";
        cin>>pila;
        
        if(pila=='A')
        {
            if(pilas>1)
            {
                cout<<"Cual pila desea ver\n";
                cout<<"Seleccione un numero del 1 al "<<pilas<<"\n";
                cin>>posicion;
                stack_pop(point,n_datos,posicion);
            }
            else
            {
                stack_pop(point,n_datos,pilas);
                system("pause");
                system("cls");
            }
        }
        else if(pila=='B')
        {
            pilas++;
            n_datos=definir_dato();
            datos_1=definir_datos1(n_datos);
            for( int j=0;j<n_datos;j++)
            {
numeros=datos_1[j];
                stack_push(point, numeros,pilas,n_datos,j);
            }
        }
        else if(pila=='C')
        {
            return 0;
        }
        else
        {
            cout<<"Seleccione una opcion\n";
            system("pause");
            system("cls");
            goto b;
        }
    }
    while(pila=='A'||pila=='B');
    
    //point->stack_pop(point,datos);    
    /*cout << "Expect a 2 ->" << stack_pop(a_stack) << "\n";
    cout << "Expect a 1 ->" << stack_pop(a_stack) << "\n";*/
    system("pause");
    return (0);   
}

SEGUNDA PARTE TALLER 1: Taller teótico asignación de memoria

1.  1. ¿En que zonas de la organización del computador se almacenan las variables globales y las locales?. (Pista: recuerde el comienzo de la clase, cuando se explicó de donde salían los punteros, el segmento de código, el segmento de pila, el segmento de datos, el segmento extra...)

Durante la ejecución de un programa, se utilizan varias zonas de memoria bien diferenciadas por su cantidad según el tipo de dato que almacenen, para guardar los parámetros, las variables locales, globales, el código, etc. Son la pila de llamadas (call stack), que puede variar de tamaño durante la ejecución porque guardan objetos que son conocidos en runtime; el área de datos dinámicos, también conocida como el montón local (“local heap”), el área de datos estáticos y el área de código. Cuando se realiza un programa compilado compuesto de varias funciones (o métodos, si estamos utilizando un lenguaje orientado a objetos), los compiladores traducen cada función y su contenido a código máquina dependiente de la plataforma. Cuando se inicia la ejecución de dicho programa, el sistema operativo carga el código ejecutable en una zona de memoria que esté libre, y además, reserva al menos dos espacios más de memoria para que el programa pueda ejecutarse, y almacenar allí los datos que necesite: son el stack y el heap. Para el caso de las variables globales, se reserva además una tercera zona llamada zona de datos ó área de datos, las cuales permanecen constantes en tamaño a lo largo de la vida del programa, precisamente porque aquí se guardan variables y constantes cuyo tamaño es conocido en tiempo de compilación. En el caso del montón, puede ocurrir que en tiempo de ejecución el proceso demande más memoria para datos persistentes, espacio que más adelante puede ser liberado de nuevo. Tanto en el caso de pila como en el del heap, el tamaño de estas zonas puede aumentar y disminuir, y consecuentemente, la memoria total demandada al Sistema por el proceso en ejecución. En ésta organización en subzonas no necesariamente continuamente (puede que lo sean), que constan de características particulares y distintas en función del tipo de dato y cómo son manejados por el programa. La subzona que le corresponde a un dato concreto depende de que el dato sea conocido en tiempo de compilación o en runtime y de que el dato sea estático o se destruya cuando el programa sale del bloque en que fue definido (automático).
Supongamos que vamos a ejecutar un programa, y en un momento dado sólo está cargado el sistema operativo en la memoria principal.

Cuando le pedimos al sistema operativo que ejecute el programa, se carga el código ejecutable en una zona libre de la memoria, y el sistema operativo, además, reserva:
·         Una zona de datos para las variables globales y las constantes. Como en runtime se conocen perfectamente las variables globales y las constantes, se reserva el espacio necesario. Además, aquellas variables globales que sean inicializadas a un valor concreto y también las constantes, se les puede dar valor cuando se reserva la zona de datos.
·         Una zona para las llamadas (stack) que almacenará los parámetros de las funciones, las variables locales y los valores de retorno de las funciones (o métodos).
·         Una zona para la gestión dinámica de memoria (el heap). Es decir, aquella memoria que se solicita durante la ejecución del programa.

En resumidas cuentas, las globales se almacenan en el espacio reservado para el programa,
mientras que las locales en el espacio reservado para la función en la
que está contenida.
2.    2. En C++, ¿donde se almacena la memoria que se asigna dinámicamente?

Se asigna en un “Montón Local” (“Local heap”), el cual es un área fija de memoria, asignada en runtime por las rutinas de inicio antes de que comience la ejecución de main. Por ejemplo, cuando pedimos al programa que asigne memoria mediante malloc, o cuando creamos un nuevo objeto con el operador new. Las asignaciones de memoria del montón son generalmente más lentas que las de pila. Además los objetos situados en esta área tienden a ser persistentes; se mantienen hasta que el programador decide su destrucción, con la liberación consiguiente de la memoria previamente asignada; por ejemplo con una llamada al destructor de una clase, la función free o la palabra delete.
La zona de la memoria principal del computador donde se reservan espacios para asignarlos a variables dinámicas se denomina heap o montón. Cuando el sistema operativo carga un programa para ejecutarlo y lo convierte en proceso, le asigna cuatro partes lógicas en memoria principal: instrucciones, datos (estáticos), pila y una zona libre. Esta zona libre (heap) es la que va a contener los datos dinámicos. En cada instante de la ejecución del programa, el heap tendrá partes asignadas a datos dinámicos y partes libres disponibles para asignación de memoria, como puede observarse en la figura 2.1. El mecanismo de asignación-liberación de memoria durante la ejecución del programa hace que esta zona esté usualmente fragmentada (ver figura 2.1), siendo posible que se agote su capacidad si no se liberan las partes utilizadas ya inservibles. (La pila también varía su tamaño dinámicamente, pero la gestiona el sistema operativo, no el programador.)
3.    3. ¿Qué es el desbordamiento de memoria?

         Es un error de software que se produce cuando se copia una cantidad más grande de datos sobre un área más pequeña sin interrumpir la operación sobreescribiendo otras zonas de datos no previstas. Esto puede suponer la posibilidad de alterar el flujo del programa pudiendo hacer que este realice operaciones imprevistas.

4.   4.  ¿Qué retorna el operador NEW cuando se desea asignar espacio en memoria y no hay disponible?

Si  al asignar memoria para un objeto se produce un error por falta de memoria, new devuelve un puntero nulo (NULL). Para verificar si este suceso ocurre, será necesario añadir código similar al siguiente:
int *pi = new int[NMAX];

if( pi==0)
{
            cerr << ”Insuficiente memoria” << endl;
            return -1;
}
Otra manera de verificar este suceso es escribir una función que manipule de forma personalizada el suceso y registrar tal función invocando a la función predefinida_set_new_handler.  

BIBLIOGRAFÍA
 Del primer punto:
Del segundo punto:
Del tercer punto:
Del cuarto punto:
CEBALLOS, Francisco Javier.
Programación orientada a objetos con c++. Segunda edición.

8/3/10

Taller 1: Primera Parte: Apropiandose del paradigma de los Punteros.

/********************************************************
* Stack *
* A set of routines to implement a simple integer *
* stack. *
* Procedures *
* stack_init -- initalize the stack. *
* stack_push -- put an item on the stack. *
* stack_pop -- remove an item from the stack. *
********************************************************/
#include <assert.h>
#include <cstdlib>
#include <iostream>
using namespace std;
const int STACK_SIZE = 100; // Maximum size of a stack
/*struct arreglo
{
    double dato;
    arreglo *next;
};
struct arreglo lista;
struct arreglo *array=&lista;*/
// The stack itself
struct stack {
      // protected:
                 int count; // Number of items in the stack
                /* struct arreglo
                {
                    double dato;
                    arreglo *next;
                };
                struct arreglo lista;*/
                 double data[STACK_SIZE]; // The items themselves
       public:
              stack(){cout<<"\n\tCONSTRUYENDO...";};
              ~stack(){cout<<"\n\tDESTRUYENDO...";};
};

/********************************************************
* stack_init -- initialize the stack. *
* *
* Parameters *
* the_stack -- stack to initalize *
********************************************************/
inline void stack_init(struct stack *the_stack)
{
       (*the_stack).count = 0; // Zero the stack
}
/********************************************************
* stack_push -- push an item on the stack. *
* *
* Warning: We do not check for overflow. *
* *
* Parameters *
* the_stack -- stack to use for storing the item *
* item -- item to put in the stack *
********************************************************/
inline void stack_push(struct stack *the_stack,const int item,int posicion)
{
       assert(((*the_stack).count >= 0)&&((*the_stack).count<sizeof((*the_stack).data)/sizeof((*the_stack).data[0])));
       (*the_stack).count=posicion;
       (*the_stack).data[(*the_stack).count] = item;
}
/********************************************************
* stack_pop -- get an item off the stack. *
* *
* Warning: We do not check for stack underflow. *
* *
* Parameters *
* the_stack -- stack to get the item from *
* *
* Returns *
* The top item from the stack. *
********************************************************/
inline double stack_pop(struct stack *the_stack, int posicion)
{
       assert(((*the_stack).count >= 0)&&((*the_stack).count <sizeof((*the_stack).data)/sizeof((*the_stack).data[0])));// Then we return the top value
        (*the_stack).count=posicion;
        return ((*the_stack).data[(*the_stack).count]);
}
// A short routine to test the stack

int main(int argc, char *argv[])
{
    int datos, numeros;
    int datos1[100];
    char desicion;

    cout<<"Determine el numero total de datos que desea ingresar\n";
    cin>>datos;
  
    for(int j=0;j<datos;j++)
    {
        cout<<"Ingrese el "<< j+1<<" dato\n";
        cin>>datos1[j];
    }
    struct stack a_stack; // Stack we want to use
    struct stack *point= &a_stack;  
    stack_init(point);
    // Push three value on the stack
 
    for(int k=0;k<datos;k++)
    {
        numeros=datos1[k];
        stack_push(point, numeros,k);     
    }
    system("cls");
    /*stack_push(a_stack, 2);
    stack_push(a_stack, 3);*/
    // Pop the item from the stack
    for(int h=(datos-1);h>=0;h--)
    {
        cout<<"\aDesea visualizar los datos? S/N\t";
        cin>>desicion;
        if((desicion=='S')||(desicion=='s'))
        {
           cout << "Expect a "<<datos1[h]<<" ->" << stack_pop(point,h) << "\n";  
        }
    }

    /*cout << "Expect a 2 ->" << stack_pop(a_stack) << "\n";
    cout << "Expect a 1 ->" << stack_pop(a_stack) << "\n";*/
    system("pause");
    return (0);
  
}

Tarea apuntadores

#include <iostream>
using namespace std;


int funcion1(int variable_local){
    variable_local=5;
    return variable_local;
int a=funcion1(variable_local);
cout<<"Variable local = "<<variable_local<<endl;
    cout<<"a= "<<a<<endl;
}
char funcion2(int *p)
{
    if (*p==5)
    {
        p = new int[15];
    }
    while (*p)
    {
 p=0;
 p++;
    }
}
int main ()
{
    int *variable_local;
    variable_local = new int;
    char*x;
    int*y;
    y=new int [15];
    char nombre_array[20];
    x=nombre_array;
int b=1;
    while (x)
    {
        cout<<b++;
        *x++;
        cout<<"*x="<<*x<<endl;
    }
    *variable_local=5;
funcion1(*variable_local);
funcion2(variable_local);
system ("pause");
return 0;
}