Bueno pues vamos uno por uno...
Para empezar un tema importante: diferencia entre while() y do{}while().
Un while()
primero comprueba una condición y se pueden dar dos casos:
- true -> Entra en el bucle. Termina. Comprueba nuevamente la condición... Y así hasta que la condición sea falsa.
- false -> No entra en el bucle. Se lo salta.
Un do{}while()
primero entra en el bucle. Termina y es entonces cuando mira la condición:
- true -> Se repite el bucle. Termina y vuelve a comprobar hasta que sea falso.
- false -> No vuelve a repetir el bucle (pero recuerda que ya lo ha ejecutado una vez antes)
Resumido:
- while() -> Comprueba - Ejecuta - Comprueba - ... - Comprueba - Sale (PUEDE NO EJECUTARSE NINGUNA VEZ)
- do{}while() -> Ejecuta - Comprueba - Ejecuta - ... - Comprueba - Sale (SIEMPRE SE EJECUTA AL MENOS 1 VEZ)
El bucle while() se utiliza cuando ya conocemos el valor que vamos a utilizar para la condición antes de ejecutar el bucle. Y por otra parte el do{}while() se utiliza cuando no conoceremos el valor de la condición hasta después de ejecutar el bucle una vez.
9. Programa que captura un año válido y dice si es bisiesto o no. Para ser válido deberá cumplir con estar entre 1900 y 2019, de no ser así indique el error y vuélvalo a solicitar hasta que lo sea. Para saber si es bisiesto, éste deberá ser divisible por 4 pero no por 100 o divisible entre 400.
int main()
{
int año;
printf( "\n Introduzca un a%co: ", 164 );
scanf( "%d", &año );
if (año>=1900 && año <=2019)
if ( año % 4 == 0 && año % 100 != 0 || año % 400 == 0 )
do{
printf("ERROR, Dame otro año",164);
scanf ("%d",&año);
}while(año<1900&&año>2019);
printf( "\n ES BISIESTO" );
else
printf( "\n NO ES BISIESTO" );
}
En el 9 , no se como hacer que aparezca un error cuando se coloca un numero menor de 1900 y mayor a 2019.
Aquí lo que quieres hacer se conoce como filtro. Vas a pedir un valor concreto hasta que te lo pongan correctamente. Se puede hacer con ambos bucles aunque el más típico es un do{}while() de la siguiente manera:
DO
pido el dato
WHILE el dato no es valido
Pero se puede hacer con un while() de la siguiente manera:
pido el dato
WHILE el dato no es valido
pido el dato
FIN WHILE
Pero tú has mezclado ambas cosas ya que pides el año antes de empezar el bucle pero luego usas un do-while. Ahora viene el tema de mostrar un "algo" cuando el valor no es válido. Si estás usando un do-while, tienes que hacerlo de la siguiente manera:
DO
pido el dato
SI el dato no es valido
muestro ese "algo"
FIN SI
WHILE el dato no es valido
Como ves tienes que comprobar si el dato es válido en dos sitios. Una forma de mejorar el código es usar una variable booleana. En caso de usar C se puede usar la biblioteca <stdbool.h> (creo que era) o usar un int y darle valores 1 (true) y 0 (false).
Visto con un supuesto más concreto. Un filtro que te pide la edad y tiene que estar entre 18 y 65:
#include <stdio.h>
#include <stdbool.h>
#define EDAD_MINIMA 18
#define EDAD_MAXIMA 65
int main(){
int edad;
bool edad_valida;
do{
printf("Introduce una edad entre %d y %d: ", EDAD_MINIMA
, EDAD_MAXIMA
); edad_valida = (edad >= EDAD_MINIMA && edad <= EDAD_MINIMA);
if(!edad_valida){
printf("La edad introducida no es valida"); }
} while(!edad_valida);
printf("La primera edad valida introducida es: %d", edad
); }
Y si prefieres hacerlo con un while, te ahorras la doble comprobación (o con nuestra mejora: el uso de un bool) pero vas a tener que pedir el dato antes del bucle y al final de este. Con el mismo ejemplo de antes para que veas que son intercambiables:
#include <stdio.h>
#define EDAD_MINIMA 18
#define EDAD_MAXIMA 65
int main(){
int edad;
printf("Introduce una edad entre %d y %d: ", EDAD_MINIMA
, EDAD_MAXIMA
);
while(edad < EDAD_MINIMA || edad > EDAD_MAXIMA){
printf("La edad introducida no es valida"); printf("Introduce una edad entre %d y %d: ", EDAD_MINIMA
, EDAD_MAXIMA
); }
printf("La primera edad valida introducida es: %d", edad
); }
Es mejor que uses la primera siempre porque aunque la segunda parece más simple repites código necesariamente y ahora solo pides un número pero puede ser que pidas muchos datos y tengas que repetir muchas líneas.
Con esto ya deberías poder hacer el 9 pero si tienes alguna duda, siempre puedes preguntarla. Y que no te de miedo cargarte lo que tienes y empezar de 0. A veces es más fácil porque así no intentas reutilizar lo que ya tienes. Sobre todo en casos como estos que está hecho un lío.
Ahora vamos primero al 11 ya que tienes parte hecha. Para no volver a repetir todo sobre los bucles, te doy una idea para hacerlo. Esta vez te lo pondré en pseudocódigo así que tendrás que entenderlo para luego escribirlo tú en el lenguaje que uses. Puedes ir filtrando cada dato con lo que haces más bucles do-while pero con condiciones más sencillas o pedir todo y luego ya validar. Me parece más correcto lo primero porque si te ponen el día 32, para qué vas a pedir el mes si ya sabes que no va a estar bien? Pero como pone que pide una fecha pues lo haré para pedirlo todo junto y luego validar. (Doy por hecho que tampoco has visto arrays todavía, si es cierto no es para asustarte, no son para tanto y hasta te pueden quitar trabajo pero lo haré sin usarlos).
PD: Cuando no sepas dónde poner el do-while para que un programa se repita. Hazlo primero sin que se repita: pide datos y valida y cuando ya lo tengas mete todo el programa dentro de un do{} y pon la condicion del while() y listo:
// SIN REPETIR EL PROGRAMA
dia = pedirDia()
mes = pedirMes()
año = pedirAño()
fechaValida = true // supones que la fecha es valida
// Para empezar comprueba el año, si se sale de los limites no hace falta seguir
SI año < AÑO_MINIMO or año > AÑO_MAXIMO ENTONCES
fechaValida = false
FIN SI
// Ahora tienes que ver si la fecha sigue siendo valida porque si ya no lo es, no tienes que hacer nada mas
SI fechaValida and (mes < MES_MINIMO or mes > MES_MINIMO) ENTONCES
fechaValida = false
FIN SI
// Ahora mas de lo mismo, si la fecha sigue siendo valida tendras que comprobar el dia:
SI fechaValida ENTONCES
limiteDia = 31 // suponemos como limite maximo 31
SI mes = 4 or mes = 6 or mes = 9 or mes = 11 ENTONCES
limiteDia = 30
SINO SI mes = 2 ENTONCES
limiteDia = 28 // el enunciado dice que febrero se considera siempre de 28 dias
FIN SI
fechaValida = (dia > 0 and dia <= limiteDia)
FIN SI
SI fechaValida ENTONCES
Mostrar "La fecha es valida"
SINO
Mostrar "La fecha no es valida"
FIN SI
Y ahora que ya lo tienes. Coges todo el código lo metes en un DO y le pones la condición:
HACER
// todo el programa...
// EXCEPTO las declaraciones de variables porque con declararlas una vez antes del bucle ya vale
// PERO tienes que recordar poner los valores por defecto al principio o al final de cada vuelta para que la siguiente vuelta funcione bien
MIENTRAS !fechaValida
El ejercicio 10 te lo explico por encima. Daré por hecho que ya sabes lo que es un número binario, cómo se pasa de binario a decimal y viceversa y esas cosas...
Lo primero sería hacer un filtro como ya has visto para que el número esté entre 1 (00000001) y 255 (11111111). Te lo explicaré sin la función pow() para que veas una forma mejor de hacerlo pero sencilla también.
El 1 que más vale en binario de los ocho que componen nuestro número es 128 (no entraré en detalles, espero que estemos de acuerdo). Y de ahí, los siguientes unos van valiendo la mitad: 64, 32, 16, 8, 4, 2 y 1. Entonces puedes ir mirando si tu número es mayor o igual que x (llamemos así al 128, 64,...) y si lo es, se lo restas y muestras un 1, si no lo es, muestras un 0. Siempre al finalizar divides x a la mitad:
HACER
numero = pedirNumero()
MIENTRAS numero < 1 or numero > 255
factor = 128
MIENTRAS numero > 0 HACER
bit = 0
SI numero >= factor ENTONCES
numero = numero - factor
bit = 1
FIN SI
Mostrar bit
factor = factor / 2
FIN MIENTRAS
Con esto tendrás el número representado con 8 bits sencillo y bastante eficiente. Se puede mejorar obviamente pero si estás empezando es mejor que tengas códigos fáciles de entender que eficientes.
PD 2: Por lo que veo parece que te han dicho que te van a enseñar C++ pero lo que te están enseñando es una mezcla de C/C++ (muy común en muchos lugares, a mí también me lo hicieron). Pero que sepas que la mayoría de lo que usas es C.
PD 3: No utilices la biblioteca <conio.h>. Es una biblioteca que no es estándar por lo que puede dar problemas según donde se use y seguramente lo hagas por la función getch() para que no se cierre el programa.
- Como alternativa de C tienes getchar() de la biblioteca <stdio.h> que ya estás usando.
- Como alternativa de C++ tienes cin.get() de <iostream>. Con esta se hacen las entradas y salidas en C++.
PD 4: Haces bien poniendo nombres fáciles de identificar a las variables pero acostúmbrate a usar también constantes en vez de poner números sueltos. Con una constante, la puedes cambiar una vez y que el programa funcione de otra manera y si vas poniendo números sueltos tendrás que cambiarlos todos uno por uno... Un rollo vamos.
#define <NOMBRE CONSTANTE> <valor>
- Constantes al estilo C++:
const <tipo> <NOMBRE CONSTANTE> = <valor>