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

Problema de principiante con struct en C

Estas en el tema de Problema de principiante con struct en C en el foro de C/C++ en Foros del Web. Hola, estoy practicando con struct en C y tengo algunas dudas de principiante. He realizado este pequeño código para entenderlo, pero aún así tengo algunos ...
  #1 (permalink)  
Antiguo 15/12/2010, 10:30
 
Fecha de Ingreso: octubre-2006
Mensajes: 169
Antigüedad: 17 años, 6 meses
Puntos: 2
Problema de principiante con struct en C

Hola,

estoy practicando con struct en C y tengo algunas dudas de principiante. He realizado este pequeño código para entenderlo, pero aún así tengo algunos problemas.

1.- Por un lado parece que struct se asemeja "prehistóricamente" a lo que serían las clases y las variables de struct los objetos. No sé si alguien que conozca la historia de la programación puede confirmar esto.

2.- Entiendo que en las estructuras anidadas que he puesto en el código, tienes que acceder a cualquier miembro desde la instancia o mejor dicho variable superior que anida las demás. ¿No tendría sentido acceder desde datos[i].edad?

3.- Con las dos maneras que pongo a continuación el compilador da warnings -con la primera error-. ¿Cómo debo hacerlo? ¿O es que no es correcto este acceso palmera.datos[1].nombre?

palmera.datos[1].nombre = "Pablo");
strcpy (palmera.datos[1].nombre, "Pablo");

5.- tNino datos [5]; significa que no podré crear más de cinco alumnos de pero en realidad se puede. ¿A qué se debe?


Gracias.

Código:
/*System header files*/
#include <stdio.h>
#include <stdlib.h>

/*Symbolic constants*/
#define NUM_MAX 5

/*User defined types*/
typedef struct{
	char nombre[NUM_MAX];
	int ano;
	int edad;
} tNino;

typedef struct{
	int id;
	tNino datos [5];	
} tAlumnos;	

tAlumnos palmera;

int main (void)
{
	printf("Hola Mundo\n");
	//palmera.datos[1].nombre = "Pablo");
	strcpy (palmera.datos[1].nombre, "Pablo");
	palmera.datos[1].ano = 2000;
	palmera.datos[1].edad = 10;
	return 0;
}
ERROR "warnings" que da el compilador.

gcc -Wall -c "struct.c" (en el directorio: /home/luis/Descargas)
struct.c:27: warning: implicit declaration of function ‘strcpy’
struct.c:27: warning: implicit declaration of function ‘strcpy’
La compilación a terminado con éxito.

Última edición por luface2000; 15/12/2010 a las 11:14
  #2 (permalink)  
Antiguo 15/12/2010, 11:16
 
Fecha de Ingreso: abril-2010
Ubicación: Rosario
Mensajes: 1.850
Antigüedad: 14 años
Puntos: 228
Respuesta: Problema de principiante con struct en C

el warning se debe a que debes agregar string.h en los includes :
#include <string.h>

Sobre la pregunta historica no tengo idea....pero se puede encontrar cierta correspondencia entre uno y otros...

A la segunda pregunta no le encontre el sentido....si entendes como se anidan y como se acceden que es lo que estas preguntando??
  #3 (permalink)  
Antiguo 15/12/2010, 11:33
Avatar de Munire  
Fecha de Ingreso: julio-2010
Ubicación: en el ciberdespacio (España)
Mensajes: 150
Antigüedad: 13 años, 9 meses
Puntos: 4
Respuesta: Problema de principiante con struct en C

Cita:
1.- Por un lado parece que struct se asemeja "prehistóricamente" a lo que serían las clases y las variables de struct los objetos. No sé si alguien que conozca la historia de la programación puede confirmar esto.
algo se asemeja, pero no es lo mismo. por ejemplo en las clases puedes meter funciones pero en las estructuras no.

Cita:
2.- Entiendo que en las estructuras anidadas que he puesto en el código, tienes que acceder a cualquier miembro desde la instancia o mejor dicho variable superior que anida las demás. ¿No tendría sentido acceder desde datos[i].edad?
no, por que datos esta dentro de "palmera"
esta bien como lo has puesto en el codigo

Cita:
3.- Con las dos maneras que pongo a continuación el compilador da warnings -con la primera error-. ¿Cómo debo hacerlo? ¿O es que no es correcto este acceso palmera.datos[1].nombre?
palmera.datos[1].nombre = "Pablo"); MAL. no se puede hacer asi. tienes que hacerlo copiando letra a letra: palmera.datos[1].nombre[i]
o con la funcion strcpy()

strcpy (palmera.datos[1].nombre, "Pablo"); BIEN, la razon de por que no te funcionaba te la ha dicho sam90



Cita:
5.- tNino datos [5]; significa que no podré crear más de cinco alumnos de pero en realidad se puede. ¿A qué se debe?
tNino datos [5]; significa que has creado 5 estructuras llamadas datos del tipo tNino (con unas variables especificas). si pones tNino datos [6]; creas 6.

tAlumnos palmera; significa que has creado una estructura llamada palmera del tipo tAlumnos. dentro de esa estructura hay un entero "id" y 5 estructuras "datos"
  #4 (permalink)  
Antiguo 15/12/2010, 11:36
 
Fecha de Ingreso: octubre-2006
Mensajes: 169
Antigüedad: 17 años, 6 meses
Puntos: 2
Respuesta: Problema de principiante con struct en C

Gracias por la respuesta. He añadido el #include <string.h> y solucionado. En la segunda pregunta, es un poco ingenua, pero ahí va. Si se instancia la variable palmera de tAlumnos, para acceder a cualquier miembro de las tuplas anidadas hay que hacerlo desde palmera.lo que sea, no tendría sentido el acceso desde datos[i].lo que sea que es una instacia de tNino, ¿es así?.

EDITO= gracias por las respuestas, está todo aclarado, aunque si le pongo como máximo tNino datos [2] y creo 5 niños pues no me da error yeso no lo entiendo, ¿a qué se debe?


Un saludo.
  #5 (permalink)  
Antiguo 15/12/2010, 11:50
Avatar de Munire  
Fecha de Ingreso: julio-2010
Ubicación: en el ciberdespacio (España)
Mensajes: 150
Antigüedad: 13 años, 9 meses
Puntos: 4
Respuesta: Problema de principiante con struct en C

Cita:
Iniciado por luface2000 Ver Mensaje
EDITO= gracias por las respuestas, está todo aclarado, aunque si le pongo como máximo tNino datos [2] y creo 5 niños pues no me da error yeso no lo entiendo, ¿a qué se debe?
no te entiendo, escribenos lo que has puesto.
  #6 (permalink)  
Antiguo 15/12/2010, 12:20
 
Fecha de Ingreso: octubre-2006
Mensajes: 169
Antigüedad: 17 años, 6 meses
Puntos: 2
Respuesta: Problema de principiante con struct en C

El código completo es este

Código:
/*System header files*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*Symbolic constants*/
#define NUM_MAX 5

/*User defined types*/
typedef struct{
	char nombre[NUM_MAX];
	int ano;
	int edad;
} tNino;

typedef struct{
	int id;
	tNino datos [2];	
} tAlumnos;	

tAlumnos palmera;

int main (void)
{
	printf("Hola Mundo\n");
	
	palmera.id = 0;
	strcpy (palmera.datos[0].nombre, "Laura");
	palmera.datos[0].ano = 2000;
	palmera.datos[0].edad = 10;
	printf("Los datos son: ID=%d Nombre=%s Año Nacimiento=%d y Edad=%d\n", palmera.id, palmera.datos[0].nombre, palmera.datos[0].ano, palmera.datos[0].edad);
	
/*PRUEBA*/
	printf("Esto imprime el primer caracter de %s que es = %c\n", palmera.datos[0].nombre, palmera.datos[0].nombre[0]);
	
	palmera.id = 1;
	strcpy (palmera.datos[1].nombre, "Pablo");
	palmera.datos[1].ano = 2003;
	palmera.datos[1].edad = 8;
	printf("Los datos son: ID=%d Nombre=%s Año Nacimiento=%d y Edad=%d\n", palmera.id, palmera.datos[1].nombre, palmera.datos[1].ano, palmera.datos[1].edad);
	
	palmera.id = 2;
	strcpy (palmera.datos[2].nombre, "Pili");
	palmera.datos[2].ano = 1972;
	palmera.datos[2].edad = 38;
	printf("Los datos son: ID=%d Nombre=%s Año Nacimiento=%d y Edad=%d\n", palmera.id, palmera.datos[2].nombre, palmera.datos[2].ano, palmera.datos[2].edad);
	
	palmera.id = 3;
	strcpy (palmera.datos[3].nombre, "Lorenzo");
	palmera.datos[3].ano = 1968;
	palmera.datos[3].edad = 42;
	printf("Los datos son: ID=%d Nombre=%s Año Nacimiento=%d y Edad=%d\n", palmera.id, palmera.datos[3].nombre, palmera.datos[3].ano, palmera.datos[3].edad);
	
	palmera.id = 14;
	strcpy (palmera.datos[14].nombre, "Lorenzo");
	palmera.datos[14].ano = 1968;
	palmera.datos[14].edad = 42;
	printf("Los datos son: ID=%d Nombre=%s Año Nacimiento=%d y Edad=%d\n", palmera.id, palmera.datos[14].nombre, palmera.datos[14].ano, palmera.datos[14].edad);
	return 0;
}
Y funciona todo OK. No entiendo que "instanciando" más de 2 datos de palmera lo acepte sin error.

Gracias.
  #7 (permalink)  
Antiguo 16/12/2010, 02:11
 
Fecha de Ingreso: agosto-2008
Mensajes: 240
Antigüedad: 15 años, 8 meses
Puntos: 6
Respuesta: Problema de principiante con struct en C

Hola, yo declararía la variable tAlumno palmera dentro del propio main(), me explico:

Código C:
Ver original
  1. int main()
  2. {
  3.  
  4. tAlumnos palmera;
  5.  
  6. .....
  7.  
  8. return 0;
  9. }

Puede que os parezca un poco maniático, pero yo diría que es lo correcto.

Por cierto, una dudita que me ha surgido, ¿qué consigues con esta sentencia?
Código C:
Ver original
  1. typedef struct{
  2.     int id;
  3.     tNino datos [2];     // Aquí está mi duda
  4. } tAlumnos;

Un saludo y muchas gracias,
gonzo13
  #8 (permalink)  
Antiguo 16/12/2010, 03:35
 
Fecha de Ingreso: octubre-2006
Mensajes: 169
Antigüedad: 17 años, 6 meses
Puntos: 2
Respuesta: Problema de principiante con struct en C

Hola,

he puesto la variable tAlumno palmera dentro del main y creo que tienes razón, es más purista pero funciona.

Código:
int main (void)
{
	tAlumnos palmera;
En lo segundo que comentas está mi duda.

Código:
typedef struct{
	int id;
	tNino datos [3];	           <--------tabla de tupla
} tAlumnos;
Entiendo que creas un tipo tAlumnos de struct y que albergará una tabla de struct de 3 posiciones en el caso de código que muestro. En la práctica ira la secuencia 0,1,2, es decir tres posiciones. El tema es que cuando ejecutas el programa por pantalla de la consola hace un printf de todos los casos. El tema es que no entiendo como hace la secuencia la tabla. Si es tNino datos[3] debería ser 0,1,2 pero en realidad hace 0,1,2,3. Es lo que no entiendo. Por ejemplo, el que código que pego a continuación

Código:
/*System header files*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*Symbolic constants*/
#define NUM_MAX 5

/*User defined types*/
typedef struct{
	char nombre[NUM_MAX];
	int ano;
	int edad;
} tNino;

typedef struct{
	int id;
	tNino datos [4];	
} tAlumnos;	

int main (void)
{
	tAlumnos palmera;
	printf("Hola Mundo\n");
	
	palmera.id = 0;
	strcpy (palmera.datos[0].nombre, "Laura");
	palmera.datos[0].ano = 2000;
	palmera.datos[0].edad = 10;
	printf("Los datos son: ID=%d Nombre=%s Año Nacimiento=%d y Edad=%d\n", palmera.id, palmera.datos[0].nombre, palmera.datos[0].ano, palmera.datos[0].edad);
	
	printf("Esto imprime el primer caracter de %s que es = %c\n", palmera.datos[0].nombre, palmera.datos[0].nombre[0]);
	
	palmera.id = 1;
	strcpy (palmera.datos[1].nombre, "Pablo");
	palmera.datos[1].ano = 2003;
	palmera.datos[1].edad = 8;
	printf("Los datos son: ID=%d Nombre=%s Año Nacimiento=%d y Edad=%d\n", palmera.id, palmera.datos[1].nombre, palmera.datos[1].ano, palmera.datos[1].edad);
	
	palmera.id = 2;
	strcpy (palmera.datos[2].nombre, "Pili");
	palmera.datos[2].ano = 1972;
	palmera.datos[2].edad = 38;
	printf("Los datos son: ID=%d Nombre=%s Año Nacimiento=%d y Edad=%d\n", palmera.id, palmera.datos[2].nombre, palmera.datos[2].ano, palmera.datos[2].edad);
	
	palmera.id = 3;
	strcpy (palmera.datos[3].nombre, "Lorenzo");
	palmera.datos[3].ano = 1968;
	palmera.datos[3].edad = 42;
	printf("Los datos son: ID=%d Nombre=%s Año Nacimiento=%d y Edad=%d\n", palmera.id, palmera.datos[3].nombre, palmera.datos[3].ano, palmera.datos[3].edad);
	
	palmera.id = 4;
	strcpy (palmera.datos[4].nombre, "Lorenzo");
	palmera.datos[4].ano = 1968;
	palmera.datos[4].edad = 42;
	printf("Los datos son: ID=%d Nombre=%s Año Nacimiento=%d y Edad=%d\n", palmera.id, palmera.datos[4].nombre, palmera.datos[4].ano, palmera.datos[4].edad);
	
	return 0;
}
para tNino datos[4] no da error y son 5 datos, pero si pongo tNino datos[3] el mensaje que muestra en consola es,
Código:
Hola Mundo
Los datos son: ID=0 Nombre=Laura Año Nacimiento=2000 y Edad=10
Esto imprime el primer caracter de Laura que es = L
Los datos son: ID=1 Nombre=Pablo Año Nacimiento=2003 y Edad=8
Los datos son: ID=2 Nombre=Pili Año Nacimiento=1972 y Edad=38
Los datos son: ID=3 Nombre=Lorenzo Año Nacimiento=1968 y Edad=42
Los datos son: ID=4 Nombre=Lorenzo Año Nacimiento=1968 y Edad=42
Segmentation fault

------------------
(program exited with code: 0)
Press return to continue

con lo que rebosa la tabla confirmando lo que digo. ¿Entonces como maneja el inicio y final de esa tabla? Lo siento, es un ladrillo de pregunta.

Gracias.
  #9 (permalink)  
Antiguo 16/12/2010, 06:19
Avatar de Munire  
Fecha de Ingreso: julio-2010
Ubicación: en el ciberdespacio (España)
Mensajes: 150
Antigüedad: 13 años, 9 meses
Puntos: 4
Respuesta: Problema de principiante con struct en C

Cita:
Iniciado por luface2000 Ver Mensaje
Hola,

he puesto la variable tAlumno palmera dentro del main y creo que tienes razón, es más purista pero funciona.



Entiendo que creas un tipo tAlumnos de struct y que albergará una tabla de struct de 3 posiciones en el caso de código que muestro. En la práctica ira la secuencia 0,1,2, es decir tres posiciones. El tema es que cuando ejecutas el programa por pantalla de la consola hace un printf de todos los casos. El tema es que no entiendo como hace la secuencia la tabla. Si es tNino datos[3] debería ser 0,1,2 pero en realidad hace 0,1,2,3. Es lo que no entiendo. Por ejemplo, el que código que pego a continuación


para tNino datos[4] no da error y son 5 datos, pero si pongo tNino datos[3] el mensaje que muestra en consola es,
Código:
Hola Mundo
Los datos son: ID=0 Nombre=Laura Año Nacimiento=2000 y Edad=10
Esto imprime el primer caracter de Laura que es = L
Los datos son: ID=1 Nombre=Pablo Año Nacimiento=2003 y Edad=8
Los datos son: ID=2 Nombre=Pili Año Nacimiento=1972 y Edad=38
Los datos son: ID=3 Nombre=Lorenzo Año Nacimiento=1968 y Edad=42
Los datos son: ID=4 Nombre=Lorenzo Año Nacimiento=1968 y Edad=42
Segmentation fault

------------------
(program exited with code: 0)
Press return to continue

con lo que rebosa la tabla confirmando lo que digo. ¿Entonces como maneja el inicio y final de esa tabla? Lo siento, es un ladrillo de pregunta.

Gracias.
segmentation fault significa violacion de acceso esto quiere decir que estas escribiendo en un area restringida, que no tienes los permisos, por que seguramente ya habra algo escrito ahi.

si creas 3 datos: datos[3]
reservas tantos bytes por 3 (por que son 3 datos)

y si asignas valores a datos 5 por ejemplo_: datos[5].nombre
estas escribiendo en un area que no has reservado pero te deja por que existe.

x0 x1 x2 x3 x4 x5 x6 ..... (espacios de memoria)
_______ (reservas 3)

dato es un puntero al primer elemento. si pones dato[1] es lo mismo que apuntar a dato[0] + 1 , es decir estas escribiendo en el siguiente espacio de memoria.

si escribes en x5 , aunque no lo hayas reservado te deja pero por que se da el caso de que esta vacio, tambien se podria dar el caso de que estuviera ocupado (segmentation fault)
  #10 (permalink)  
Antiguo 16/12/2010, 06:26
 
Fecha de Ingreso: octubre-2006
Mensajes: 169
Antigüedad: 17 años, 6 meses
Puntos: 2
Respuesta: Problema de principiante con struct en C

Todo aclarado.

Muchas gracias por las respuestas.

Etiquetas: principiante
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 20:14.