11. Ejercicio 1

11.1. ejemplo de solución

//  Ing. Germán Andrés Xander 2022.  //

#include<iostream>
using namespace std;
 
struct datos{
    int orden;
    char texto[10];
    struct datos *pprox;
};
 
void agregar(datos *&pt);
void agregar_final(datos *&pt);
void mostrar(datos *pt);
void eliminar_una(datos *&pt);
void eliminar_todas(datos *&pt);
 
int main() {
    char opcion;
    datos *lista=NULL;            //creo el puntero en main()
    do{
        cout<<"\t         Menu"<<endl
            <<"\t a para agregar instancias"<<endl
            <<"\t m para mostrar"<<endl
            <<"\t e para eliminar una instancia"<<endl
            <<"\t E para eliminar todas las instancias"<<endl
            <<"\t s salir"<<endl;
        cin>>opcion;
        switch(opcion){
            case 'a':
                agregar(lista);
                break;
            case 'm':
                mostrar(lista);
                break;
            case 'e':
                eliminar_una(lista);
                break;
            case 'E':
                eliminar_todas(lista);
                break;
        }
    }while(opcion!='s');
    return 0;
}
 
void agregar(datos *&pt){            //paso por referencia para poder modificar "a dónde apunta"
    int instancias;
    cout<<"ingrese cantidad de instancias a agregar"<<endl;
    cin>>instancias;
    cout<<endl;
    for (int i=0; i<instancias; i++){
        agregar_final(pt);
    }
}

void agregar_final(datos *&pt){            //paso por referencia para poder modificar "a dónde apunta"
    if(!pt){                    //la primer vez el puntero es NULL y evalua por true.
                                //"...the null pointer is implicitly converted into boolean false
                                //while non-null pointers are converted into true..."
        pt=new datos;            //para la primer instancia debo modificar "a dónde apunta" el puntero original (lista)
        cout<<"ingrese orden"<<endl;
        cin>>pt->orden;
        cout<<"ingrese texto"<<endl;
        cin>>pt->texto;
        pt->pprox=NULL;
    }else{                        // para las instancia posteriores debo trabajar sobre una copia del puntero
        datos *pt2=pt;            // para no perder la dirección de la 1er instancia
        while(pt2->pprox!=0){        //me posiciono en la última instancia
            pt2=pt2->pprox;
        }
        pt2->pprox=new datos;        //solicito una nueva instancia y asigno la dirección en el puntero al prox de la última
        cout<<"ingrese orden"<<endl;
        cin>>pt2->pprox->orden;
        cout<<"ingrese texto"<<endl;
        cin>>pt2->pprox->texto;
        pt2->pprox->pprox=NULL;
    }
    cout<<endl;
}

void mostrar(datos *pt){  //como no pasa por referencia no se alterar el original
    while(pt!=0){
        cout<<"orden: "<<pt->orden<<"\t texto: "<<pt->texto<<"\t dirección al próximo: "<<pt->pprox<<endl;
        pt=pt->pprox;
    }
    cout<<endl<<endl;
}
 
void eliminar_una(datos *&pt){
    datos *pt2=pt,*pt3=pt;
    if(!pt){
        cout<<"no hay instancias"<<endl;
    }else{
        while(pt2->pprox!=0){        //me posiciono en la última instancia
            pt3=pt2;
            pt2=pt2->pprox;
        }
        if(pt2==pt3){             //nunca entro al while anterior. es la última
            delete pt;            //libero la memoria original
            pt=NULL;              //para saber que ya no apunta a memoria mía
            cout<<"ya no quedan instancias"<<endl<<endl;
        }else{
            delete pt2;
            pt3->pprox=NULL;
        }
    }
}
 
void eliminar_todas(datos *&pt){
    while(pt){
        eliminar_una(pt);
    }
}