Curso completo de programación con lenguaje C

wiFlY

#60 Tu pareces controlar del tema. Podrias hacerme el favor de mirar el codigo que puse en #57? es que no entiendo que estoy haciendo mal con los numeros double pero en algun lado la estoy liando.

EDIT: definitvamente hay algo que he entendido mal ya que no soy capaz de introducir un numero double y que me lo devuelva, sin mas XD

2 respuestas
B

#61 si estás usando float para salida tienes que definir las variables como float( a no ser que hagas casting). Eso o usar %lf en el printf.

1 1 respuesta
wiFlY

#62 segun pone en el tutorial los double usan %f. No se, yo no tengo ni flowers, tu sabes que letra deberia usar para los numeros double? tanto para scan como para print.

Saludos y gracias.

cabron

#61

%f es para float, si usas dobule tienes que poner %lf

1
B

Sobre lo que dice #60, es importante controlar el tamaño máximo del input.

Más info, aunque tampoco tiene mucho. Simplemente es controlar el tamaño máximo de la entrada con el parámetro que se le pasa a fgets. Esto también es útil para funciones como strcpy (no la uséis, usad strncpy siempre que podáis).

wiFlY

Bueno, cuelgo los primeros ejercicios resueltos.

Ejercicio 1
Ejercicio 2

.

Ejercicio 3
Ejercicio 4
1 respuesta
gonya707

#66 ahora no puedo darte una respuesta completa a todo (estoy currando) pero en el ultimo ejercicio tienes un error que he visto antes de leer que te daba ese problema jejeje. Echale un ojo, es una tonteria

1 respuesta
wiFlY

#67 Solucionado. Tenia dos errores: me faltaba un & y ademas habia puesto fscanf por fprintf ahahaha es lo que tiene hacer los debes por la noche.

Para los dos siguientes creo que primero tendre que aprender bien como funciona rand y srand y despues intentar hacerlos. Porque asi de primeras no tengo muy claro como.

EDIT: estoy probando a usar el macro RAND_MAX para ponerlo a 100 y asi conseguir al menos que rand me de valores entre 0 y 100, pero no consigo que funcione. Yo he puesto "#include RAND_MAX 100" despues de añadir las librerias y antes del main.

EDIT2: Encontre como limitar el rand superiormente mediante "int rand(voice)%limite". Pero inferiormente aun no he conseguido nada.

MarioTubos
wiFlY no leer
1 2 respuestas
Maaarc
wiFlY no leer
1 2 respuestas
gonya707

#69 #70 pero no se lo resolvais. La cosa es que cada uno se estruje la mente

1 3 respuestas
Maaarc

#71 vale :'(

MarioTubos

#71 Que lo busque en google diras HAHA

1 respuesta
wiFlY

#69 #70 Gracias por la ayuda.

La forma para poner limite superior la habia encontrado en google y consegui que funcionase correctamente, es decir, que no me diese numeros por encima de 100.

La forma para poner limite inferior y superior pero no consegui que funcionase. Acabo de probar ahora y me ha ido perfectamente :/

#73 Google siempre, por supuesto xD Pero que conste que me he interesado por el tema y me han pasado unos apuntes de introduccion a los computadores de teleco. No me los voy a estudiar pero algunas lecturas si que hare heheheheh

#71 Lo que me pusieron ellos lo habia encontrado ya en internet y me pasaba lo que explico en las lineas de arriba. Ahora me va perfectamente el programilla, de hecho dejo aqui el

ejercicio 5

EDIT: DUDA!!!!

Como me he cansado de abrir cmd y tener que navegar para ir a la carpeta donde guardo los programas decidi crear un programa almacenado en la carpeta donde se ejecuta cmd (o la carpeta que aparece por defecto) y que me llevase directamente a la carpeta de los programas.

programa

Pues no me funciona. No la verdad no se si estoy usando correctamente las funciones de stdlib referentes al sistema, pero la cadena de comandos que escribo en cmd para llegar a la carpeta de los programas es exactamente esa (bueno, dir es opcional).

2 respuestas
gonya707

#74 a mi me funciona poniendo una ruta a mi escritorio y haciendo un dir, probablemente es por el espacio en "Dev C", a las consolas no les gustan los directorios con espaciado.

gAdrev

#74

Pon comillas escapadas (\") al directorio. Aunque para algo así, mejor hazte un .BAT o una variable de entorno con el path al que quieras cambiar más fácilmente.

1 1 respuesta
wiFlY

#76 Teniendo en cuenta que los .bat nada mas que me suenan de verlos alguna vez por el pc... creo que intentare hacerlo en C, que ademas es lo que trato de aprender... Tampoco puedo ponerme a aprendermelo todo porque los dias nada mas que tienen 24h.

Pero gracias por la ayuda de todas maneras :)

1 respuesta
gAdrev

#77

Ok, te lo digo porque es mucho más fácil y un programa C me parece una exageración, así de paso ves qué es un BAT. Conocer los lenguajes de shell en los diferentes SO, aunque sea por encima, siempre es útil.

Sería poner en un fichero de texto cuyo nombre termine en .BAT:

cmd /K "cd /d d:\directorio de ejemplo"

Pones el directorio que quieras y listo.

wiFlY

Añado el ultimo ejercicio

Ejercicio 6

edit: estoy liado con el tema de crear un programa que me mande a la carpeta de los programas creados pero no consigo que funcione el comando cd mediante C

1 respuesta
gonya707

#79 estan bien los ejercicios, pero para evitar poner los system pause cada vez que quieres un numero aleatorio cambia la semilla cada vez, tampoco pasa nada si pones cosas como

 srand(1000 * time(NULL) +98765 * time(NULL)));

vamos puedes liar la semilla todo lo que quieras para que te de numeros impredecibles.

Solo veo un error en tus codigos asi echando un ojo rapido y es en el segundo codigo:

num = rand()%(999-100);

Si con eso pretendes que te de un numero de 3 cifras, es incorrecto xD eso te va a dar un numero entre 0 y 899. Se hacen antes las operaciones de los parentesis.

1 1 respuesta
wiFlY

#80 Corrijo la generacion aleatoria de numero entre 100 y 999. Creo que ahora esta bien.

num = rand()%899+100;

Lo de cambiar la semilla lo intente pero no me funcionaba aunque ahora si. Creo que el problema que tuve en su momento fue escribir srand en vez de rand, se lo achaque a que no sabia cambiar de semilla y cambie el programa para, finalmente, darme cuenta de ese error xD

1
B

Allá vamos.

Capítulo 3 - Deberes

Ejercicio 1
Ejercicio 2
Ejercicio 3
Ejercicio 4

Iré editando según vaya acabando los ejercicios.

m4andg4

Holaa muy buena la iniciativa, la verdad es que se bastante de C a haberlo visto en la universidad y tal, pero me asalta una duda...

que diferencia hay entre fprintf(stdout), fscanf(stdin) y printf(), scanf() es la primera vez que veo las dos primeras :O

2 respuestas
wiFlY

#83 si no me equivico, con printf y scanf la entrada y la salida son las standard, mientras que con fprintf y fscanf tienes que especificar que entrada y que salida quieres usar.

1 1 respuesta
gonya707

#83 Es justamente como dice #84. Mas adelante veremos el uso y gestíon de ficheros, y ahí se verá la razón por la que usar fprintf y fscanf.

1
gonya707

4 - Bloques condicionales y mecanismos de decisión

En este capítulo presentaré unas de las estructuras más usadas en cualquier lenguaje de programación, que nos serán muy útiles en especial para tomar decisiones. Hasta ahora nuestro programa era totalmente secuencial, le presentabamos una serie de instrucciones y él las ejecutaba en fila. Ahora es el momento de que el programa sea capaz de decidir si hay ciertas líneas que no se tienen que hacer, o bien si tiene que tomar un camino distinto en vez de aplicar todas las instrucciones.

Pero antes de meternos en faena quiero extender un poco más nuestro abanico de variables e introducir dos más. Una de ellas nos será útil para casi cualquier programa y la otra está íntimamente ligada al uso de bloques condicionales, que es el grueso de esta lección.

variables char

char letra;
letra = 'A';

Una variable char almacena un caracter. Sólamente uno, no podeis poner dos letras dentro de un char. Fijaos en el detalle de que la asignación de un valor a un char exige que el caracter esté entre comillas simples, al contrario de las cadenas de texto, como la que se meten en fprintf y fscanf, que son con comilla doble.

Algunos ya habeis usado sin daros cuenta este tipo de variable cuando poníais tildes en un texto de fprintf, de este modo:

fprintf ("Hola qu%c tal", 130);

En este caso justamente después de la letra u se inserta una variable %c, que corresponde a char, y su valor es 130. Qué es este 130? es la posición de "e minúscula con tilde" en la tabla ascii. En resumen:

  • char define una variable de tipo caracter.

  • las asignaciones de valor se utilizan con comillas simples.

  • el símbolo de inserción de un char es %c.

variables bool

Una variable tipo int ocupa 16 bit, por lo tanto puede almacenar hasta 216 valores distintos. Un bool es una variable que ocupa un solo bit, por lo tanto solo dos valores son posibles. Es por ello por lo que bool se usa para almacenar númueros lógicos, es decir sí o no, verdadero o falso, true or false

bool condicion1;
bool condicion2;

condicion1 = 1; //true
condicion2 = 0; //false

El número 0 es el único que hará que el valor del bool almacene false, cualquier otra cosa será true.

condicion1 = 'a'; //equivale a true
condicion2 = 4.2; //equivale a true

Esto puede sonar un poco confuso ahoira pero se despejará a continuacion en los bloques if. Simplemente pensad en un hueco de la memoria de un sólo bit, por lo que solo puede almacenar un 1 lógico o un 0 lógico, que nosotros traducimos en true o false a efectos de programación. Al contrario que el resto de variables, bool no suele imprimirse por pantalla en ninguna ocasión, asi que no merece la pena saber con qué '%' se inserta en los fprintf.

operadores lógicos

Anteriormente se explicaron los operadores aritméticos, +, -, * etc... Existen muchos más operadores y por ahora vamos a ver otra familia, los operadores lógicos, que se encargan no de operar números, sino de compararlos.

// El operador == es  'igual', compara dos números y devuelve true si son iguales, false en cualquier otro caso.
bool a = (45 == 45 ) ; // true 
bool b = (12 == 45 ) ; // false
bool c = ('a' == 'b' ) ; // false

// El operador != es  'desigual', devuelve true cuando los números son distintos.
bool d = (12 != 45 ) ; // true

// El operador > es  'mayor que', devuelve true cuando el primer número es mayor que el segundo.
bool e = (12 > 45 ) ; // false

Del mismo modo, < es 'menor que', y >= y <= son respectivamente 'mayor o igual' y 'menor o igual'. Para recordar el orden de los símbolos pensad que se escriben igual que se leen.

Otro grupo dentro de los operadores lógicos son:

// El operador ! 'not', niega lo que venga a continuacion y devuelve el resultado contrario
bool f = !(12 == 12); //false

// El operador && 'and' devuelve true sí y sólo sí las dos condiciones de sus lados son true
bool g = (12 == 12) && (32 > 21); //true
bool h = (12 != 54) && (2 >= 21); // false

//El operador || 'or' devuelve false sí y sólo sí todas las condiciones son falsas.
bool i = (12 == 12) || (12 > 21); //true
bool j = (23 == 76) || (12 > 21); //true

Estos dos ultimos operadores son muy fáciles de recordar, simplemente leedlos en voz alta en tono interrogativo, por ejemplo la variable i sería "es doce igual a doce ó doce mayor que veintiuno?" la primera condición es verdadera, por tanto sí.

Por supuesto, en todos estos ejemplos he usado números, que en el caso de programas reales serán variables. Un pequeño consejo: Si comparais una variable con un número, poned primero el número. Es decir así:

bool x = (12 == num);

Y no así:

bool x = (num == 12);

La razón es muy sencilla. En algunas ocasiones te olvidas del segundo = del operador y entonces haces una asignación. Si me equivoco y pongo esto:

bool x = (num = 12);

cambiaré el valor de num a 12 y además una asignación devuelve siempre true, por lo que la condición será siempre verdadera, sin embargo si pongo esto:

bool x = (12 = num);

Dará un error al compilar, porque '12' no es ninguna variable, es un número, y no puedes cambiar su valor.

el bloque if-else

Por fin vamos a darle uso real a los bool. Un bloque condicional if hace que el programa haga (o no) una serie de instrucciones:

if (var == 12){
	//instruccion 1
	//instruccion 2
	//instruccion n
}

//el programa sigue...

En este ejemplo, la comprobación que hacemos es que una variable llamada 'var' que habremos creado antes sea igual que doce. Que es verdadero? entonces ejecuta las instrucciones dentro de las llaves {}. Que no lo es? entonces ignóralas y continua con el programa. Recordad no poner el ; después de un if.

El contenido de los paréntesis de un if es siempre un bool, vamos hay que meter tru o false de alguna manera, pero hemos visto que los operadores lógicos siempre devuelve un bool, y que cualquier cosa que no sea 0 va a retornar true, por ejemplo

if (4){ //entra
}

if ('s'){ //entra
}

if (!5){ //no entra (not 5 devuelve 0, por tanto false)
}

En ocasiones se necesita que cumplida cierta condición se hagan ciertas acciones, y en el caso de que no se cumpla otras. Podríis pensar que una manera de hacer esto es así:

 if (var > 12){
         // cosas...
}
 if ( ! (var > 12)){
         // otras cosas
}

Pero existe otro método mejor, y es el bloque else(si no). else siempre debe ir justo después de un if, y se entrará en else cuando no se haya entrado en if. El código anterior quedaría:

 if (var > 12){
         // cosas...
}
else{
         // otras cosas
}

operador ternario

El operador ternario es una especie de if-else comprimido en una línea. Util cuando solo se desea hacer una acción dentro del if y otra distinta dentro del else. Su modo de uso es este:

// expresión boleana ? valor si cierto : valor si falso
(var1 > 2) ? var2 = 0 : var2 = 1;

En este caso se comprueba si var1 es mayor que 12. El el caso de que sea cierto, a otra variable var2 se le asignará el valor 0, y si es falso, var2 será 1.

switch

Por último, el bloque switch nos sirve para evitar tener muchos if seguidos, algo parecido a esto:

 if (var == 1){
         // cosas...
}
 if (var == 2){
         // cosas...
}
 if (var == 3){
         // cosas...
}
 if (var == 4){
         // cosas...
}

En su lugar, la manera elegante de hacer lo mismo es con switch, de este modo:

switch (var) {
         case 1:
                //cosas
         break;
         case 2:
                //cosas
         break;
         case 3:
                //cosas
         break;
         case 4:
                //cosas
         break;
}

En los paréntesis de switch se especifica siempre una variable, la que querramos comparar, y a continuación tantos bloques de 'case' como necesitemos. Los cases tienen una sintaxis algo rara, en vez de delimitarlos con llaves {}, empiezan con dos puntos : y terminan siempre con uns intrucci break;. No poner el break; haría que se ejecutasen todas las acciones a partir de la primera cierta.

deberes lección 4

-Recordais los ejercicios de otras lecciones que quedaron incompletos? mas concretamente estos:

Realizar un programa completo que pida al usuario dos números por teclado y realice las cuatro operaciones básicas con ellos. El programa debe presentar por pantalla los resultados. El resultado deberia ser algo parecido a esto: http://i.imgur.com/kTq5uLv.png

Crear un programa que pregunte por los dos catetos de un triángulo rectángulo y calcule la hipotenusa. Posteriormente debe calcular los dos ángulos restantes terminando de resolver el triángulo e imprimir todos los resultados por pantalla.

Crear un programa que pregunte un número entero de tres cifras y desglose en numero en centenas unidades y decenas, es posible hacerlo tan solo con int. Ejemplo de resultado: http://puu.sh/6PI58.png

En los tres casos siempre habia la posibilidad de que el usuario trolleara y metiese números que pueden causar error al programa (divided by zero, o un cateto negativo, o un numero de mas de 3 cifras...) Ahora podemos tomar decisiones analizando variables, por lo que el ebjetivo es ahora rehacer estos tres programas, pero que comprueben previamente si el valor introducido es correcto. En el caso de que lo sea continuar la ejecución normalmente, y en caso negativo alertar al usuario de que ha habido un error y se reiniciará el programa automáticamente (esto ultimo podeis hacerlo con system()).

-Crear un programa que pida una letra por teclado e indique al usuario si el caracter obtenido es mayúscula o minúscula.

-Crear una mejora del programa anterior que pida un caracter por teclado e indique al usuario si el caracter obtenido es una letra, un número o cualquier otro símbolo.

-Cuales son los resultados de estas operaciones logicas?

((12>2) || (3<=1)) && (23!=23)
!(4 == 1) || (!12 == !0)
(a == b) && (a < b)
(a == b) || (a < b)

-Hacer otro programa tipo calculadora, pero que esta vez pida los dos numeros y la operacion a realizar. La operacion puede ser un caracter y las posibles entradas los caracteres '+', '-'... etc. Si os quereis flipar un poco podeis hacer que tambien haga potencias, raices, senos... y si hace operaciones que solo exigen un numero de entrada que no pregunte el segundo.

-Más triágulos. Esta vez hacer un programa que decida si el triangulo introducido (3 lados) es equilátero, isósceles o escaleno, comprobar que efectivamente esos lados forman un triangulo url=http://puu.sh/6YhWp.jpg [/url] y si os sentis valurosos, calcular el área

-Un programa que diga si el número introducido es divisible por 2, 3, 5 y 7.

2 1 respuesta
wiFlY

#86 Una pregunta rapida. En que libreria se encuentran estos comandos que has explicado?

1 respuesta
gonya707

#87 En ninguna, es propio del lenguaje C. No son funciones, son instrucciones.

1
B

Venga, soy el único que sigue picando código por aquí? :qq:

Capítulo 4 - Deberes

Ejercicio 1 y 2
Ejercicio 3
Ejercicio 4
Ejercicio 5
Ejercicio 6

Iré editando según vaya acabando los ejercicios.

2 respuestas
angelrcd

A ver, acabo de empezar esto ahora mismito y me he puesto a hacer el ejercicio 2, antes de esto no tenia ni la mas minima idea de programar, pero ni la mas minima en serio...
Esto es lo que he intentado:

spoiler

Cuando intento compilar me dice: Source file not compiled
Seguramente esta lleno de errores aberrantes que harian llorar al niño Jesus y a cualquiera que sepa lo mas minimo de programacion xD, pero yo no lo veo, si alguien me da una ayudita...

1 respuesta