C/Visual C - ERROR ARRAY DE ESTRUCTURAS

   
Vista:

ERROR ARRAY DE ESTRUCTURAS

Publicado por Pablo (3 intervenciones) el 18/05/2013 19:15:54
Buenas tardes.

Tengo el siguiente código:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include <stdio.h>
#include <stdlib.h>
 
typedef struct
{
	char nombre[10];
	int  edad;
} Persona;
 
int leerContactos(void);
Persona* crearListin(int n);
int leerListin(Persona* p, int n);
int escribirListin(Persona* p, int n);
 
int main(void)
{
	Persona* 	p;
	int			contactos;
	int			error;
 
	contactos = leerContactos();
	if(contactos < 1)
	{
		printf("Error al introducir nº de contactos");
	}
	else
	{
		p = crearListin(contactos);
		if(p == NULL)
		{
			printf("No hay espacio en memoria para almacenar los contactos");
		}
		else
		{
			error = leerListin(p,contactos);
			if(error < 0)
			{
				printf("Error al introducir los datos");
			}
			else
			{
				/*printf("%s (%d)",(p+1)->nombre,(p+1)->edad);*/
				escribirListin(p,contactos);
			}
			free(p);
		}
	}
	return (0);
}
 
/*--------------------------------------------------------------------*/
int leerContactos(void)
{
	int n;
 
	printf("Introduzca el nº de contactos a leer: ");
	scanf("%d",&n);
 
	return (n);
}
 
Persona* crearListin(int n)
{
	return (Persona*) malloc(n*sizeof(Persona));
}
 
int leerListin(Persona* p, int n)
{
	int i;
 
	for(i=0; i<n; i++)
	{
		printf("Introduzca el nombre = ");
		/*scanf("%s",&(p[i].nombre));*/
		scanf("%s",(p+i)->nombre);
		printf("Introduzca la edad = ");
		/*scanf("%d",&(p[i].edad));*/
		scanf("%d",(p+i)->edad);
	}
}
 
int escribirListin(Persona* p, int n)
{
	int i;
 
	for (i=0; i<n; i++)
	{
		printf("%s ",(p+i)->nombre);
		printf("(%d)\n",p[i].edad);
	}
}
 
Pues bien. En la función leerListin
 
int leerListin(Persona* p, int n)
{
	int i;
 
	for(i=0; i<n; i++)
	{
		printf("Introduzca el nombre = ");
		/*scanf("%s",&(p[i].nombre));*/
		scanf("%s",(p+i)->nombre);
		printf("Introduzca la edad = ");
		/*scanf("%d",&(p[i].edad));*/
		scanf("%d",(p+i)->edad);
	}
}


si utilizo las sentencias comentadas no tengo problemas, pero me gustaría como podría traducirse utilizando aritmética de punteros. Tengo que p == &p[0] y (p+i) == &p[i], también tengo que *(p+i) == p[i], pero lo que no llego a encontrar es la relación entre XXXX == &(p[i].campo).

Gracias.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

ERROR ARRAY DE ESTRUCTURAS

Publicado por Pablo (3 intervenciones) el 18/05/2013 19:54:14
Ya he encontrado la forma.

&((p+i)->campo)

aunque me desconcierta un poco, ya que si (p+i) == &p[i], me esperaba que debía ser algo así como (p+i)->campo o (p+i).campo.

Si alguien puediera explicarlo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

ERROR ARRAY DE ESTRUCTURAS

Publicado por Chema (187 intervenciones) el 18/05/2013 23:21:49
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SIZE_NAME 24
 
typedef struct Persona {
	int edad;
	char nombre[SIZE_NAME];
}Persona;
 
typedef struct Agenda {
	int num;
	int size;
	Persona *psn;
}Agenda;
 
 
static Agenda* crearListin(int n);
static void InsertField(Agenda *agd, Persona *psn);
static void PrintAgenda(Agenda *agd) ;
 
Agenda *crearListin(int num) {
	Agenda *agd;
	agd = malloc(sizeof(Agenda));
	agd->psn =  malloc(num*sizeof(Persona));
	agd->num =0;
	agd->size = num;
	return agd;
}
 
void InsertField(Agenda *agd, Persona *psn) {
	if(agd->size <=0)
		return;
	/*
	 * Ojo a *psn, es la respuesta a tu pregunta
	 */	
	agd->psn[agd->num] = *psn;
	agd->num +=1;
	agd->size -=1;
}
 
void PrintAgenda(Agenda *agd) {
	int i;
	for(i=0 ; i < agd->num; i++){
		printf("Edad:=%d  Nombre:  %s \n",agd->psn[i].edad, agd->psn[i].nombre);
	}
}
 
int main(void) {
	int i,x;
	Agenda *agd;
	Persona psn;
	srand (time(NULL));
	agd = crearListin(10);
 
	for(i=0 ; i < 10; i++){
		for(x=0 ; x< SIZE_NAME -1; x++){
			psn.nombre[x]=( (rand() % 26)+97);
		}
			psn.nombre[x]=0x0;
			psn.edad = rand() % 100+1;
			InsertField(agd,&psn);
	}
 
	PrintAgenda(agd);
	free(agd->psn);
	free(agd);
	return (0);
}
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

ERROR ARRAY DE ESTRUCTURAS

Publicado por Tom (481 intervenciones) el 20/05/2013 17:11:06
Partiendo de:

1
Persona *p;

Cuando haces
p = malloc()
creas una zona contigua de memoria en la que caben n estructuras Persona. la variable p apunta al inicio de esa zona.

Así, (p + i) devuelve una dirección de memoria que el compilador interpreta como (p + (i * sizeof(Persona)); ya que p es un puntero a Persona.

así que (p + i) sigue siendo un puntero. Para dereferenciarlo usarás & o ->

En tu caso, podrías usar (p + i)->campo

p[i] es exactamente lo mismo, salvo que el compilador ya lo dereferencia como una struct (o sea p[i] es (*(p + i))).

Entonces, estas 3 expresiones hacen lo mismo:

1
2
3
(p + 1)->edad = 11;
	p[1].edad = 11;
	(*(p + 1)).edad = 11;


Con el campo nombre tienes otro puntero adicional, ya que nombre es un puntero que apunta a una zona de tamaño 10. Aunque eso es precisamente lo que espera scanf, así que podrías hacer:

1
2
scanf("%s", (pp + 1)->nombre);
	scanf("%d", &((pp + 1)->edad));


Respecto a la última pregunta, &(p[i].campo) es la dirección en la que se sitúa el valor campo de la estructura numero i. O sea, es un type_of(campo)*

En realidad se calcula como p + (i * sizeof(struct Persona)) + _offsetof(struct Persona, "campo"). Y su tipo, depende de campo, claro (puede ser un int * si campo es edad, en tu ejemplo, o un char* si es nombre.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar