domingo, 27 de noviembre de 2011

Paso de Estructuras a Funciones en C++

Para pasar datos tipo struct a funciones en C++ es posible hacerlo de dos diferentes maneras:

1) Invocando la función con el nombre del tipo creado como struct. La función invocada recibe la dirección de la estructura y usa un alias para referirse a ella.

2) Invocando la función con el nombre del tipo creado como struct. La función invocada recibe como parámetro un dato del tipo creado como struct.

Pasar estructuras a funciones es muy parecido a pasar un arreglo.

En el siguiente ejemplo se usan los dos casos mencionados.

 #include <iostream>
 using namespace::std;

 struct Datos
 {
 // Estos datos no se pueden 
 // inicializar
 int anio;
 int mes;
 int dia;
 };

 // Prototipos de funcion
 void Recibe( Datos &s);
 void Imprime1( Datos &t);
 void Imprime2( Datos Nacimiento);

 /////////////////////////////////////////////////////////////
 // MAIN
 /////////////////////////////////////////////////////////////

 int main()
 {      // Abre main
 // Declaracion de Elisa como tipo Datos
 Datos Elisa;

 // Se reciben los datos de Elisa mediante la funcion Recibe
 Recibe(Elisa);

 // Se imprimen los datos de Elisa desde la funcion Imprime1
 cout <<"\nLa fecha de nacimiento de Elisa desde Imprime1: "<<endl;
 Imprime1(Elisa);
 // Se imprimen los datos de Elisa desde la funcion Imprime2
 cout <<"\nLa fecha de nacimiento de Elisa desde Imprime2:" <<endl;
 Imprime2(Elisa);
 // Se imprimen los datos de Elisa desde main 
 cout <<"\nLa fecha de nacimiento de Elisa desde main." <<endl;
 cout <<Elisa.dia<<"/" <<Elisa.mes<< "/" << Elisa.anio << endl << endl; 

 return 0;
 }      // Cierra main

 /////////////////////////////////////////////////////////////////
 // RECIBE
 ////////////////////////////////////////////////////////////////

 void Recibe( Datos &s)
 {      // Abre funcion Recibe
 cout << "\nIntroduzca el anio de nacimiento: " <<endl;
 cin >> s.anio;
 cout << "\nIntroduzca el mes de nacimiento: " <<endl;
 cin >> s.mes;
 cout <<"\nIntroduzca el dia de nacimiento: " <<endl; 
 cin >> s.dia;
 }      // Cierra funcion Recibe

 ////////////////////////////////////////////////////////////////
 // IMPRIME1
 ////////////////////////////////////////////////////////////////

 void Imprime1( Datos &t)

 {    // Abre Imprime
 cout <<t.dia <<"/"<<t.mes<<"/"<<t.anio<<endl;
 return;
 }    // Cierra Imprime

 ////////////////////////////////////////////////////////////////
 // IMPRIME2
 ////////////////////////////////////////////////////////////////

 void Imprime2( Datos Nacimiento)
 { // Abre 
 cout << Nacimiento.dia <<"/" <<Nacimiento.mes<<"/"<< Nacimiento.anio << endl;
 return;
 }


Una ejecución de este programa es la siguiente:

lunes, 21 de noviembre de 2011

Barajado de Cartas en Java

Este programa es parte del libro Java Cómo Programar, Séptima edición, de Deitel. Algunos de los problemas propuestos más complicados del capítulo 7 tienen que ver con la modificación de éste código. Por eso lo incluyo aquí como una referencia. Lo que hace es solamente barajar todas las cartas, como puede verse ejecutando este programa.

El siguiente código debe guardarse con el nombre PruebaPaqueteDeCartas.java

public class PruebaPaqueteDeCartas
 {     // Abre clase PruebaDeCartas

 public static void main(String args[])
 {     // Abre main
  PaqueteDeCartas miPaqueteDeCartas = new PaqueteDeCartas();
  miPaqueteDeCartas.barajar();
  
  ///////////////////////////////////
  // IMPRIME
  //////////////////////////////////

 System.out.println("\n");
 for ( int i = 0; i < 13; i++ )
 { // Abre for
 System.out.printf("%-20s%-20s%-20s%-20s\n", 
 miPaqueteDeCartas.repartirCarta(), miPaqueteDeCartas.repartirCarta(),
 miPaqueteDeCartas.repartirCarta(), miPaqueteDeCartas.repartirCarta());
 }  // Cierra for

 System.out.println("\n");
 }     // Cierra main
 }     // Cierra clase PruebaDeCartas

El siguiente código debe guardarse con el nombre Carta.java

public class Carta
 
 { // Abre clase Carta

 private String cara;
 private String palo;
 public Carta( String caraCarta, String paloCarta)
 {   // Abre constructor
 cara = caraCarta;
 palo = paloCarta;

 }   // Cierra constructor

 public String toString()
 {   // Abre metodo toString
 return cara + " de " + palo;
 }   // Cierra metodo toString
 } // Cierra clase Carta


El siguiente código debe guardarse con el nombre PaqueteDeCartas.java

import java.util.Random;

 public class PaqueteDeCartas

 {  // Abre clase PaqueteDeCartas
 private Carta paquete[];
 private int cartaActual;
 private final int NUMERO_DE_CARTAS = 52;
 private Random numerosAleatorios;

 /////////////////////////////////////////////////////////////////
 // CONSTRUCTOR
 /////////////////////////////////////////////////////////////////

 public PaqueteDeCartas()
 {   // ABre constructor PaqueteDeCartas

 String caras[] = { "AS", "DOS", "TRES", "CUATRO", "CINCO", "SEIS", "SIETE",
 "OCHO", "NUEVE", "DIEZ", "JOTO", "QUINA", "REY"};
 String palos[] = { "CORAZONES", "DIAMANTES", "TREBOLES", "ESPADAS"};

 paquete = new Carta[ NUMERO_DE_CARTAS ];
 cartaActual = 0;
 numerosAleatorios = new Random();

 for ( int cuenta = 0; cuenta < paquete.length; cuenta++ )
 paquete[ cuenta ] = new Carta( caras[cuenta % 13], palos[cuenta/13]); 
 }   // Cierra constructor PaqueteDeCartas


 /////////////////////////////////////////////////////////////////
 // METODO BARAJAR
 /////////////////////////////////////////////////////////////////

 public void barajar()
 {   // Abre metodo barajar
 cartaActual = 0;
 
 for ( int primera = 0; primera < paquete.length; primera++ )
 { // Abre for
 int segunda = numerosAleatorios.nextInt(NUMERO_DE_CARTAS);
 
 Carta temp = paquete[primera];

 paquete[primera] = paquete[segunda];
 paquete[segunda] = temp;
 
 }  // Cierra for
 }   // Cierra metodo barajar 

 public Carta repartirCarta()
 {  // Abre metodo repartirCarta
 if (cartaActual < paquete.length )
 return paquete[cartaActual++];
 else return null;
 }  // Cierra metodo repartirCarta
 }  // Cierra clase PaqueteDeCartas

domingo, 20 de noviembre de 2011

Determinar si un año es bisiesto en C++

Este programa es parte del libro Programación y Resolución de Problemas con C++ de Nell Dale y Cheep Weems, cuarta edición. El problemita es sencillo pero sirve, al menos para mí, como un primer uso del tipo de datos boolean. Para entender el algoritmo basta con recordar que un año bisiesto es aquel que tiene 366 dias en vez de 365. La regla, en el calendario gregoriano, es la siguiente:

Un año es bisiesto si es divisible entre 4, excepto el último de cada siglo (aquel divisible por 100), salvo que este último sea divisible por 400.

Con ésto es posible escribir la función Bisiesto que contiene este programa. Tal vez lo único extraño es la llamada de esta función mediante if. En realidad hay que recordar que un condicional en C++ se evalúa como true o como false, (véase el inciso 3 de esta entrada)así que, dado que la función llamada (Bisiesto) devuelve uno de esos dos valores, es perfectamente válido invocarla en el if.

////////////////////////////////////////////////////
 // Este programa recibe un anio e imprime si es   //
 // bisiesto o no                                  // 
 // /////////////////////////////////////////////////
 

 #include <iostream>
 using namespace::std;

 bool Bisiesto( int );

 int main()
 {                //  Abre main
 int anio;
 cout <<"\nIntroduzca un anio y sabra si es bisiesto:\n";
 cin >> anio;

 if ( Bisiesto( anio ) )
 // Nota: If solo evalua true o false
 cout << anio << " es un anio bisiesto." << endl;
 else // es decir, si es false
 cout << anio << " no es un anio bisiesto." << endl;
 
 return 0;
 }                // Cierra main

 ////////////////////////////////////////////////////
 // FUNCION BISIESTO
 ////////////////////////////////////////////////////
 
 bool Bisiesto( int a  )
 // Esta funcion regresa un valor booleano true
 // si el anio es bisiesto y regresa el valor 
 // booleano false si el anio no es bisiesto

 {     // Abre funcion Bisiesto

 if ( 0 != a%4 )
 return false;
 else if ( 0 != a % 100 )
 return true;
 else if ( 0 != a % 400 )
 return false;
 else 
 return true;
 }     // Cierra funcion Bisiesto
Aquí una ejecución del programa:

Introduzca un anio y sabra si es bisiesto:
2004
2004 es un anio bisiesto.



lunes, 14 de noviembre de 2011

Deitel_Java_7.21 (Lenguaje Logo en Java)


Saludo en Logo
7.21 (Gráficos de Tortuga) El lenguaje logo hizo famoso el concepto de los gráficos de tortuga. Imagine a una tortuga mecánica que camina por todo el cuarto, bajo el control de una aplicación en Java. La tortuga sostiene una pluma en una de dos posiciones, arriba o abajo. Mientras la pluma está abajo, la tortuga va trazando figuras a medida que se va moviendo, y mientras la pluma está arriba, la tortuga se mueve alrededor libremente sin trazar nada. En este problema usted simula la operación de la tortuga y creará un blog de dibujo computarizado.
Utilice un arreglo de 20 por 30 llamado piso que se inicialice con ceros. Lea los comandos de un arreglo que los contenga. Lleve el registro de la posición actual de la tortuga en todo momento, y si la pluma se encuentra arriba o abajo. Suponga que la tortuga siempre empieza en la posición (0,0) del piso con su pluma hacia arriba. El conjunto de comandos de la tortuga que su aplicación debe procesar se muestra a continuación.

1 Pluma arriba
2 Pluma abajo.
3 Gira a la derecha.
4 Gira a la izquierda.
5 Avanza.
6 Imprime el arreglo.
9 Centinela (Fin de datos)
_____________________________________________________________________________________
SOLUCIÓN:
Este programa también aparece resuelto en C++ en este blog. Esta versión en Java me ha resultado más fácil de escribir. Es posible añadir más comandos y hacer este código más interesante. Como consejo si lo que quiere es escribir este código, lo primero que debe hacerse es asegurarse que la tortuga gira correctamente hacia la derecha y hacia la izquierda. Para esto es necesario saber cual es la dirección de la tortuga, esto lo hace el método Dirección. He usado las letras k, l, j, h para referirme a "arriba", "derecha", "abajo" y "izquierda" respectivamente, porque esas son las teclas de desplazamiento del editor Vi. Una vez que la tortuga gira correctamente es necesario hacerla avanzar y retroceder en líneas horizontales, y después en verticales. Finalmente he agregado la opción imprimir comando para que el usuario sepa en todo momento qué se espera de él.

Este código debe guardarse con el nombre UsaLogo.java

public class UsaLogo
 {            // Abre clase Logo
 
 public static void main(String args[])
 {     // Abre main
 Logo miObjeto = new Logo();
 miObjeto.Administrador_Logo();
 }      // Cierra main
 }            // Cierra clase Logo


Este código debe guardarse con el nombre Logo.java

import java.util.Scanner;

 public class Logo
 {   // Abre clase Logo
 Scanner entrada = new Scanner(System.in);
 private int Direccion = 'l';
 private int Pluma = 1; // La pluma inicia hacia arriba
 private int ANCHO_TABLERO = 90;
 private int ALTO_TABLERO = 40;
 private int Tablero[][] = new int[ALTO_TABLERO + 1][ANCHO_TABLERO + 1];
 private int X = 1;  // La tortuga inicia en la parte superior
 private int Y = 1;  // izquierda
 

 public void Administrador_Logo()
 {       // Abre metodo Administrdor_Logo

 int comando;

 
 System.out.println("\nPor favor introduzca comando: ");
 comando = entrada.nextInt();

 while ( 0 != comando )
 {      // Abre while 
 switch (comando)
 {   // Abre switch
 case 1:
 System.out.println("\nLa pluma esta hacia arriba.");
 Pluma = 1;
 break;
 case 2:
 System.out.println("\nLa pluma esta hacia abajo.");
 Pluma = 2;
 break;

 case 3:
 System.out.println("\nSe gira a la derecha.");
 switch (Direccion)
 {  // Abre switch anidado
 case 'k':
 Direccion = 'l';
 break;
 case 'l':
 Direccion = 'j';
 break;
 case 'j':
 Direccion = 'h';
 break;
 case 'h':
 Direccion = 'k';
 break;
 default:
 System.out.println("\nDireccion Invalida");
 break; 
 }  // Cierra switch anidado
 break;

 case 4:
 System.out.println("\nSe gira a la izquierda");
 switch (Direccion)
 {     // Abre switch
 case 'k':
 Direccion = 'h';
 break;
 case 'h':
 Direccion = 'j';
 break;
 case 'j':
 Direccion = 'l';
 break;
 case 'l':
 Direccion = 'k';
 break;
 default:
 System.out.println("\nDireccion invalida.");
 break;
 }     // Cierra switch
 break;

 case 5:
 Avanza();
 break;
 case 6:
 Imprimir_Tablero();
 break;
 case 7:
 System.out.printf("\nLa direccion de la tortuga es: %c", Direccion);
 System.out.printf("\nLa posicion de la tortuga es X = %d, Y = %d\n", X, Y);
 break;
 case 8:
 System.out.println("\nLos comandos son:");
 Imprimir_Comandos();
 break;

 default:
 System.out.println("\nComando invalido.\n");
 break;
  
 }   // Cierra switch
 System.out.print("\nPor favor introduzca comando, 0 para terminar, ");
 System.out.print("8 para imprimir los comandos.\n");
 comando = entrada.nextInt();
 
 }      // Cierra while
 }       // Cierra metodo Administrador_Logo

 ////////////////////////////////////////////////
 // METODO AVANZA
 ///////////////////////////////////////////////
 
 public void Avanza()
 {        // Abre metodo Avanza
 int casillas_avanza;
 System.out.println("\nPor favor introduzca las posiciones que avanzara la tortuga: ");
 casillas_avanza = entrada.nextInt();
 switch (Direccion)
 {     // Abre switch
 case 'l':
 
 if ( X + casillas_avanza <= ANCHO_TABLERO)
 
 { // Abre if 
 if ( 1 != Pluma) // Si la pluma esta hacia abajo
 for ( int i = X; i <= X + casillas_avanza; i++ )
 Tablero[Y][i] = 1; 

 // El cambio en X se hace al final 
 // para no afectar a la variable que de hecho aparece
 // en el ciclo for anterior
 X += casillas_avanza;
 
 }  // Cierra if
 else
 {  // Abre else
 if ( 1 != Pluma )
 for ( int j = X; j <= ANCHO_TABLERO; j++ )
 Tablero[Y][j] = 1;
 X = ANCHO_TABLERO;
 // De nuevo, el cambio en X se hace al final, de lo contrario
 // Se alteraria la misma variable que aparece en el diclo for
 }  // Cierra else
 break;

 case 'h':
 if ( 1 <= X - casillas_avanza )
 {  // Abre if
 if ( 1 != Pluma )
 for ( int i = X; i >= X - casillas_avanza; i--)
 {  // Abre for
 Tablero[Y][i] = 1; 
 }  // Cierra for
 
 X -= casillas_avanza;
 }  // Cierra if 
 else  // es decir, si X - casillas_avanza < 1
 {    // Abre else
 if ( 1 != Pluma )
 for ( int i = X; i >= 1; i--)
 Tablero[Y][i] = 1;

 X = 1; 
 }    // Cierra else
 break;

 case 'j':
 if ( Y + casillas_avanza <= ALTO_TABLERO)
 
 { // Abre if 
 if ( 1 != Pluma) // Si la pluma esta hacia abajo
 for ( int i = Y; i <= Y + casillas_avanza; i++ )
 Tablero[i][X] = 1; 

 // El cambio en Y se hace al final 
 // para no afectar a la variable que de hecho aparece
 // en el ciclo for anterior
 Y += casillas_avanza;
 
 }  // Cierra if
 else
 {  // Abre else
 if ( 1 != Pluma )
 for ( int j = Y; j <= ALTO_TABLERO; j++ )
 Tablero[j][X] = 1;
 Y = ALTO_TABLERO;
 // De nuevo, el cambio en X se hace al final, de lo contrario
 // Se alteraria la misma variable que aparece en el diclo for
 }  // Cierra else
 break;
 
 case 'k':

 if ( 1 <= Y - casillas_avanza )
 {  // Abre if
 if ( 1 != Pluma )
 for ( int i = Y; i >= Y - casillas_avanza; i--)
 {  // Abre for
 Tablero[i][X] = 1; 
 }  // Cierra for
 
 Y -= casillas_avanza;
 }  // Cierra if 
 else  // es decir, si X - casillas_avanza < 1
 {    // Abre else
 if ( 1 != Pluma )
 for ( int i = Y; i >= 1; i--)
 Tablero[i][X] = 1;

 Y = 1; 
 }    // Cierra else
 break;

 default:
 System.out.println("\nDireccion equivocada.");
 break; 
 }    // Cierra switch  
 }        // Cierra metodo Avanza 

 ///////////////////////////////////////////////
 // IMPRIMIR_TABLERO 
 ///////////////////////////////////////////////

 public void Imprimir_Tablero()
 {    // Abre metodo Imprimir_Tablero

 System.out.printf("\nEl Tablero es de %d de ancho X %d de alto\n", ANCHO_TABLERO, ALTO_TABLERO);
 // Imprime contorno superior del tablero
 System.out.printf("|");
 for ( int n = 1; n <= ANCHO_TABLERO; n++ )
 System.out.printf("-");

 System.out.printf("|\n");
 // Imprime el tablero
 for ( int i = 1; i <= ALTO_TABLERO; i++ )
 {   // Abre for
 // Escribe contorno derecho
 System.out.printf("|");
 // Imprime renglon
 for ( int j = 1; j <= ANCHO_TABLERO; j++ )
 {  // Abre for anidado
 if ( 0 == Tablero[i][j])
 System.out.printf(" ");
 else
 System.out.printf("*");
 }      // Cierra for anidado
 System.out.printf("|%d\n", i);
 }  // Cierra for 

 // Imprime contorno inferior del tablero
 System.out.printf("|");
 for ( int m = 1; m <= ANCHO_TABLERO; m++ )
 System.out.printf("-");
 System.out.printf("|");
 
 
 }    // Cierra metodo Imprimir_Tablero

 ///////////////////////////////////////////////
 // METODO IMPRIMIR_COMANDOS
 ///////////////////////////////////////////////

 public void Imprimir_Comandos()
 {     // Abre metodo Imprimir_Comandos
 System.out.println("\n1 Pluma hacia arriba.");
 System.out.println("2 Pluma hacia abajo.");
 System.out.println("3 Gira a la derecha.");
 System.out.println("4 Gira a la izquierda.");
 System.out.println("5 Avanza.");
 System.out.println("6 Imprime Tablero.");
 System.out.println("7 Imprime Posicion y Direccion.");
 System.out.println("8 Imprime comandos.");
 }     // Cierra metodo Imprimir_Comandos

 
 }   // Cierra clase Logo
Related Posts Plugin for WordPress, Blogger...