Curso completo de programación con lenguaje C

gonya707

#90 normalmente el compilador te dice donde y en que lineas tienes los errores, de todos modos ya te los digo yo: te faltan los puntos y comas despues de cada linea. Todas las acciones tienen que terminar con un ;

1 respuesta
angelrcd

#91 Gracias por contestar tan rapido pero creo que no es eso, ya he puesto los puntos y coma que me faltaban y me sigue saltando el mismo error. Y a mi el compilador no me señala nada :S
Ahora esta asi:

spoiler
1 respuesta
gonya707

#92 pasan varias cosas:

-la funcion para imprimir por pantalla es fprintf, no fprint
-dentro de los printf se usa %f para imprimir los float, no &f, lo has puesto bien la primera pero no las siguientes. Ten cuidado con esas cosas.

1 respuesta
Maaarc

#93 Si te fijas en la Linea 6 y en la Linea 9 también lo tiene diferente :/

1 respuesta
gonya707

#94 es verdad xD. Bueno pues eso.

angelrcd

Por fin lo he podido compilar xD, ahora cuando lo ejecuto desde la consola todo va bien, puedo añadir los 2 numeros, pero cuando ya tienen que aparecer los numeros sumados y tal, me aparece todo junto sin saltos de linea (aunque para eso ya se que tengo que utilizar la "n" o no se que, en un momento lo miro xD), lo malo es que todos los resultados me dan 0, ponga los numeros que ponga. He cambiado un poco como lo he escrito:

spoiler
1 respuesta
gonya707

#96 te dan 0 porque en l;os fprintf has puesto &n3 etc, en los print no hay que poner el &, es solo para fscanf.

1 respuesta
angelrcd

#97 Muchas gracias! era eso, cuando averigue como poner los saltos de linea lo pongo aqui ya terminado, gran trabajo por cierto :)

1 respuesta
gonya707

#98 dentro de las cadenas de texto (lo que esta rodeado por comillas dobles "") introduce un\n cada vez que quieras meter un salto de linea

angelrcd

Terminado, con acentos y todo:

Leccion 2, ejercicio 1 y 2

PREGUNTA: ¿Se pueden poner las letras con tilde junto con el resto de la frase sin tener que cambiar de linea?

Daredevil
printf("%cCu%cl es el precio por unidad?\n", 168, 160);

¿Cuál es el precio por unidad?

Así lo harías ;)

gonya707

5 - Acciones repetitivas: bucles

En esta lección veremos otro de los bloques más emblemáticos en cualquier lenguaje de programación, los bucles. En muchas ocasiones en programas que ya hemos hecho se repiten acciones una y otra vez cambiando un pequeño parámetro cada vez. Un bucle nos puede ayudar a condensar una serie de lineas de código que se repiten de una manera resumida y más eficiente. Con este capítulo se terminará el bloque más elemental de la programacián, no teneis ni idea de la cantidad de cosas que pueden hacerse sabiendo estas pocas cosas, pero empezareis a verlo cuando veais la infame cantidad de deberes que voy a dejar :D

Operadores de asignación

Y como no, antes de ponernos en el tema necesitamos conocer otros de los operadores del lenguaje. Hasta ahora conociamos los aritméticos (+ - * / %), lógicos (== ! != > && etc) y ahora es el turno de los operadores de asignación.

A estas alturas todos sabemos lo que es una asignación. (Lo sabemos no?). Una asignación se produce siempre que usamos el símbolo =, asignando el valor de la derecha hacia la izquierda, como por ejemplo un valor a una variable.

int num;
num = 16;

el símbolo = es un operador de asignación, y hasta ahora ya lo habíamos usado muchas veces, pero existen más. Supongamos que a continuación de declarar esa variable num y darle el valor 16 el programa continúa así:

// El operador += acumula y asigna, es decir, sería lo mismo que escribir num = num + 12;
num += 12;

// El operador -= resta y asigna, es decir, sería lo mismo que escribir num = num - 4;
num -= 4;

del mismo modo, también existen los operadores *= y /= (multiplica y asigna y divide y asigna).

Otro tipo muy especial dentro de esta familia de operadores son ++ y --, incrementando en el primer caso la variable una unidad y decrementando en el segundo.

// Esto equivale a escribir num = num + 1;
num++;

De estos operadores toma C++ su nombre, ya que C++ es C y un poquito más ;)

bucles while

Sabido todo lo anterior entramos en materia. Un bucle nos va a servir, como ya he dicho para realizar repetitivamente una acción, y el más básico de todos es el bucle while.

While en inglés es "mientras", a while se le especifica una condición y si se cumple, se entra al bloque while

int indice = 0; 

while (indice <= 9){
	fprintf(stdout, "\n%d", indice);
	indice++;
}

En este ejemplo se crea una variable 'indice' con valor 0, e inmediatamente después se encuentra un bucle while. Un while es a fin de cuentas lo mismo que un if, con la salvedad de que cuando termina el bloque, se vuelve al principio y se vuelve a comprobar la condición. La ejecución en este punto sería así:

  • es 0 <= 9? true, por tanto entra al bucle e imprime 'indice'. Indice se incrementa una unidad

  • es 1 <= 9? true, por tanto entra al bucle e imprime 'indice'. Indice se incrementa una unidad

  • es 2 <= 9? true, por tanto entra al bucle e imprime 'indice'. Indice se incrementa una unidad
    ...

  • es 10 <= 9? false. No se entra al bucle y sigue el programa

Este mismo resultado podríamos haberto obtenido escribiendo 10 sentencias fprintf, pero al ser acciones repetitivas, un bucle está pensado específicamente para esta ocasión.

Recordad que cuando se vuelve a empezar el bucle while, se va a volver a comprobar la condicion, por lo tanto es obligatorio cambiar la condición dentro del bucle. Es este caso se incrementa 'indice' y el número que se compara es distinto cada vez. Si se nos olvidase cambiar indice en cada iteración del bucle, correríamos el riesgo de entrar en un bucle infinito, y que nuestro programa implosionase. ;)

bucles do-while

Un bucle do-while es muy parecido a un while, como su propio nombre indica. La diferencia radica en que en un while puedes entrar o no desde el principio, y que el do-while se ejecutará al menos una vez. Su sintaxis es la siguiente:

do{

//cosas

}while(condicion booleana);

Notad que en el caso de los while no se terminaba la linea con punto y coma, mientras que con un do-while sí. Al terminar de realizarse las acciones dentro de las llaves del do se comprueba la condició booleana, y de ser cierta, se repite de nuevo .

Esta estructura do-while es perfecta para cosas como menús. Es común mostrar un menú al comienzo de un programa, se imprimen unas opciones y el usuario elige entre ellas. El menú va a verse al menos una vez, y una vez terminada la opción es muy probable que sea necesario mostrar de nuevo el menú. Todo esto se puede estructurar aproximadamente así.

do{
   //mostrar menu
   //escanear la opcion elegida
   //realizar una accion en funcion de la opcion elegida
   //decidir si se ha terminado
}while( !terminado );

Por supuesto el do-while tiene más aplicaciones típicas, pero ya las iréis descubriendo poco a poco.

bucles for

Probablemente los bucles más usados. Un bucle for se parece mucho al bucle while, pero en su propia declaración haces tres cosas:

1-asignas un valor a una variable
2-decides la condición de repetición del bucle
3-especificas como va a cambiar en cada iteración la variable de 1-

La sintaxis de un for es la siguiente:

int i;
for (i = 0; i < 10; i++){
    //cosas
}

Al entrar en el bucle, nada más empezar se ejecuta la primera instrucción i = 0. Esta instrucción ya no volverá a llamarse. A continuación se comprueba que i<10, y en función de que esta condición sea verdadera o falsa se entrará o no a hacer todas las instrucciones dentro del bucle. Una vez terminadas estas instrucciones se comprueba el tercer miembro del for, y se ejecuta, que en este caso es incrementar en una unidad i.

En la mayoría de ocasiones while y for son práacticamente intercambiables, teniendo en cuenta que en un while hay que cambiar la condición cada vez dentro del bucle, mientras que en el for se hace 'solo' (porque se lo hemos especificado en el tercer parámetro). De todos modos la regla de oro para saber cual es más adecuado para nuestro problema es esta:

deberes lección 5

Esta lección no ha sido 'tan' larga, pero el contenido en ella tiene un valor incalculable.

1-programa que pida un numero y de por concluido cuando el numero se encuentre entre dos números que se generen aleatoriamente. El programa deberá mostrar esos números en pantalla terminar unicamente cuando el valor sea correcto. Si el valor no es correcto deberá solicitar de nuevo otro número.

2-programa que dibuje lineas de asteriscos de una longitud especificada por teclado. Por ejemplo si se le pide tamaño 6, deberá escribir por consola:

******

3-Realizar un programa que escriba en pantalla (en la medida de lo posible) el código ascii completo, de 256 posiciones.

4- implementar un código completamente funcional de un menú por consola, como se ha explicado en la parte del bucle do-while. De momento con un mockup es más que suficiente, poned tres o cuatro opciones que hagan cosas distintas y una más para salir del programa. Este "esqueleto" de programa nos será muy útil mós adelante.

5-Realizar un programa que calcule multiplicaciones partiendo de la base de que NM = N + N +... (M veces). Vamos resumiendo, que está prohibido usar el símbolo '' durante el programa.

6-Del mismo modo que el programa anterior, crear otro que resuelva potencias con multiplicaciones sucesivas y sin usar double pow(double, double);

7-Crear un programa que calcule el factorial de un número introducido por teclado. Por ejemplo 5! = 5 * 4 * 3 * 2 * 1 = 120

8-crear un programa que pida un número N y muestre los N primeros miembros de la serie de Fibonacci.

9-Hacer un programa que calcule el cuadrado de un número pero de una manera muy especial, por sumas de la serie impar. Según una propiedad matemática, N2 es igual ala suma de los N primeros números impares. Por ejemplo: 52 = 25 = 1 + 3 + 5 + 7 +9 (los 5 primeros números impares). Lo hizo un mago.

10- Crear un programa que dibuje rectángulos con asteriscos, preguntando por el tamaño de los lados y dibujando a continuación. Este ejercicio es como la expanxión del de la línea de asteriscos.

11-De una manera parecida al anterior, hacer un programa que dibuje rectángulos, pero esta vez huecos. Solo puede haber asteriscos en los bordes y no en el interior.

12-Y por último hacer un jueguecillo. Internamente se debe calcular de manera aleatoria un número entero entre 0 y 100, y el jugador debe de adivinarlo. Para ello el jugador deberá introducir un número sucesivas veces y el programa le advertirá si la respuesta es mayor, menor o bien ha acertado. Cuando acierte el programa deberá hacer un recuento de los turnos que se ha tardado en adivinar.

6
angelrcd

Estoy en la leccion 3, el primer problema, el del angulo con sus catetos etc... Para calcular el ángulo de un triángulo he intentado ahcer esto:

angulo1 = asin(cat1/hipotenusa);

; dando ese valor a la variable "angulo1", el cual en teoría debe darme el valor del angulo. Para el otro angulo he utilizado otra variable que consiste en: 180-90-angulo1... No se porque el ángulo1 me da mal, siempre me sale un número menor de 0, por lo tanto angulo2 me sale 89.xxxxx, alguien me dice que esta mal en como he puesto que debe ser la variable "angulo1"?
Aqui el codigo entero por si hace falta:

spoiler
1 respuesta
gonya707

#103 Yo diria que el código que pones está perfecto, probablemente el problema reside en que las funciones de math.h se calculan con radianes y no con grados, o bien que los resultados te los esta dando en el cuadrante equivocado, como hacen las calculadores.

1 respuesta
angelrcd

#104 He comprobado que el problema es que te da los angulos en radianes, dejo aquí el ejercicio terminado:

Lección 3 ejercicio 1
angelrcd
Lección 3 ejercicio 2

Sin ningún problema serio a la hora de escribir el código, aunque me he tenido que estrujar la cabeza hasta que se me ha ocurrido como desglosar el número matemáticamente xD
EDIT: He seguido el consejo de #109 y he utilizado ints en vez de doubles, asi queda mas bonito xD

2 respuestas
gonya707

#106 te he editado el mensaje porque salia hecho un churro el codigo, no te asustes por el aviso de moderacion xD

1 respuesta
angelrcd

#107 En serio, que has editado?, xk a veces me sale asi y no entiendo porque
creo que #105 tambien se ve mal por cierto xD

1 respuesta
gonya707

#108 No hago nada, simplemente le doy a editar y Acepto tal cual está. Una de dos, o es tu navegador que se comporta raro o bien has editado desde le dición rápida, porque si la usas pasan esas cosas.

Por cierto sobre tu ejercicio en #106, no tiene sentido que uses doubles, si todas las cuentas las tienes que hacer sobre numeros enteros, usa ints directamente, porque además apuesto que el resultado te esta saliendo en plan:

centenas 2.000000
decenas 5.000000
unidades 8.000000

angelrcd
Lección 3 ejercicio 3
B

Para la sexta lección hay que hacer una shell #1.

preguntitas

bueno, por aqui otro que se anima a retomar el c/c++

Dado que estoy bajo linux y no tengo ganas que usar joe/gcc como hace 15 años en la universidad. ¿que IDE recomendais? he estado googleando y estoy con el Geany, ¿algun inconveniente?

Voy a seguir con las lecciones. Gracias.

1 respuesta
Daredevil

#112 Lo más similar para Linux al IDE que ha recomendado gonya en el hilo es el Code::Blocks.

wiFlY

Comienzo con los ejercicios de la leccion 4 en los cuales estuve bastante atascado y despues no tuve tiempo para ponerme con ello.

Por partes, primero la identificacion de la variable que a la que se da entrada, y con identificacion me refiero a saber exactamente de que se trata (letra mayuscula o minuscula, numero de X cifras, otro caracter...). Estuve probando un dia y no consegui absolutamente nada, ahora miro el ejercicio resuelto de #89 pero hay algunas cosas que no me han quedado claras.

Tal y como esta resuelto da la impresion de que el conjunto de valores que se le pueden dar a una variable char esta ordenado de alguna manera, es decir que existe un orden establecido. Al menos creo que esta claro que el ordenador entiende el orden logico de los numeros y, viendo este ejercicio, tambien parece que las letras del abecedario (que abecedario?). Voy por buen camino? Hay algun orden para otros caracteres?

Ahora voy con otra duda. Si para realizar una comprobacion sobre una variable con el fin de conocer si es letra, numero, etc. hay que usar la variable char y esta solo puede almacenar un caracter, como puedo yo identificar si, por ejemplo, una entrada es un numero del 0 al 999? Es decir, como manejo entradas de mas de una letra/numero con la variable char?

operaciones logicas
1 respuesta
gonya707

#114 El orden es la tabla ascii y la respuesta a lo segundo es tan larga que son 2 lecciones que tocan en unas semanas xD

Si para realizar una comprobacion sobre una variable con el fin de conocer si es letra, numero, etc. hay que usar la variable char

Eso no se de donde lo has sacado xD char es para almacenar un caracter dentro, que casualmente es lo mismo que un entero de 8 bits, asi que si comparas por ejemplo 'ñ' == 164 es probable que te de true, pero la ñ deberias guardarla en un char y el número 164 en un int.

como puedo yo identificar si, por ejemplo, una entrada es un numero del 0 al 999.

Te estás liando. Cuando haces un fscanf y guardas el numero 999, no se estan guardando variables por cada cifra, solo una variable entera con el valor 999. Una vez con esta variable rellena puedes comprobar si esta bajo ese rango

if(n > 0 && n<1000){

}
1 respuesta
wiFlY

#115 Si para realizar una comprobacion sobre una variable con el fin de conocer si es letra, numero, etc. hay que usar la variable char

Segun lo que he visto yo entiendo que para diferenciar entre letra o numero (dejemos ahora de lado otros caracteres) necesito usar char ya que si uso int, float o double cualquier letra que entre sera asignada como un numero. Por ejemplo "ñ" lo registraria como 164 y el numero 164 tambien, con int, float o double.

Yo lo digo porque si quiero mejorar el programa que descomponia un numero de tres cifras en centenas, decenas y unidades no se como hacer para que el programa me de error si introduzco 3 letras o las que sean.

No se si me estoy explicando bien o no...

PD: porfavor mirame las operaciones logicas que he puesto en #114 porque aunque me dan igual que al otro usuario tengo alguna dudilla y las he descompuesto paso por paso. Sobre todo tengo duda con !0 el cual he puesto como verdadero.

PD2: estoy dale que te pego un poco y estoy empezando a pensar que los operadores logicos solo funcionan con numeros enteros... es correcto?

1 respuesta
gonya707

#116 Empiezo a entenderte, o sea que lo que quieres es que el programa pida el número y sepa distinguir centenas unidades y decenas analizando los numeros como caracteres. Se puede hacer efectivamente, simplemente pon tres fscanf %c sin limpiar el buffer entre ellos. Cuando llegues al primero metes el numero, por ejemplo 473, como esta esperando un caracter porque le has dicho que %c, va a coger solo el primero, 4, y al llegar al segundo fscanf al ver que el buffer tiene todavia dos valores, 7 y 3, va a coger el 7, y etc.

los operadores lógicos funcionan con cualquier tipo, no solo con enteros, efectivamente !0 es true. 0 es false y todo lo que no sea 0 es true, por lo tanto not false es true

1 respuesta
wiFlY

#117 Vale vale, voy viendo la luz poco a poco jejeje.

Lo de los operadores logicos y los numeros enteros viene de intentar hacer el ultimo ejercicio de la leccion 4 de una manera diferente a como la resolvio el otro usuario.

Mi intencion era usar para el mismo numero (el resultado de dividir el numero intruducido entre un primo) dos variables (un int y un double) de manera que el double registrase el numero con los posibles decimales y el int solo la parte entera. Despues compararia dichas variables (la int y la double) mediante un == y de serlo entonces el numero introducido deberia ser divisible por el primo.

Por ejemplo, introducir el numero 23, dividirlo por 2 y quedarme con dos variables:

una de tipo int = 11
una de tipo double = 11.5

Al no ser exactamente iguales el numero no es divisible por dos. El problema es que al hacerlo el resultado es siempre verdadero, como si fuesen iguales pese a no serlo.

1 respuesta
gonya707

#118 Tu método es correcto, para que puedas implementarlo sin problemas se me ocurre esto:

-recibes número 23 en un double N
-guardas el resultado de 23/2 en un double M
-compruebas si M-floor(M) es == 0 (es decir, si la parte decimal es igual a 0)
-analizas los resultados

1 respuesta
wiFlY

#119 Que gusto ver que lo que yo quiero hacer (analizar los decimales) es tan basico que ya se invento hace mucho un comando para ello ahahahah Imagino que no sera la tonica en otros menesteres de la programacion...

1 respuesta

Usuarios habituales