[C] Problema con Arrays.

Iniciado por edr89, 25 Mayo 2013, 03:01 AM

0 Miembros y 1 Visitante están viendo este tema.

edr89

Hola,
estoy revisando el tema de arreglos y necesito crear un programa que calcule el promedio de 5 calificaciones tecleadas, esto va por alumno. Creo que el problema esta en los renglones 29, 30.

Al final cuando imprime el promedio del alumno 1, alumno 2 etc, solamente el primer dato es correcto, los demas no, imagino que estoy asignando mal los valores a cada variable del arreglo alumno[r].

Mi idea es la sig: Se ingresan las 5 calificaciones que se suman y guardan en califsum, despues se calcula el promedio de dichos datos y se almacena el resultado en alumno[n], al final se tienen los promedios de 10 alumnos en el arreglo. Tambien debo obtener el promedio general, pero no se como trabajar los elementos de un arreglo (en general para sumar, restar,etc)

#include <stdio.h>

main()
{
    int i=0,j,k=1,r=0,alu=1,calif=0,califsum=0,respuesta=0;
    float califprom=0,alumno[10]={0};
    printf("Cuantos alumnos quieres registrar?: ");
    scanf("%d,",&respuesta); //El numero de alumnos esta contenido en respuesta
    while(respuesta>10)
    {
        printf("El sistema no permite registrar mas de 10 alumnos por sesion.\n");
        printf("Cuantos alumnos quieres registrar?: ");
        scanf("%d,",&respuesta); //El numero de alumnos esta contenido en respuesta
    }
    for(i=0;i<respuesta;i++) //Bucle para el numero de alumnos
    {
        j=0;
        printf("Teclea las calificaciones del alumno %d:\n",i+1);
        while(j<5) //Bucle por 5 calificaciones
        {
            printf("%d. ",k); //Se imprime el numero de calificacion 1. 2. 3. etc.
            scanf("%d",&calif);
            califsum+= calif;
            k++;
            j++;
        }
        k=1;
        califprom = califsum / 5;
        alumno[r] = califprom;
        r++;
    }
    printf("\nDetalle de calificaciones:\n\n");
    r=0;
    while(alu<=respuesta)
    {
        printf("Promedio Alumno %d: %.2f\n",alu,alumno[r]);
        alu++;
        r++;
    }
}


¿Se pueden imprimir incrementos ++ en printf()? en la linea 18 por ejemplo tuve que modificar porque al tener i++ las cosas no funcionaban:
printf("Teclea las calificaciones del alumno %d:\n",i++);

espero entiendan lo que trato de hacer,
saludos!

edr89

#1
Se reinician variables en renglones 31,32, ahora da el promedio correcto para todos los alumnos. El detalle del incremento ++ no lo termino de entender.

Para el promedio general defino algo similar, suma de alumno[n] y voy incrementando n de uno en uno.

#include <stdio.h>

main()
{
    int i=0,j,k=1,r=0,s=0,alu=1,calif=0,califsum=0,respuesta=0;
    float califprom=0,alumno[10]={0},sumgral=0,promgral=0;
    printf("Cuantos alumnos quieres registrar?: ");
    scanf("%d,",&respuesta); //El numero de alumnos esta contenido en respuesta
    while(respuesta>10)
    {
        printf("El sistema no permite registrar mas de 10 alumnos por sesion.\n");
        printf("Cuantos alumnos quieres registrar?: ");
        scanf("%d,",&respuesta);
    }
    for(i=0;i<respuesta;i++) //Bucle para el numero de alumnos
    {
        j=0;
        printf("Teclea las calificaciones del alumno %d:\n",i+1);
        while(j<5) //Bucle por 5 calificaciones
        {
            printf("%d. ",k); //Se imprime el numero de calificacion 1. 2. 3. etc.
            scanf("%d",&calif);
            califsum+= calif;
            k++;
            j++;
        }
        k=1;
        califprom = califsum / 5;
        alumno[r] = califprom;
        r+=1;
        califprom = 0;
        califsum = 0;
    }
    printf("\nDetalle:\n\n");
    r=0;
    while(alu<=respuesta)
    {
        printf("Promedio Alumno %d: %.2f\n",alu,alumno[r]);
        alu++;
        r+=1;
    }
    r=0;
    while(s<respuesta) //Se suman los promedios de cada alumno.
    {
        sumgral+= alumno[r];
        r+=1;
        s+=1;
    }
    promgral = sumgral / respuesta;
    printf("\nPromedio general: %.2f",promgral);
}

Al tratar de editar el post el código anterior me aparece distinto, con signos, por eso creo otro mensaje.
Saludos!

leosansan

#2
Cita de: edr89 en 25 Mayo 2013, 03:35 AM
....................................
El detalle del incremento ++ no lo termino de entender.


Sencillamente incrementa en una unidad el valor de la variable, Por ejemplo i++ = i+1.

Te dejo un código con "for". Es un bucle lógico y más claro que while cuando se conoce el rango de valores, como es tu caso, ya que conoces de antemano el número de alumnos y notas que vas a introducir.

Por otro lado, la función main debe ser declarada cono int con su correspondiente return.

No necesitas de un bucle exclusivo para calcular alumno[r], que yo llamo suma_medias, me parece que el nombre hace mejor referencia a la variable que cacula.

En fin, el código está bastante bien, pero para mi gusto los while lo hacen menos entendible:


Código (cpp) [Seleccionar]
#include <stdio.h>
int main()
{
   int i=0,j=0,n=0;
   float media_alumno[10]={0},nota=0,suma_medias=0,sum_notas=0;
   printf("Cuantos alumnos quieres registrar?: ");
   do{
       scanf("%d,",&n);
       if(n>10)
       {
           printf("El sistema no permite registrar mas de 10 alumnos por sesion.\n");
           printf("Cuantos alumnos quieres registrar?: ");
           scanf(" %d,",&n);
       }
   }while(n>10);
   for(i=0;i<n;i++)
   {
       for(j=0;j<5;j++)
       {
           printf("Teclea la nota %d del alumno %d:",j+1,i+1);
           do{
               scanf(" %f",&nota);
               if(nota>10 || nota<0)
               {
                   printf("La nota ha de ser entre 0 y 10.\n");
                   printf("Vuelva a teclear la nota %d  del alumno %d:",j+1,i+1);
                   scanf(" %f,",&nota);
               }
           }while(nota>10 || nota<0);
           sum_notas+=n;
       }
       puts ("");
       media_alumno[i]=sum_notas/5.;
       suma_medias+=media_alumno[i];
   }
       puts ("");
       for(i=0;i<n;i++)
            printf("Promedio Alumno %d: %.2f\n",i+1,media_alumno[i]);
       printf("\n\nPomedio general: %.2f\n\n",suma_medias/2.);
       return0;


Saluditos! .... ..

edr89

Cita de: leosansan en 25 Mayo 2013, 08:06 AM
Sencillamente incrementa en una unidad el valor de la variable, Por ejemplo i++ = i+1.
Eso me queda claro pero cuando utilizo printf y hago referencia a la variable como i++, no imprime el incremento, por eso utilice i+1, a veces en los bucles tampoco me respetaba i++ y no incrementaba. Tambien utilizo i+=1 porque no me da problemas al correr el programa.

Cita de: leosansan en 25 Mayo 2013, 08:06 AMPor otro lado, la función main debe ser declarada cono int con su correspondiente return.

Porqué? :huh:
Entiendo que si divido el código en distintas funciones, el bloque de promedio individual, por ejemplo,  debe regresar el valor de las operaciones realizadas, entonces se regresa el valor de X para que en la funcion main() se haga uso del dato.

promedioind(int x)
{
return x;
}


En el caso de mi código, qué pasa si no regreso valor?, aun no llego a la parte de declarar tipo de funciones, los tipos de return y sus usos. Lei por ahi que return 0; indica que el programa termino sin errores, a medida que el valor cambia es porque termina de cierta forma.

Cita de: leosansan en 25 Mayo 2013, 08:06 AM
No necesitas de un bucle exclusivo para calcular alumno[r], que yo llamo suma_medias, me parece que el nombre hace mejor referencia a la variable que calcula.
Reviso con tiempo tus modificaciones, parece mas eficiente, menos variables y lineas de código, el programa en si ya esta listo solo me falta hacer el algoritmo   :(

Cita de: leosansan en 25 Mayo 2013, 08:06 AMEn fin, el código está bastante bien, pero para mi gusto los while lo hacen menos entendible
Gracias, utilizo while por que es lo que mas he practicado, empiezo a familiarizarme con for y estoy tratando de aplicar todo (while, do-while, for,switch e ifs) pero al usar arrays me confunde un poco. (Es cuestion de seguir practicando porque tambien estoy aprendiendo arrays en 1 dimension, en fin, lo basico de lo basico).


Saludos!

leosansan

#4
Cita de: edr89 en 27 Mayo 2013, 00:40 AM
Eso me queda claro pero cuando utilizo printf y hago referencia a la variable como i++, no imprime el incremento, por eso utilice i+1, a veces en los bucles tampoco me respetaba i++ y no incrementaba. También utilizo i+=1 porque no me da problemas al correr el programa

Porqué? :huh:


La explicación es sencilla .La forma i++ es un incremento a posteriori, es decir se incrementará el valor de la variable en la siguiente instrucción donde aparezca i
Entiendo que si divido el código en distintas funciones, el bloque de promedio individual, por ejemplo,  debe regresar el valor de las operaciones realizadas, entonces se regresa el valor de X para que en la función main() se haga uso del dato. Lo mismo le sucede a ++i, que representa un incremento de una unidad a anterior'.

Para que lo veas con un ejemplo.El siguiente código:


Código (cpp) [Seleccionar]
#include <stdio.h>

int main()
{

   int i;
   for (i=0;i<5;i++)
   {
       printf ("i = %d   ",i);
       printf ("i++= %d   ",i++);
       printf ("++i= %d   ",++i);
   }
   return 0;
}


tiene como salida:

Código (cpp) [Seleccionar]

i = 0   i++= 0   ++i= 2   i = 3   i++= 3   ++i= 5


¿Qué ha pasado?:
* en el for toma el valor inicial cero y empiezan actuar las instrucciones del cuerpo

* El primer printf imprime i, que es cero.

* El segundo printf se encuentra con i++ por lo que no incrementa i en ese momento, imprime por lo tanto el valor de i que sigue siendo cero, pero ya para la siguiente instrucción se incrementará i en una unidad.

* El tercer printf se encuentra con ++i, por lo que imprimirá 2, una unidad de incremento que viene del anterior printf debido al i++ y otra unidad debida al pre incremento del ++i de ese tercer printf.

* Como se acabaron las instrucciones actúa el for incrementando la i, que pasará de 2 a 3.

* Vuelve a entrar en el cuerpo del if y el primer printf imprime i que será 3.

* Actúa el segundo printf, que como post incrementa, en ese momento no varía el valor de i e imprime 3.

*Y por último actúa el tercer printf que con el incremento del anterior printf y el pre incremento del suyo hace que i valga 5, que es lo que imprime.


Cita de: edr89 en 27 Mayo 2013, 00:40 AM]
promedioind(int x)
{
return x;
}


Como la función retorna un valor int debe ser también de tipo int, es decir lo correcto es poner:


int promedioind(int x)
{
   return x;
}

Cita de: edr89 en 27 Mayo 2013, 00:40 AM]
En el caso de mi código, qué pasa si no regreso valor?,


En el caso de que no retorna nada es de tipo void, Por ejemplo, la siguiente función se limita a imprimir sin retornar ningún valor, por eso se declara como tipo void:

Código (cpp) [Seleccionar]

void imprimir (int x)
{
   printf ("%d",x);
}


Espero haberme explicado con meridiana claridad al menos. :-)

Saluditos!. ... ..

edr89

Entendido, para imprimir numeros consecutivos, del 1 al 5 etc, debo usar
for (i=0;i<5;i++)
printf("%d.\n",++j);


donde j vale 0 y se imprime 1,2,3,4,5.
Para que imprima el incremento en la misma instruccion uso ++j, para imprimir en el incremento en la siguiente instruccion uso j++.

hay algo que no entiendo, en el ejemplo trivial se imprime:
Citari = 0   i++= 0   ++i= 2   i = 3   i++= 3   ++i= 5
al principio pense que se iba a imprimir 15 veces(5 del bucle por 3printfs), pero los incrementos en printf se guardan en la variable, entonces el bucle no corre 5 veces porque el valor de 5 se alcanza antes.

Si regresamos al codigo de notas el incremento en j trabaja diferente, lo trato de asociar asi:
for(j=0;j<5;j++) //Bucle para las 5 calificaciones
       {
           printf("Teclea la nota %d del alumno %d:",j+1,i+1);
           do{
               scanf(" %f",&nota);
               if(nota>10 || nota<0)
               {
                   printf("La nota ha de ser entre 0 y 10.\n");
                   printf("Vuelva a teclear la nota %d  del alumno %d:",j+1,i+1);
                   scanf(" %f,",&nota);
               }
           }while(nota>10 || nota<0);
           sum_notas+=nota;
       }

1. Valor inicial de j = 0
2. en el primer printf j=1
3. tercer printf j = 2?

es decir cuando la nota esta fuera de rango se imprime 1 de nuevo: "Vuelva a teclear la nota 1 del alumno 1". ¿por que en el ejemplo trivial i incrementa y se queda con ese nuevo valor?, para este otro caso j tiene el mismo valor, me explico?

Respecto a definir el tipo de funcion, mi duda es si da error cuando main() no es de algun tipo, en este caso el programa corre, da los promedios por alumno, el general, no parece haber fallas, si defino int main() y termino con return 0;

Qué sucede con el programa?
En general como puedo saber que tal o cual funcion debe ser de algun tipo y regresar algun valor.

Saludos!

leosansan

#6
Cita de: edr89 en 27 Mayo 2013, 19:43 PM
Entendido, para imprimir numeros consecutivos, del 1 al 5 etc, debo usar
for (i=0;i<5;i++)
printf("%d.\n",++j);

donde j vale 0 y se imprime 1,2,3,4,5.

Pero no te compliques la vida, si sólo se trata de imprimir, otra cosa sería que estuviésemos rellenando un array, puedes hacer:

Código (cpp) [Seleccionar]
for (i=1;i<6;i++)
.......


Citar

Para que imprima el incremento en la misma instruccion uso ++j, para imprimir en el incremento en la siguiente instruccion uso j++.


O:K

Citar
hay algo que no entiendo, en el ejemplo trivial se imprime:al principio pense que se iba a imprimir 15 veces(5 del bucle por 3printfs), pero los incrementos en printf se guardan en la variable, entonces el bucle no corre 5 veces porque el valor de 5 se alcanza antes.

Tu mismo lo has dicho, al incrementar la i se acaba el bucle aparentemente antes de tiempo, porque en realidad no es que el bucle "tenga" que repetirse cinco veces, sino que se repite hasta que se cumple la condición de lo que viene después del primer punto y coma.

Citar
Si regresamos al codigo de notas el incremento en j trabaja diferente, lo trato de asociar asi:
for(j=0;j<5;j++) //Bucle para las 5 calificaciones
      {
          printf("Teclea la nota %d del alumno %d:",j+1,i+1);
          do{
              scanf(" %f",&nota);
              if(nota>10 || nota<0)
              {
                  printf("La nota ha de ser entre 0 y 10.\n");
                  printf("Vuelva a teclear la nota %d  del alumno %d:",j+1,i+1);
                  scanf(" %f,",&nota);
              }
          }while(nota>10 || nota<0);
          sum_notas+=nota;
      }

1. Valor inicial de j = 0
2. en el primer printf j=1
3. tercer printf j = 2?

Fíijate que no he usado ni pre ni post incremento, sino el valor de la variable más uno y como los dos printf están en el cuerpo del for j no varía su valor, es decir:

1. Valor inicial de j = 0
2. en el primer printf:  j+1=1
3. en el segundo : j +1=1

Citar

Respecto a definir el tipo de funcion, mi duda es si da error cuando main() no es de algun tipo, en este caso el programa corre, da los promedios por alumno, el general, no parece haber fallas, si defino int main() y termino con return 0;

Qué sucede con el programa?
En general como puedo saber que tal o cual funcion debe ser de algun tipo y regresar algun valor.

Respecto al tipo de función de main es que está establecido, por lo que yo tengo entendido, como int, lo cual no quiere decir que si no pones int ni return 0 te pueda compilar bien. Pero eso ya dependerá del compilador, puedes encontrarte con alguno que no te permita compilar sin esas condiciones.

Y respecto al tipo de función es el programador el que al construir la función sabe si va a devolver un int un float,.... o nada, y en función de ello le pone el tipo. Es decir tú cuando construyes la función debes saber de antemano qué va a hacer y que va a devolver y en función de eso pones el tipo a la función.


Saluditos. .... ...