Foros del Web » Programación para mayores de 30 ;) » C/C++ »

[SOLUCIONADO] problema con arreglo de estruturas

Estas en el tema de problema con arreglo de estruturas en el foro de C/C++ en Foros del Web. hola, estoy tratando de hacer esto, y ovbiamente me devuelve un error... alguna sugerencia??? Código: void nuevoAlumno (struct alumno *p){ int i=0; printf("ingrese la edad"); ...
  #1 (permalink)  
Antiguo 13/05/2014, 15:34
 
Fecha de Ingreso: junio-2009
Mensajes: 78
Antigüedad: 14 años, 10 meses
Puntos: 0
problema con arreglo de estruturas

hola, estoy tratando de hacer esto, y ovbiamente me devuelve un error...
alguna sugerencia???

Código:
void nuevoAlumno (struct alumno *p){
int i=0; printf("ingrese la edad"); scanf("%d", &(*(p+i).edad)); getchar();
} int main() {
struct alumno {
int edad; char sexo;
}; struct alumno alumnos[3]; nuevoAlumno(alumnos); return 0;
}
tambien probe con
Código:
scanf("%d", &((p+i)->edad) );
pero tampoco...

los errores devueltos segun el caso son:

error: invalid use of undefined type 'struct alumno'
error: deferencin pointer to incomplete type

desde ya gracias si alguien puede darme una mano
  #2 (permalink)  
Antiguo 13/05/2014, 17:02
 
Fecha de Ingreso: junio-2008
Ubicación: Seattle, USA
Mensajes: 733
Antigüedad: 15 años, 10 meses
Puntos: 61
Respuesta: problema con arreglo de estruturas

La funcion nuevoAlumno recibe como parametro un tipo que no ha sido definido.
El compilador toma las definiciones de arriba hacia abajo, de izquierda a derecha.
No puedes poner el tipo alumno antes de haberlo definido (existen excepciones a esto), pero basicamente es esto lo que el compilador te reclama.

Mueve la definicion de struct alumno antes de la primera vez que la uses y el error (al menos ese) desaparecerá.
__________________
Visita mi perfil en LinkedIn
  #3 (permalink)  
Antiguo 13/05/2014, 18:29
Avatar de vangodp  
Fecha de Ingreso: octubre-2013
Mensajes: 934
Antigüedad: 10 años, 6 meses
Puntos: 38
Respuesta: problema con arreglo de estruturas

ademas poner esto: scanf ( "%d", & ( *( p + i ) ).edad ); en vez de esto: scanf("%d", &(*(p+i).edad));
Código C:
Ver original
  1. #include <stdio.h>
  2.  
  3. struct alumno {
  4.     int edad;
  5.     char sexo; 
  6. };
  7.  
  8. void nuevoAlumno ( struct alumno * p ) {
  9.     int i = 0; 
  10.     printf ( "ingrese la edad" );
  11.     scanf ( "%d", & ( *( p + i ) ).edad  );
  12.     getchar(); 
  13. }
  14.  
  15. int main() {   
  16.     struct alumno alumnos[3];
  17.     nuevoAlumno ( alumnos );
  18.     printf("%d", alumnos[0]);
  19.     return 0;  
  20. }
el cierre cierre de llave tiene que resolver el punter no la edad XD & ( *( p + i ) ).edad

-primero (p+i)
-después (*p).edad
-has echo (*p.edad)
-En todo caso a lo mejor querías hacer: & ( ( *( p + i ) ).edad ); que también funciona ;)

Esto:(*p).edad
Es equivalente a esto: p->edad

version1: scanf ( "%d", & ( ( *( p + i ) ).edad ) );
version2: scanf ( "%d", & ( p->edad ) );
  #4 (permalink)  
Antiguo 13/05/2014, 19:00
Avatar de Drewermerc  
Fecha de Ingreso: febrero-2014
Mensajes: 185
Antigüedad: 10 años, 2 meses
Puntos: 5
Respuesta: problema con arreglo de estruturas

bueno yo solo agrego que para capturar los datos hace fata un for por que si no solo va a capturar uno que sera el de la posicion 0.

saludos.
drewermerc.
  #5 (permalink)  
Antiguo 13/05/2014, 19:52
Avatar de vangodp  
Fecha de Ingreso: octubre-2013
Mensajes: 934
Antigüedad: 10 años, 6 meses
Puntos: 38
Respuesta: problema con arreglo de estruturas

Bueno... pera que he cometido un error XDD..."Otro mas para mi colección XD"

cuando he dicho:
version1: scanf ( "%d", & ( ( *( p + i ) ).edad ) );
version2: scanf ( "%d", & ( p->edad ) );

...quería decir:
version1: scanf ( "%d", & ( ( *( p + i ) ).edad ) );
version2: scanf ( "%d", & (p+i)->edad );
Puedes comprobar cambiando entre los 2 scanf()
Código C:
Ver original
  1. #include <stdio.h>
  2.  
  3. struct alumno {
  4.     int edad;
  5.     char sexo; 
  6. };
  7.  
  8. void nuevoAlumno ( struct alumno * p ) {
  9.     int i = 0; 
  10.     printf ( "ingrese la edad" );
  11.     //scanf ( "%d", & ( ( *( p + i ) ).edad )  );
  12.     scanf ( "%d", & (p+i)->edad );
  13.     getchar(); 
  14. }
  15.  
  16. int main() {   
  17.     struct alumno alumnos[3];
  18.     nuevoAlumno ( alumnos );
  19.     printf("%d", alumnos[0]);
  20.     return 0;  
  21. }

y sry XD
  #6 (permalink)  
Antiguo 13/05/2014, 23:05
Principe_Azul
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: problema con arreglo de estruturas

Cita:
Esto:(*p).edad
Es equivalente a esto: p->edad

version1: scanf ( "%d", & ( ( *( p + i ) ).edad ) );
version2: scanf ( "%d", & (p+i)->edad );
Hola, no sabía que el -> era lo mismo que hacer *, osea es un puntero, buen dato. Gracias!!
  #7 (permalink)  
Antiguo 14/05/2014, 04:17
 
Fecha de Ingreso: junio-2009
Mensajes: 78
Antigüedad: 14 años, 10 meses
Puntos: 0
Respuesta: problema con arreglo de estruturas

muchas gracias a todos, me fueron de mucha ayuda... =)

efectivamente el problema estaba en que no declaraba la estructura al comienzo...

saludos, y muchas gracias nuevamente
  #8 (permalink)  
Antiguo 14/05/2014, 07:34
Avatar de vangodp  
Fecha de Ingreso: octubre-2013
Mensajes: 934
Antigüedad: 10 años, 6 meses
Puntos: 38
Respuesta: problema con arreglo de estruturas

Cita:
Iniciado por Principe_Azul Ver Mensaje
Hola, no sabía que el -> era lo mismo que hacer *, osea es un puntero, buen dato. Gracias!!
Cita:
no sabía que el -> era lo mismo
A ver realmente no son lo mismo eso es lo que son:

(*p).edad = 1; // Desreferenciar y acceder al campo edad.
p->edad = 2; // Acceso al campo edad con el operador flecha.

no puedes crear un puntero así:

int -> p; ni hacer ninguna otra cosa que sea para acceder al contenido desde el puntero

Esto es un puntero * y eso -> solo te permite acceder con -> a un campo desde un puntero ;)

Bueno esto no lo entenderías sin un código así que aquí va XD
Código C:
Ver original
  1. #include <stdio.h>
  2.  
  3. struct alumno {
  4.     int edad;
  5.     char sexo; 
  6. };
  7.  
  8.  
  9. int main() {
  10.        
  11.     struct alumno unAlumno;  // Creamos una estructura tipo alumno y la llamamos unAlumno.
  12.     struct alumno * p;       // Creamos un puntero tipo alumno y lo llamamos p.
  13.  
  14.     unAlumno->edad = 10; //Veras que esta linea da error, ponga el // delante para que compile.
  15.     //La linea anterior da error por que unAlumno no es un puntero, solo puedes usar -> para acceder
  16.     //al campo edad desde un puntero.
  17.    
  18.     p = &unAlumno;   // Asociamos unAlumno con el puntero p
  19.     p->edad = 10;    // Ahora si podemos acceder desde p al campo edad con el operador ->
  20.    
  21.     *p.edad = 20;    // Tampoco puedes hacer esto. Para que funcione ponga el // delante.
  22.     (*p).edad = 20;  // Pero si obligas primero que se desreferencie con los operadores () ¡¡¡Funciona!!!
  23.     //Al poner () en *p "(*p)" es como decir "Primero desreferencie y después acceda a la variable edad"
  24.     //-> quiere decir accede al campo edad;
  25.     //Por tanto (*p).edad y p->edad hacen lo mismo pero no son exactamente lo mismo ;)
  26.     return 0;  
  27. }
Intenta compilar esto.
Te va tirar error en algunas lineas y es que lo hice a propósito para que veas el funcionamiento de (*p).edad y p->edad.
En la linea que tire error ponga // delante a efecto de convertir la linea en comentario.
Observe el error emitido por el compilador y la linea donde esta el error.

Las lineas que van a dar error son linea 14 y 21, es solo para que veas.
En la linea 14 intento acceder a el campo edad con el operador -> desde un objeto alumno, Como es un objeto y no un puntero pues FAIL XD
Luego veras el -> trabajando desde un puntero.
Y por ultimo se ve la similitud que tienen (*p) y p->
-> nos viene mejor que (*p) por razones obvias..¿Que es mas fácil?:
p->edad;
o
(*p).edad;

No se tu me parece que -> es mas fácil
Así que si pasas un puntero a una función o lo que sea puedes usar el -> para acceder a sus campos dentro de dicha función, esto esta a la orden del día en c++ ;)
Entender como funciona las cosas es mejor que suponer, y no soy tan fiera en los punteros pero si quieres un consejo, gástate tiempo en entenderlos por que solo así vas a lograr dominar c/c++ ;)

Si alguien quiere seguir aportando información o ve algo malo, me encanta aprender :D

Última edición por vangodp; 14/05/2014 a las 07:41
  #9 (permalink)  
Antiguo 14/05/2014, 08:14
 
Fecha de Ingreso: junio-2008
Ubicación: Seattle, USA
Mensajes: 733
Antigüedad: 15 años, 10 meses
Puntos: 61
Respuesta: problema con arreglo de estruturas

Tanto *p.campo como (*p).campo podrian ser validos, si "p" y "campo" son punteros a algo. No es el caso del ejemplo, pero creo que es bueno aclarar por qué funciona así.

Hay que considerar la precedencia de los operadores: en C el paréntesis tiene máxima precedencia, el punto tiene mas precedencia que el operador de desreferenciación "*".

En esta expresión:
*p.campo
el punto actúa antes que el "*".
En los ejemplos no se quiere esto primero, sino que se quiere desreferenciar primero, por ello (*p).campo hace actuar primero al operador de desreferenciación.
__________________
Visita mi perfil en LinkedIn
  #10 (permalink)  
Antiguo 14/05/2014, 08:19
Avatar de vangodp  
Fecha de Ingreso: octubre-2013
Mensajes: 934
Antigüedad: 10 años, 6 meses
Puntos: 38
Respuesta: problema con arreglo de estruturas

Cita:
Iniciado por CalgaryCorpus Ver Mensaje
Tanto *p.campo como (*p).campo podrian ser validos, si "p" y "campo" son punteros a algo. No es el caso del ejemplo, pero creo que es bueno aclarar por qué funciona así.

Hay que considerar la precedencia de los operadores: en C el paréntesis tiene máxima precedencia, el punto tiene mas precedencia que el operador de desreferenciación "*".

En esta expresión:
*p.campo
el punto actúa antes que el "*".
En los ejemplos no se quiere esto primero, sino que se quiere desreferenciar primero, por ello (*p).campo hace actuar primero al operador de desreferenciación.

Mejor imposible XD
  #11 (permalink)  
Antiguo 14/05/2014, 23:37
Principe_Azul
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: problema con arreglo de estruturas

Ahhh, muy bien, gracias por explicación!!!

Osea el -> es practicamente como hacer p.edad para saber un valor dentro de una estructura

Código C++:
Ver original
  1. struct valores {
  2.     int edad = 20;
  3. } p;

osea, se usa el -> para acceder a valores, tal como lo hace p.edad.
Disculpen si entendí mal.

Gracias nuevamente.
  #12 (permalink)  
Antiguo 15/05/2014, 05:44
Avatar de vangodp  
Fecha de Ingreso: octubre-2013
Mensajes: 934
Antigüedad: 10 años, 6 meses
Puntos: 38
Respuesta: problema con arreglo de estruturas

¡No! Has entendido mal.
En tu caso has creado un objeto de la estructura valores al cual le has llamado llamado p, y en ese caso p no es un puntero sino un objeto.
Es como crear una variable int variable, no tiene nada que ver con un puntero int *puntero = variable;
un puntero es una variable que apunta a otra variable simplemente.
Tu estructura "valores" es una variable ya que puedes cambiar los valores internos asi que una variable seria asi
struct valores {
int edad = 20;
} p;
struct valores * ptr;

ptr = &p;

Con pe accedes asi p.edad; pero con el puntero accedes asi *ptr.edad, ahi es cuando puedes poner el ->.

lo del (*ptr) es por lo que comenta Calgary, es que el operador punto . tiene mas prioridad que el operador * o sea si hago eso *ptr.edad pues puede que el compilador tome eso ptr.edad lo que es un objto no un puntero, ademas nisiquiera existe en nuestro caso lo que puede dar un error del copón XD haciendo eso (*ptr).edad obligamos a que primero se tome en cuenta el puntero después accedemos a edad. En ese caso es mas fácil usar ptr->edad. Es solo pensar... en el caso del objeto p.edad, es mas fácil que p->edad, no tienes sentido que hacer eso, solo si es un puntero y tuvieras que usar *ptr.edad o peor (*p).edad, recuerda lo ;)


Código C++:
Ver original
  1. #include <stdio.h>
  2.  
  3. struct alumno {
  4.     int edad;
  5.     char sexo;
  6. }p;
  7.  
  8.  
  9. int main() {
  10.  
  11.     struct alumno unAlumno;
  12.     struct alumno * ptr;
  13.    
  14.     //unAlumno->edad = 10; //Veras que esta linea da error, ponga el // delante para que compile
  15.    
  16.     ptr = &unAlumno;   // Asociamos unAlumno con el puntero ptr
  17.     ptr->edad = 10;    // Ahora si podemos acceder al campo edad con el operador ->
  18.    
  19.     //*ptr.edad = 20;    // Tampoco puedes hacer esto
  20.     ( *ptr ).edad = 20;  //
  21.    
  22.     p->edad = 100;       //Como ves p no es un puntero sino mas bien un objeto como los es unAlumno
  23.    
  24.     //Esto es un objeto
  25.     //struct alumno unAlumno;
  26.    
  27.     //Esto es un puntero
  28.     //struct alumno * ptr;
  29.    
  30.     //p es un objeto no un puntero. Es como si hiciera eso para crearlo:struct alumno p;
  31.     //para que pe sea un puntero debes crearlo asi: struct alumno * p; entonces despues de asignarle un objeto al que apuntar puedes usar el ->
  32.     //struct alumno {
  33.     //  int edad;
  34.     //  char sexo;
  35.     //} p;
  36.    
  37.     //Si aun no entiendes los punteros debes entenderlos bien, volver a leer una y otra vez hasta comprenderlos.
  38.     //Si tiene dificultades para entenderlos debes practicar bastante con ellos. Pide ayuda en el foro si no entiendes algo.
  39.    
  40.     return 0;
  41. }

Si no entiendes sigue preguntando ;)


Última edición por vangodp; 15/05/2014 a las 05:59
  #13 (permalink)  
Antiguo 15/05/2014, 09:41
Avatar de Drewermerc  
Fecha de Ingreso: febrero-2014
Mensajes: 185
Antigüedad: 10 años, 2 meses
Puntos: 5
Respuesta: problema con arreglo de estruturas

hola amigo.
bueno mira esto es asi.
el operador "->" solo se usa cuando asignas como puntero a una estructuta o la pasas por referencia en funcione entonces hay tambien lo puede usar para poder acceder a los datos.

el ". " solo lo pudes usar para structuras sencillas y manejarlas en ocal osea solo en el main.

bueno aqui te dejo un codigo donde estan las formas en las forms en las que se puede usar este operador y el punto y si analizas con cuidado solo te puse cosas que significan lo mismo soloq ue las puede poner de dirferente manera a esto me refiero con las forma de asignarle nombre a la sestructuras.
bueno con la explicacion de vangodp creo que podras entender todo el codigo.

Código C:
Ver original
  1. #include <stdio.h>
  2. /*ejemplod e estructura con puntero*/
  3. struct ejemplo{
  4.     char *nombre;
  5.     int edad;
  6. };
  7. //estructura simple para  pasar por referencia en una funcion
  8. struct ejemplodos{
  9.     char *nombredos;
  10.     int edaddos;
  11. }datoss;
  12.  
  13. void ejemplouno(struct ejemplo *puntero);
  14. void ejemplodos(struct ejemplodos *datoss);
  15. int main ()
  16. {
  17.     struct ejemplo datos, *puntero;
  18.     puntero = &datos;
  19.     puntero->nombre = "persona uno";
  20.     puntero->edad= 25;
  21.     printf("\n\nnombre: %s\n edad:%d\n", puntero->nombre, puntero->edad);
  22.        
  23.     ejemplouno(puntero);
  24.  
  25.     datoss.nombredos= "persona en local y estructura simple";
  26.     datoss.edaddos= 35;
  27.     printf("\n\nnombre: %s\n edad:%d\n", datoss.nombredos, datoss.edaddos);
  28.     //se pasa los valores de datoss pero se le hace referencia ala direccion de memoria para poder trabar con ellos de la funcion
  29.     ejemplodos(&datoss);
  30.    
  31. }
  32.  
  33. void ejemplouno(struct ejemplo *puntero)
  34. {
  35.     puntero->nombre = "ejemplo";
  36.     puntero->edad= 15;
  37.     printf("\n\nnombre: %s\n edad:%d\n", puntero->nombre, puntero->edad);
  38. }
  39.  
  40. void ejemplodos(struct ejemplodos *datoss)
  41. {
  42.     datoss->nombredos= "persona dos";
  43.     datoss->edaddos= 25;
  44.     printf("\n\nnombre: %s\n edad:%d\n", datoss->nombredos, datoss->edaddos);
  45.     /* pudes probar descomentando esto para que vea que no se puede usar elpunte mas que en local.
  46.     datoss.nombredos= "persona en local y estructura simple";
  47.     datoss.edaddos= 35;
  48.     printf("\n\nnombre: %s\n edad:%d\n", datoss.nombredos, datoss.edaddos);*/
  49. }

bueno espero qe te sirva.
saludos.
drewermerc.
  #14 (permalink)  
Antiguo 15/05/2014, 10:24
Principe_Azul
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: problema con arreglo de estruturas

Bien! Muchas gracias por tu ayuda vangodp y Drewermerc!!!

Código C++:
Ver original
  1. struct valores {
  2.     int edad = 20;
  3. } p;
  4.  
  5. struct valores * ptr;
  6.  
  7. ptr = &p;

Lo que entiendo ahí es que se crea un puntero de nombre "ptr" que apunta hacia la estructura "valores" (para tomar su valor), y al final "ptr" toma el valor por referencia de la estructura "valores"
¿Es esto correcto?

En el ejemplo del amigo Drewermerc:

Código C++:
Ver original
  1. void ejemplouno(struct ejemplo *puntero);

ahí se crea una función que toma como parámetro el puntero de nombre "puntero", osea, hay que usar el "struct NombreDeEsctructura" cuando se quiere referir a una estructura. Verdad?

Muchas gracias a los 2 por sus ayudas, se valora!!
  #15 (permalink)  
Antiguo 15/05/2014, 10:52
Avatar de Drewermerc  
Fecha de Ingreso: febrero-2014
Mensajes: 185
Antigüedad: 10 años, 2 meses
Puntos: 5
Respuesta: problema con arreglo de estruturas

hola Principe_Azul.

si eso se hacer mas quenada para inicializar el punter ya que si no lo haces te puede arrjar errores a la hora de compilar.

y si es la funcion se tiene que indicar el tipo de dato que se va a resivir en este caso se le indica que el dto que se debe resivir es de tipo estructura.

bueno si se tiene que poner el nombre de la estructura que se hace referencia lo que si puede cambiar el el nombre del puntero.

Código C:
Ver original
  1. //podria ser asi
  2. void ejemplodos(struct ejemplodos *datoss)
  3. //o si, es lo mismo el programa va a funciona
  4. void ejemplodos(struct ejemplodos *d)
  5.  /* pero si lo pones asi, dara un error ya que no has definido ninguna estructura  con el nombre ejem*/
  6. void ejemplodos(struct ejem *d)
saludos.
Drewermerc.
  #16 (permalink)  
Antiguo 16/05/2014, 14:18
Principe_Azul
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: problema con arreglo de estruturas

Muchas gracias Drewermerc, muy cláros tus ejemplos, gracias amigo!!

Etiquetas: arreglo, int
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 14:54.