Ayuda Codigo C

1, 2, 3
Sertinell escribió:
Serginius escribió:Buenas, tengo otra duda!

Cómo puedo hacer que me redondee hacia arriba el resultado de una operación? (En C), me iría de perlas para un programa pero no se hacerlo... algo similar a cuando haces la división entre 2 ints, que redondea hacia abajo, pues eso...

Gracias!

Si son 2 enteros, al hacer la división entera sumale 1 ^^.

Si es para redondear otras operaciones, usa ceil, o haz un cast a int y suma 1.

Y es distinto truncar que redondear hacia abajo, solo son lo mismo para positivos.


Y comprueba que el resultado no exceda el límite del tipo de la variable a la que le asignas el resultado.

- ferdy
Vale, como son 2 ints, al final he hecho que si son multiples deje el resultado igual, y si no sume 1, la verdad es que era bastante fácil, pero hay veces que con algo muy tonto no sé que hacer xD

Gracias a todos por responder tan rápido ^^
No se si lo quieres para divisiones o para todo, te pongo para las divisiones de manera clara.

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int num1=0,num2=0;
    int resultado=0;
   
    printf("Introduce el primer numero:\n");
    _flushall();
    scanf("%i",&num1);
    printf("Introduce el segundo numero:\n");
    _flushall();
    scanf("%i",&num2);
    if(num1%num2==1)/*Si el resto de la division de num1 y num2 es 1... (solo devuelve 0 o 1, siendo 1 cuando no es
    {                         exacta la division*/
                    resultado=(num1/num2)+1;
    }
    else
    {
        resultado=num1/num2;
    }
    printf("%i \n",resultado );
    system("pause");
    return 0;
}


En un if no hace falta poner el ==1 o ==0 ya que devuelve 1 si es verdadero o 0 si es falso, pero son mis manias :D
Ouch.... típico error. ¿Qué ocurre si meto estos números? -2147483648 y -1

Saludos.

PD: Iba a decir típico error de principiante. Por desgracia, mucho no principiante tambien lo comete.
Es curioso que la FPE no aparece si defines num1 como unsigned int [boing].

¿Tienes documentación y ejemplos sobre este tipo de fallos, ferdy?
srpatato escribió:Es curioso que la FPE no aparece si defines num1 como unsigned int .


¿Seguro que es curioso? ¿El resultado es correcto?

srpatato escribió:¿Tienes documentación y ejemplos sobre este tipo de fallos, ferdy?


Todo está en el estándar...

El año pasado publiqué algún ejemplo de este tipo de comportamientos "no evidentes" en mi blog.

- ferdy
Ferdi no tengo el compilador a mano y no puedo probar lo que me has dicho, que saldría como resultado un double o más grande? es que no se a que te refieres, yo lo he puesto así porque yo tengo la asignatura "fundamentos de la programación" y tampoco es que nos hayan puestos casos extremos y tal tu sabes ;) Un saludo peña :P
Iverson88 escribió:Ferdi no tengo el compilador a mano y no puedo probar lo que me has dicho, que saldría como resultado un double o más grande? es que no se a que te refieres, yo lo he puesto así porque yo tengo la asignatura "fundamentos de la programación" y tampoco es que nos hayan puestos casos extremos y tal tu sabes ;) Un saludo peña :P

http://codepad.org/GbW6fcIZ

xD
Ferdy escribió:
srpatato escribió:Es curioso que la FPE no aparece si defines num1 como unsigned int .


¿Seguro que es curioso? ¿El resultado es correcto?

Asignando int a secas, salta una float pointer exception; con unsigned int, el resultado sale 0. Por supuesto que no es el resultado correcto, de ahí mi curiosidad :P de hecho, no sé "por qué" ocurre ni esto ni la FPE. Sé qué ocurre, pero no por qué. No he tocado tanto C ni C++... pero habrá que hacerlo.

srpatato escribió:¿Tienes documentación y ejemplos sobre este tipo de fallos, ferdy?


Todo está en el estándar...

El año pasado publiqué algún ejemplo de este tipo de comportamientos "no evidentes" en mi blog.

- ferdy


Sí, pero un tocho de 550 páginas como que no apetece mirar de cabo a rabo. Ejemplos concretos interesan más, así que miraré tu flog. Y no es por perrería, es por buscar precisamente los fallos más "extraños" a los que un tío que programe en C/C++ se pueda encontrar. De todas formas, para este ejemplo intentaré entender qué causa este comportamiento en el estándar.
Sí bueno, -2^31 entre -1 es 2^31, valor que escapa al rango de un int con signo... pero ya te digo, nunca me había parado a pensar qué pasaría al hacer la división. Si multiplicas en vez de dividir, por ejemplo, no te salta FPE... es el mismo tipo de excepción que dividir entre cero, pero no es la misma excepción no?
Buenas :)
Aprovecho el hilo para preguntar yo también una cuestión (casi podría ser esto el Hilo Oficial de preguntas de C XD). Estoy haciendo en C el "Juego de la vida" y, cómo no, me encuentro con un problema a la hora de "limpiar" la pantalla para volver a mostrar la matriz/gradilla/como queráis llamarlo XD. Nunca uso funciones de este tipo porque no las veo necesarias, pero en este caso la diferencia de usarla a no se nota bastante [ayay]. De momento llamo a una función que ejecuta las siguientes líneas:
printf("\033[2J"); // "Borra" pantalla
printf("\033[1;1H"); // Sitúa cursor al inicio

Pero no se si esto funcionaría en todos los casos (lo dudo, porque la terminal ha de tener implementados estos códigos), y he pensado en hacerlo con un define (que habría que modificar según el SO en el que vayamos a compilar):
#define LINUX    //LINUX/WINDOWS
#ifdef WINDOWS
  #define ClearScreen system("cls");
#endif
#ifdef LINUX
  #define ClearScreen system("clear");
#endif
// o en vez de 2 #ifdef's poner un #else

¿Cuál de las 2 formas veis mejor/soléis utilizar?

Y aprovechando el post... tengo un algoritmo para descomponer un número en factores primos que sería algo tal que:
factor:=2
mientras numero>1 hacer
   mientras numero%factor==0
      numero:=numero/factor
      escribir(factor)
   fin mientras
   factor++
fin mientras

Esto es, a groso modo, el código que tengo (a falta de alguna pijada como por ejemplo agrupar mismos factores en potencias). Mi duda es... ¿Es una basura de código o hay algún otro método? Porque si pienso, p.ej., en el número 243124321, sus factores son 11 y 22102211, es decir, el programa debe repetirse 22102211-2 veces para hallar este segundo número (a pesar de eso, qué rápido lo saca el jodio XD) pero aunque a día de hoy vayamos un poco más sobrados de cpu, no deja de parecerme bastante

En fin, suficiente por hoy XD. Saludos! [beer]
¿Cuál de las 2 formas veis mejor/soléis utilizar?


En Linux/Unix puedes usar ncurses para esto.

Sobre el código no tengo mucho que decirte. Quiero decir, si miras por internet verás que hay cienmil formas de hacer 'Integer Factorization'. La elección de un método dependerá de tus necesidades (tamaño de los números, cantidad de números, ...)

Saludos.
Gracias Ferdy por los consejos, me han venido muy bien [chulito]
Alguien me puede decir porque mi programa no entra en la opcion numero 1, que es donde tengo la opcion de sumar?. Se que mi codigo no es bueno ni nada de eso, pero solo quiero saber como desde el menu, entra en las distintas opciones.
Gracias.
#include <stdio.h>
#include <stdlib.h>

int sumar(int numero1,int numero2);
main()

{
    int opcion;

while (opcion !=5)
{
    printf("1- Presione 1 para sumar\n");
    printf("2- Presione 2 para restar\n");
    printf("3- Presione 3 para division\n");
    printf("4- Presione 4 para multiplicacion\n");
    printf("5- Presione 5 para salir\n");
    scanf("%d",&opcion);
   
    switch(opcion) 
  {
        case 1:
system("cls");
int numero1, numero2;
printf("Introducir valor primer numero\n");
scanf("%d",&numero1);
printf("Introducir valor segundo numero\n");
scanf("%d",&numero2);
printf("El resultado es: %d\n",sumar(numero1,numero2));
system("PAUSE");   
return 0;         
system("cls");
//goto top;
int sumar(int numero1,int numero2)
{
   

  return numero1+numero2;
 
}
           
           
            break;
           
            case 2:
               
                break;
               
                case 3:
                   
                    break;
                   
                    case 4:
                       
                        break;
                       
                        case 5:
                           
                           
                            break;
                    }
                }
                           
            }
Crapos escribió:Alguien me puede decir porque mi programa no entra en la opcion numero 1, que es donde tengo la opcion de sumar?. Se que mi codigo no es bueno ni nada de eso, pero solo quiero saber como desde el menu, entra en las distintas opciones.
Gracias.
#include <stdio.h>
#include <stdlib.h>

int sumar(int numero1,int numero2);
main()

{
    int opcion;

while (opcion !=5)
{
    printf("1- Presione 1 para sumar\n");
    printf("2- Presione 2 para restar\n");
    printf("3- Presione 3 para division\n");
    printf("4- Presione 4 para multiplicacion\n");
    printf("5- Presione 5 para salir\n");
    scanf("%d",&opcion);
   
    switch(opcion) 
  {
        case1:
system("cls");
int numero1, numero2;
printf("Introducir valor primer numero\n");
scanf("%d",&numero1);
printf("Introducir valor segundo numero\n");
scanf("%d",&numero2);
printf("El resultado es: %d\n",sumar(numero1,numero2));
system("PAUSE");   
return 0;         
system("cls");
//goto top;
int sumar(int numero1,int numero2)
{
   

  return numero1+numero2;
 
}
           
           
            break;
           
            case2:
               
                break;
               
                case3:
                   
                    break;
                   
                    case4:
                       
                        break;
                       
                        case5:
                           
                           
                            break;
                    }
                }
                           
            }


Antes de nada, acostumbrate e indentar bien el codigo, asi sera todo mucho mas legible
Definir una fionción asi por las buenas dentro de un switch es feo
case1 no deberia ser case 1 (con espacio)?

No te puedo decir mucho mas, el codigo esta muy desordenado y no se entiende, intenta organizarlo un poco
Vale, se me fue el espacio.
Lo unico que quiero saber, es que tengo que hacer en el case, para que me enlace con la funcion, una funcion como esa.
Gracias.
Como te ha dicho d34th, dentro de la función switch estás juntando los "case" con el valor, deben estar separados. También estaría bien que declararas un "default" aunque nunca fuese a cumplirse.

En cuanto al menú... tan sólo evalúa que la variable "opcion" sea distinta de 5 para repetir el while, por lo que si eliges 1, 2, 3 o 4 (o cualquier otro valor) no se cumple la condición y vuelve a empezar el bucle. Además, empiezas comprobando que la variable sea distinta de 5 cuando ni si quiera tiene asignado un valor.
hola nececito ayuda con este ejercicio:
escribir un programa en c que escriba el directorio activo, indicando cada uno de sus componentes por separado. Es decir, el programa deberá mostrar por pantalla "El disco es: XXX", "El path hasta el directorio es", etcétera.

porfavor ayuda que nose como hacerlo, bueno gracias de antemano. [ok] [oki]
Qué puta manía con que os hagan los deberes....
Ferdy escribió:Qué puta manía con que os hagan los deberes....
Ferdy hay que entenderlo, si acaba de empezar y no sabe por donde meterle mano...yo creo que en estos casos una especie de pseudocodigo o plantearle los pasos si lo podriamo poner, y luego cuando el este desarrollando el codigo que nos plantee los problemas que tenga no?
Iverson88 escribió:
Ferdy escribió:Qué puta manía con que os hagan los deberes....
Ferdy hay que entenderlo, si acaba de empezar y no sabe por donde meterle mano...yo creo que en estos casos una especie de pseudocodigo o plantearle los pasos si lo podriamo poner, y luego cuando el este desarrollando el codigo que nos plantee los problemas que tenga no?


Si no tienes unas nociones básicas de programación, dudo que te pidan trabajar con eso. Y si no las tiene, seguramente es por que no se ha molestado en aprenderlo.

Salu2!
Iverson88 escribió:Ferdy hay que entenderlo, si acaba de empezar y no sabe por donde meterle mano...yo creo que en estos casos una especie de pseudocodigo o plantearle los pasos si lo podriamo poner, y luego cuando el este desarrollando el codigo que nos plantee los problemas que tenga no?


Estoy de acuerdo con \-\adEs... cuando hay pruebas de que la persona ha currado y ha pensado por su cuenta, nunca he tenido problemas en echar un cable.... leñe, a más de uno le he acompañado en largas sesiones de debugging. No es cuestión de no ayudar, es cuestión de no ser el reemplazo barato del "difunto" Rincón del Vago.

- ferdy
Ferdy escribió:
Iverson88 escribió:Ferdy hay que entenderlo, si acaba de empezar y no sabe por donde meterle mano...yo creo que en estos casos una especie de pseudocodigo o plantearle los pasos si lo podriamo poner, y luego cuando el este desarrollando el codigo que nos plantee los problemas que tenga no?


Estoy de acuerdo con \-\adEs... cuando hay pruebas de que la persona ha currado y ha pensado por su cuenta, nunca he tenido problemas en echar un cable.... leñe, a más de uno le he acompañado en largas sesiones de debugging. No es cuestión de no ayudar, es cuestión de no ser el reemplazo barato del "difunto" Rincón del Vago.

- ferdy

ya si yo te entiendo, pero solo intentaba que llegáramos a un punto intermedio entre todos , sin malos rollos y tal :)
hola gracias por responde pero esque noce por donde cojerlo y no tengo nada aun por eso que ria saber si me pueden ayudar con este ejercicio por que esto del directorio activo no se que es y ademas como hago eso para que me busque y mediga ese mensaje porque primero lo tendre que buscar pero eso mismo noce como hacerlo pero bueno si alguien me puede ayudar se lo agradesco de antemano. [ok] [oki]
Hola de nuevo, tengo una duda algo simple...

La cosa es que quiero meter un fichero como argumento para el main, y que sí el fichero no se encuentra en el "run directory", que no me sale ahora en castellano, pues de un error.

¿Cómo lo hago? Porque se que en el argc es igual a 2, pero aunque no exista el fichero en la carpeta sigue siendo igual a 2, pensaba que si no existia el fichero no lo contaria...

Hay alguna otra forma de detectar si un fichero determinado está en una carpeta? Porque también lo puedo hacer así y me ahorro lo del argumento...

Gracias de antemano
Tienes varias opciones para hacer eso. Lo más normal es usar la función stat.

- ferdy
Ferdy escribió:Tienes varias opciones para hacer eso. Lo más normal es usar la función stat.

- ferdy

Y alguna forma usando sólo las librerias stdio y stdlib? :/ Que son las únicas que hemos usado hasta ahora y no sé si me dejarán usar otras
1) stdlib y stdio NO son librerías.
2) fopen. Pero si no incluys 'errno.h' no podrás saber exactamente si el fichero no existe o si no tienes permisos para abrirlo.

- ferdy
Ferdy escribió:
No es por nada, acabo de enseñar a otros profesores de la universidad lo que has dicho, y sinceramente, no te gustaria saber lo que dicen de ti.


Qué pena de sitio jaja. Supongo que ninguno de vosotros usará nunca quicksort porque "'n^2' es siempre peor que 'n log n'". jaja.


¿De qué hablas? ¿Qué tiene que ver la distinción entre caso promedio/peor con la discusión?

Ferdy escribió:
lo que has dicho es un error tipico de novatos (aunque tienes parte de razon), deberias revisar manuales de eficiencia de algoritmos, sobretodo por que el de encontrar todos los divisiores es un ejercicio muy famoso, y se hace hasta la raiz(esta incluida)


No he dicho nada de ESTE caso. Aquí no hace falta hacer más trabajo que hasta raiz de n.


¿Y qué más da? O(sqrt(n)) siempre es mejor que O(n) en general y en este caso, también.

Ferdy escribió:
por otra parte si n0 es muy pequeña(poca pendiente(supongo que te refieres a eso)) el programa se divide en 2 partes un en caso de que n se a menor que n0 y otra que sea mayor.

independientemente de n0, en el infinito SIEMPRE es mayou una lineal que no una raiz


Vamos a refrescar la mente:

f(n) = O(g(n)) si existen constantes c > 0 y n0 > 0 tales que: 0 <= f(n) <= g(n) para n >= n0


¿Aún crees que es la pendiente?

¿El infinito? En la teoría está bien, en la práctica depende de los datos con los que trates. En este caso está claro qué interesa. Como afirmación para cualquier caso, es una falacia.


Vamos a refrescar la tuya.

¿En la práctica? En la práctica es mejor un O(sqrt(n)) que un O(n). De falacia no tiene nada. Otra cosa es que para n pequeña uses otro algoritmo, que es muy distinto, machote. Y estas optimizaciones sólo se hacen para software muy muy específico en los que el algoritmo general es demasiado malo.

Ferdy escribió:
os recomiendo esta pagina http://uva.onlinejudge.org/, si encontrais este ejercicio de los divisores y lo haceis hasta n, no os lo aceptaran, aqui se hacen varios torneos de programacion muy importantes, y de unos 100000 usuarios yo estoy entre los 8000 primeros (no es una buena posicion tampoco, ya que voy haciendo con calma)


Como e-penis está bien... ahora, no tiene ningún valor.


¿No tiene valor?

Vaya, acabas de demostrar que no tienes ni puta idea del tema.

Me encantan los que van de sobrados sacando punta a cualquier comentario y en realidad luego demuestran que no tienen ni papa. [angelito]
Me encantan los que van de sobrados sacando punta a cualquier comentario y en realidad luego demuestran que no tienen ni papa


ell oh ell

----

¿De qué hablas? ¿Qué tiene que ver la distinción entre caso promedio/peor con la discusión?


Tiene bastante que ver con la discusión.

¿Y qué más da? O(sqrt(n)) siempre es mejor que O(n) en general y en este caso, también.


Por supuesto que no da igual. En general es distinto de siempre. Las recetas que valen para 'siempre' son una necedad.

¿Y qué más da? O(sqrt(n)) siempre es mejor que O(n) en general y en este caso, también.


No siempre, no.

¿En la práctica? En la práctica es mejor un O(sqrt(n)) que un O(n). De falacia no tiene nada. Otra cosa es que para n pequeña uses otro algoritmo, que es muy distinto, machote. Y estas optimizaciones sólo se hacen para software muy muy específico en los que el algoritmo general es demasiado malo.


¿Qué es 'el algoritmo general'? Elegir el algoritmo adecuado para los datos con los que vas a trabajar no es una optimización que se hace para software muy muy específico. Es lo que hace cualquier diseñador de software medio decente.

¿No tiene valor?

Vaya, acabas de demostrar que no tienes ni puta idea del tema


¿Y cuál es el valor real de eso? Está muy bien para practicar, aprender, mejorar, .... pero no significa nada.

- ferdy
Ferdy escribió:
¿De qué hablas? ¿Qué tiene que ver la distinción entre caso promedio/peor con la discusión?


Tiene bastante que ver con la discusión.


Tus argumentos son realmente convincentes.

Ferdy escribió:
¿Y qué más da? O(sqrt(n)) siempre es mejor que O(n) en general y en este caso, también.


Por supuesto que no da igual. En general es distinto de siempre. Las recetas que valen para 'siempre' son una necedad.


Bien, has descubierto para qué he puesto "en general" y quizás entiendas que la gente de los primeros posts estaba hablando del caso general y no del particular, que es lo habitual cuando se habla de complejidad o de cualquier cosa sin necesidad de explicitarlo.

(En general lo anterior también ; ), no vuelvas a entender las cosas por dónde te interesa).

Ferdy escribió:
¿Y qué más da? O(sqrt(n)) siempre es mejor que O(n) en general y en este caso, también.


No siempre, no.


Lo mismo de arriba.

Ferdy escribió:
¿En la práctica? En la práctica es mejor un O(sqrt(n)) que un O(n). De falacia no tiene nada. Otra cosa es que para n pequeña uses otro algoritmo, que es muy distinto, machote. Y estas optimizaciones sólo se hacen para software muy muy específico en los que el algoritmo general es demasiado malo.


¿Qué es 'el algoritmo general'? Elegir el algoritmo adecuado para los datos con los que vas a trabajar no es una optimización que se hace para software muy muy específico. Es lo que hace cualquier diseñador de software medio decente.


El algoritmo general es el que se utiliza para la mayoría de casos.

Y no, no tiene nada que ver con los datos con los que se va a trabajar. No has entendido la discusión.

Una cosa es optimizar para pocos datos de entrada y otra muy distinta para determinados datos. No tiene nada que ver una cosa con otra y las estás mezclando.

Aquí se está hablando de órdenes de complejidad, y te han dicho que en general es mejor un O(sqrt(n)) que un O(n), y es verdad, no tiene nada de falacia.

Demostración: Es en general mejor porque, en cuanto al número de datos de entrada (que es de lo que se está hablando aquí, repito), el número de casos para los que O(sqrt(n)) es mejor es infinito (y por tanto son la mayoría, ergo el caso general), dado que para "n pequeñas" son un número finito de casos: Exactamente el n0 que tú citabas, que es un número natural y por tanto finito.

Si tú mismo citas la definición matemática y no la entiendes o no la quieres entender, es tu problema. Estás haciendo el mismo papel que el inversor que mueve su millón de euros en bolsa todos los días y luego se preocupa por el céntimo que se le ha perdido en el sofá. Es absurdo.

Ferdy escribió:
¿No tiene valor?

Vaya, acabas de demostrar que no tienes ni puta idea del tema


¿Y cuál es el valor real de eso? Está muy bien para practicar, aprender, mejorar, .... pero no significa nada.


Nada, nada. Tú sigue optimizando para los casos n <= n0, que el resto del dinero ya me lo llevo yo ; )
Aquí se está hablando de órdenes de complejidad, y te han dicho que en general es mejor un O(sqrt(n)) que un O(n), y es verdad, no tiene nada de falacia.


Lo que yo he tachado de falacia es que SIEMPRE sea mejor.

Demostración: Es en general mejor porque, en cuanto al número de datos de entrada (que es de lo que se está hablando aquí, repito), el número de casos para los que O(sqrt(n)) es mejor es infinito (y por tanto son la mayoría, ergo el caso general), dado que para "n pequeñas" son un número finito de casos: Exactamente el n0 que tú citabas, que es un número natural y por tanto finito.


¡Qué ocurrente! Pena que no tenga ninguna gracia y no se parezca en NADA a una demostración. Se nota que lees y escribes pocas...

Por otro lado, no creo haber dicho lo que intentas rebatir.

Si tú mismo citas la definición matemática y no la entiendes o no la quieres entender, es tu problema. Estás haciendo el mismo papel que el inversor que mueve su millón de euros en bolsa todos los días y luego se preocupa por el céntimo que se le ha perdido en el sofá. Es absurdo.


La entiendo perfectamente, gracias.

Nada, nada. Tú sigue optimizando para los casos n <= n0, que el resto del dinero ya me lo llevo yo ; )


Uh huh.

- ferdy
Ferdy escribió:
Aquí se está hablando de órdenes de complejidad, y te han dicho que en general es mejor un O(sqrt(n)) que un O(n), y es verdad, no tiene nada de falacia.


Lo que yo he tachado de falacia es que SIEMPRE sea mejor.


No veo que xgc1986 dijera que SIEMPRE era mejor. El no decir "en general" tampoco implica que sea una falacia, ni siquiera falso (que son cosas distintas), porque se sobreentiende que se habla en general por defecto.

Ferdy escribió:
Demostración: Es en general mejor porque, en cuanto al número de datos de entrada (que es de lo que se está hablando aquí, repito), el número de casos para los que O(sqrt(n)) es mejor es infinito (y por tanto son la mayoría, ergo el caso general), dado que para "n pequeñas" son un número finito de casos: Exactamente el n0 que tú citabas, que es un número natural y por tanto finito.


¡Qué ocurrente! Pena que no tenga ninguna gracia y no se parezca en NADA a una demostración. Se nota que lees y escribes pocas...

Por otro lado, no creo haber dicho lo que intentas rebatir.


A mí lo que me parece es que, de nuevo, te vas por la tangente cuando no te interesa discutir algo. : )

Ferdy escribió:
Nada, nada. Tú sigue optimizando para los casos n <= n0, que el resto del dinero ya me lo llevo yo ; )


Uh huh.


Hasta la 1 AM no aúllo, así que no te puedo acompañar el grito...
Por favor dejaros de discusiones y pataletas de quinceañeros que somos ya mayorcitos y encima en hilo es para ayudar a la peña con códigos escritos en C.
Podéis dar varias opciones a un problema, y que el usuario pruebe y el ya verá (se supone xD) cual le es mejor en su caso y tal...

Venga en serio, que para un hilo que me gusta de eol y que siempre espero que la peña escriba no lo echeis por la borda.
Necesito que me echeis una mano, tengo que hacer un programilla, una especie de jueguecillo, y no se por que me entra 2 veces por un mismo sitio cuando deberia de entrar solo una. bueno cuelgo las funciones, se trata de llevar un cursor a una salida sin usar arrays multidimensionales.

El main
int main()
{
    int xexit, yexit, xpos=1, ypos=1, finish=0;
    struct stats p;
    srand((unsigned int)time(NULL));                            //semilla random
    posicionAleatoria(xexit, yexit, ROW_MAX, COL_MAX);          //Aleatorizacion de las variables de la posicion de salida
    while (finish==0)
    {
        finish=menu(xpos, ypos, xexit, yexit, p);                  //fin se pone a 1 cuando acaba
    }
    return 0;
}

inicio las variables y me mantengo en bucle llamando a menu mientras que finish = 0


int menu(int xpos, int ypos, int xexit, int yexit, struct stats& p)
{
    int fin=0;
    char c=0;
    printf ("\n\n\n\nPara empezar el juego pulse -1-\nPara ver las ultimas estadisticas pulsa -2-\nPara salir pulse -3-\n");
    fflush (stdin);
    scanf ("%c", &c);
    switch (c)
    {
    case '1':
        juego (xpos, ypos, xexit, yexit, p);
        break;
    case '2':
        printStats(p);
        break;
    case '3':
        fin=1;
        break;
    default:
        printf ("inserte un numero valido");
    }
    return fin;
}

inicio fin a 0, que sera la que devuelva por el return. Luego scaneo un char y lo evaluo con el switch (la estructura p que le paso a la funcion es para las estadisticas)

El programa completo
#include <iostream> <stdlib.h>                                  //stdlib.h para rand()
#define ROW_MAX 20
#define COL_MAX 20
#define TAM_MAX 50
using namespace std;

struct stats
{
    int nummov;
    int cambiodir;
    char mov[TAM_MAX];
};

void pintaSimbolo(int x, int y, char c);                        //
void borraPantalla();                                           //borra la pantalla
int comparaPos(int x1, int y1, int x2, int y2);                 //compara la posiciion de 2 objetos devolviendo un 1 si se cumple
void mover(int& x, int& y, char dir, struct stats& p);          //actualiza las coordenadas del cursor en funcion del caracter pasado
void posicionAleatoria(int& x,int& y,int maxx,int maxy);        //genera unas coordenadas aleatorias para la salida
void printOrden(int xpos,int ypos,int xexit,int yexit);         //Printea por orden las posiciones
int menu(int xpos, int ypos, int xexit, int yexit, struct stats &p);
void printStats(struct stats);
void juego(int xpos, int ypos, int xexit, int yexit, struct stats &p);




int main()
{
    int xexit, yexit, xpos=1, ypos=1, finish=0;
    struct stats p;
    srand((unsigned int)time(NULL));                            //semilla random
    posicionAleatoria(xexit, yexit, ROW_MAX, COL_MAX);          //Aleatorizacion de las variables de la posicion de salida
    while (finish==0)
    {
        finish=menu(xpos, ypos, xexit, yexit, p);                  //fin se pone a 1 cuando acaba
    }
    return 0;
}

void borraPantalla()
{
    int i;
    for (i=1;i<=ROW_MAX;i++)                                          //Bucle que recorre las filas, printeando al final un \n
    {
        printf ("\n");
    }
}

void pintaSimbolo(int x, int y, char c)
{
    int i,j;
    if (y==0)                                                   //este caso es especial para cuando tenemos en la misma liena dos elementos que printear
    {
        for (j=1; j<=x; j++)
        {
            if (j==x)
            {
                printf("%c",c);
            }
            else
            {
                printf (" ");
            }
        }
    }
    else                                                        //para cualquier otro caso, (solo y=0 en el caso anterior) funciona normalmente
    {
        for (i=1;i<=y;i++)                                          //bucle de columna
        {
            printf ("\n|");
            if (i==y)                                               //si estamos en la columna que coincide con y
            {
                for (j=1;j<=x;j++)                                  //recorremos las posiciones de columnas hasta x
                {
                    if (j==x)
                    {
                        printf("%c",c);                             //si estamos en x printeamos el caracter
                    }
                    else
                    {
                        printf (" ");                               //si no, ' '
                    }
                }
            }
        }
    }
}

int comparaPos(int x1, int y1, int x2, int y2)
{
    int a=0;
    if ((x1==x2)&&(y1==y2))                                     //si es cierta la condicion de que sean iguales 2 a 2 las posiciones x e y, ponemos el valor de a a 1
    {
        a=1;
    }
    return a;
}

void mover(int& x, int& y, char dir, struct stats& p)                            //conviene modificarla a int para mostrar si hay error
{
    int error=0,i;
    switch (dir)
    {
    case 'o':
        y --;
        break;
    case 'p':
        y ++;
        break;
    case 'q':
        x --;
        break;
    case 'a':
        x ++;
        break;
    default:
        error=1;
    }
    for(i=0; p.mov[i]!='\0'; i++){}                                //hallamos la posicion de '\n'
    p.mov[i]= dir;
    p.mov[i+1]= '\n';
}

void posicionAleatoria(int& x,int& y,int maxx,int maxy)            //Aleatoriza una posicion (x,y)
{
    maxx ++;
    maxy ++;
    x= (rand()%maxx)+1;                                                //rand genera un numero aleatorio. Haciendole el módulo al N maximo +1 nos puede salir un numero que va desde 0 hasta N
    y= (rand()%maxy)+1;

}

void printOrden(int xpos,int ypos,int xexit,int yexit)            //printea por orden
{
    if (ypos==yexit)
    {
        if (xpos<xexit)                                           //si es menor el cursor, se printea este. si no se printea primero la salida. No pueden sen iguales por que se comprueba previamente par ver quien gana
        {
            pintaSimbolo(xpos, ypos, '*');                        //aqui se printea el cursor
            pintaSimbolo((xexit-xpos), 0, 'E');                  //se printea la salida, al estar dentro de la misma posicion x solo hay que printear la linea y
        }
        else if (xpos>xexit)
        {
            pintaSimbolo(xexit, yexit, 'E');                        //aqui se printea la salida
            pintaSimbolo((xpos-xexit), 0, '*');                  //al contrario que antes
        }
    }
    else if (ypos>yexit)
    {
        pintaSimbolo(xexit, yexit, 'E');
        pintaSimbolo(xpos, (ypos-yexit), '*');                //el -1 es por que printea pla propia funcion de pintar simbolo
    }
    else if (ypos<yexit)
    {
        pintaSimbolo(xpos, ypos, '*');
        pintaSimbolo(xexit, (yexit-ypos), 'E');
    }

    else
    {
        printf("error");
    }
    printf("\n");
}

int menu(int xpos, int ypos, int xexit, int yexit, struct stats& p)
{
    int fin=0;
    char c=0;
    printf ("\n\n\n\nPara empezar el juego pulse -1-\nPara ver las ultimas estadisticas pulsa -2-\nPara salir pulse -3-\n");
    fflush (stdin);
    scanf ("%c", &c);
    switch (c)
    {
    case '1':
        juego (xpos, ypos, xexit, yexit, p);
        break;
    case '2':
        printStats(p);
        break;
    case '3':
        fin=1;
        break;
    default:
        printf ("inserte un numero valido");
    }
    return fin;
}


void printStats(struct stats p)
{
    printf ("\nEl numero de movimientos han sido:%i", p.nummov);
    printf ("\nEl numero de cambios de direccion han sido:%i", p.cambiodir);
    printf ("\nLos movimientos han sido:%s", p.mov);
}

void juego (int xpos, int ypos, int xexit, int yexit, struct stats& p)
{
    int f=0, contador=0, i;
    char dir;
    p.nummov=0;
    p.cambiodir=0;
    for (i=0;i<=TAM_MAX;i++)
        p.mov[i]=' ';
    //reiniciar la estructura de stats
    printOrden(xpos, ypos, xexit, yexit);
    while (f!=1)
    {
        fflush (stdin);
        scanf ("%c", &dir);
        mover (xpos, ypos, dir, p);
        borraPantalla();
        printOrden(xpos, ypos, xexit, yexit);
        f = comparaPos( xpos, ypos, xexit, yexit);
        contador ++;
    }
    p.nummov=contador/2;
    //actualizar numero de movimientos con contador
    printf ("You win!");
}


No esta terminado del todo, falta algunas cosillas referentes a las stats pero solucionando lo del printeo vario del menu ya solucionaria las cosas
Gracias de antemano.
EDIT: el fallo en si es este (ejecutado enel terminal)
Para empezar el juego pulse -1-
Para ver las ultimas estadisticas pulsa -2-
Para salir pulse -3-
2

El numero de movimientos han sido:0
El numero de cambios de direccion han sido:0
Los movimientos han sido:



Para empezar el juego pulse -1-
Para ver las ultimas estadisticas pulsa -2-
Para salir pulse -3-
inserte un numero valido



Para empezar el juego pulse -1-
Para ver las ultimas estadisticas pulsa -2-
Para salir pulse -3-
1) Eso es C++ no C. No pasa nada, simplemente que lo supieras (probablemente ya lo sabes).
2) No uses 'fflush(stdin)'. fflush solo tiene sentido en flujos de salida (http://www.opengroup.org/onlinepubs/000 ... flush.html)
3) El problema que tienes es que scanf NO está consumiendo el \n que mete el 'enter' en el buffer. Hay varias opciones para arreglar esto. Lo más fácil es usar " %c" como argumento de scanf (mira el espacio antes del %). Para más información de por qué esto es así http://www.opengroup.org/onlinepubs/000 ... scanf.html

- ferdy

-------

PD: Ya que estás usando C++, quizá te interese utilizar los iostreams en lugar de stdio (http://www.cplusplus.com/reference)

- ferdy
Ferdy escribió:1) Eso es C++ no C. No pasa nada, simplemente que lo supieras (probablemente ya lo sabes).
2) No uses 'fflush(stdin)'. fflush solo tiene sentido en flujos de salida (http://www.opengroup.org/onlinepubs/000 ... flush.html)
3) El problema que tienes es que scanf NO está consumiendo el \n que mete el 'enter' en el buffer. Hay varias opciones para arreglar esto. Lo más fácil es usar " %c" como argumento de scanf (mira el espacio antes del %). Para más información de por qué esto es así http://www.opengroup.org/onlinepubs/000 ... scanf.html

- ferdy

-------

PD: Ya que estás usando C++, quizá te interese utilizar los iostreams en lugar de stdio (http://www.cplusplus.com/reference)

- ferdy

Funciona perfectamente, mil gracias. Efectivamente es C++, usamos un par de detalles que hacen que sea mas sencillo (como por ejemplo el modo de definir las funciones por referencia)
Lo de fflush, ya he visto que hace mas bien poco, nuestro profesor nos lo aconseja que lo usemos, pero tampoco nos lo ha exigido.
Lo del iostreams, pues es que estamos programando en "casi C" xD
De todas formas el grueso de mi carrera creo que voy a tener que programar mas en assembler que en C, aun que sea infinitamente mas comodo este ultimo XD.
Un saludo.
Sobre el tema de la complejidad que hablabais antes, yo si creo que en general es preferible un O(nlogn) que un O(n^2), sobretodo si no tienes ni idea de con qué datos vas a usar el algoritmo, ni con qué tamaño; pero a más de uno se le quedaría la cara a cuadros al ver que un O(2^n) puede resolver el tema antes que el O(nlogn); y dadas las respuestas que he leido por aquí es muy probable que esto pasase.

Hablar sobre orden de complejidad, y no decir nada de los algoritmos en sí... es hablar a medias.

Luego te llega otro que te dice que resuelve tu O(2^n) en O(n) y el caradura no tiene cojones a demostrarte que su algoritmo es completo, ni adecuado, ni poyas ni nada. (Como leí hace un tiempo para un pseudointento de demostración de P=NP)
Bueno, pues refloto con una duda relacionada con el modificador const.

Tengo esta estructura para almacenar valores de píxeles:
struct Matriz{

    int bandas; int filas; int columnas;
    unsigned char* matriz;

    // Constructor
    Matriz (int _bandas, int _filas, int _columnas) {
        bandas = _bandas; filas = _filas; columnas = _columnas;
        matriz = (unsigned char*)malloc(sizeof (unsigned char) * filas * columnas * bandas);
        for (int i = 0; i < filas * columnas * bandas; i++) matriz[i] = 0;
    }

};


Luego, hago un puntero a una Matriz de estas e invoco una función que solo debería leer los valores de la matriz, tal que así:
int obtenerMedia(const Matriz *prueba); // Prototipo de la función a la que llamo
Matriz *m_prueba = new Matriz (3, 10, 10); // Por ejemplo
int mediaDePrueba = obtenerMedia(m_prueba);


Mi pregunta es (y si me equivoco en algún punto, pido perdón): dado que el prototipo de obtenerMedia emplea el modificador const en el parámetro, los miembros de m_prueba (es decir, bandas, filas, columnas y matriz) no pueden ser modificados, pero los valores apuntados por m_prueba -> matriz sí, ¿verdad?.
Dicho de otro modo,
int obtenerMedia(const Matriz *m_prueba){
(...)
m_prueba -> bandas = 3; // Ilegal, m_prueba es de tipo const y sus miembros no pueden ser modificados en esta función
m_prueba -> filas = 9; // Ilegal
m_prueba -> columnas = 9; // Ilegal
m_prueba -> matriz++; // Ilegal
m_prueba -> matriz[0]++;  // Legal
(...)
}

¿Estoy en lo cierto? Dicho esto, ¿hay alguna forma de asegurarse de que el contenido de m_prueba -> matriz no pueda ser modificado?

EDITO: ya lo tengo:
struct Matriz{

    int bandas; int filas; int columnas;
    const unsigned char* matriz; // Modifico esto

    // Constructor
    Matriz (int _bandas, int _filas, int _columnas) {
        bandas = _bandas; filas = _filas; columnas = _columnas;
        matriz = (unsigned char*)malloc(sizeof (unsigned char) * filas * columnas * bandas);
        // Inicialización a cero eliminada
    }

};
amuchamu escribió:
Serginius escribió:Aprovecho el hilo, yo estoy en un caso similar...

El ejercicio es este:
Escribe un programa que calcule la suma de todos los números múltiplos de 5
comprendidos entre dos enteros positivos leídos por teclado


Yo he llegado hasta aquí
#include <stdio.h>

int main()
{
  int N1;
  int N2;
  int suma=0;
  int entre;
 
  printf ("Introduce un número: ");
  scanf ("%d",&N1);
  entre = N1;
  printf ("Introduce otro número: ");
  scanf ("%d",&N2);
 
    while (entre<=N2)
  {
    suma = suma + entre;
    entre = entre + 1;
    }
  printf ("La suma és %d.\n", suma);

}


He conseguido que sume todos los números, pero no sé como hacer para que sólo sume los múltiples de 5, he provado poniendo "if (entre%5==0)" por allí enmedio pero la liaba y salían cosas raras...

Aparte, creéis que tengo que incluir los 2 números que se ponen? Si no pondría (entre = N1 + 1) y while(entre<=N2-1)

¿Que tendría que hacer?

Gracias de antemano!


Entiendo que los 2 números que pides no están incluidos, así que sería entre N1+1 y N2-1. Este ejercicio iría mejor con un for que con un while, aunque no hay problema con hacerlo a tu modo. Para sumar sólo los múltiplos de 5 has de usar el if que has escrito después, no sé dónde lo habrás puesto para que te salgan cosas raras :P

suma <- 0
A <- teclado
B <- teclado
para i <- A+1 hasta B-1 hacer
   si i es múltiplo de 5 entonces          # if (i%5 == 0){
      suma <- suma + i
   finSi
finPara


He estado pensando la mejor solución de todas para este problema y creo que se puede hacer:

("Suma fórmula de gauss para todos los números hasta limite superior" - "Suma fórmula de gauus para todos los números hasta límite inferior") * 5

la cual seria O(1) ¿Me equivoco? Tendré que comprobarlo, pero ahora no que estoy perezoso.
No tengo muy claro que es eso de Suma de Gauss, pero tirando de mates y no de programación...


Sean i y j los números introducidos y S la suma buscada:

i'=i+5-i%5
j'=j-j%5
#i' y j' son multiplos de 5...

N=(j'-i')/5

S=i'+(i'+5)+(i'+10)+...+(i'+N*5)
S=j'+(j'-5)+(j'-10)+...+(j'-N*5)
2*S=(i'+j')+(i'+j')... N veces
S=N*(i+j)/2

Y listo. Hay que revisar porque no estoy seguro de si debe ser N o (N+1) o (N-1). No se que orden es una operación simplisima, pero seguro que tarda menos que un for :).

Un saludo.
140 respuestas
1, 2, 3