Autor
|
Tema: Estructuras anidadas, funciones y punteros (Leído 10,743 veces)
|
NathanD
Desconectado
Mensajes: 48
|
Buenas a todos, tengo unas cuantas dudas y espero poder resolverlas con vosotros. Tengo que coger un ejercicio de administración de hoteles, hecho anteriormente, y hacerlo, pero esta vez usando punteros. Por ejemplo, las primeras líneas del .c con main, donde declaro la estructura y la inicializo: HOTELES hotel[NUM_HOTELES]; //3 hoteles /***************/ HOTELES_inicializarHoteles(hotel); //Inicializamos el número de clientes de cada hotel a 0
Dicha función está definida así: void HOTELES_inicializarHoteles(HOTELES hotel[]) { int i; for(i=0; i<NUM_HOTELES; i++) { hotel[i].numero_clientes = 0; } }
Como se trata de reescribir el programa usando punteros, me he limitado a cambiar el parámetro: void HOTELES_inicializarHoteles(HOTELES *hotel)
Pero no consigo hacer nada. Me da error tanto si intento acceder a la posición del hotel con aritmética de punteros *(hotel + i).numero_clientes = 0;
como accediendo a la estructura con el operador "->" hotel[i]->numero_clientes = 0;
(Y haciendo ambas cosas juntas también de da error, claro). En cambio, si en el parámetro de la función defino hotel como indirección doble, sí que debo emplear el operador "->". Pero bueno, que tampoco tengo del todo claro por qué hay que hacerlo así, lo he hecho un poco al tuntún. Además, así da error en ejecución... Mi otra duda es si también debería modificar las estructuras anidadas, es decir, si en el primer ejercicio tengo una estructura dentro de otra de forma "simple", si ahora tengo que anidarlas usando punteros. El tema de los punteros lo tengo claro, cómo y cuándo usar los operadores, direcciones de memoria, etc. Pero ahora con las estructuras no lo tengo nada claro. Gracias de antemano, perdón por el tocho y saludos.
|
|
|
En línea
|
|
|
|
avesudra
Desconectado
Mensajes: 724
Intentando ser mejor cada día :)
|
Sería de gran ayuda que postearas los errores que te dá el compilador. A mí así me funciona perfectamente: #include <stdio.h> #include <stdlib.h> #define NUM_HOTELES 3 /// DEFINICIÓN DE ESTRUCTURAS struct HOTEL { int numero_clientes; }; typedef struct HOTEL HOTELES; /// DECLARACIÓN DE FUNCIONES void HOTELES_inicializarHoteles(HOTELES *hotel); int main (int argc, char *argv []) { HOTELES hotel[NUM_HOTELES]; //3 hoteles HOTELES_inicializarHoteles(hotel); //Inicializamos el número de clientes de cada hotel a 0 return 0; } /// DEFINICIÓN DE FUNCIONES void HOTELES_inicializarHoteles(HOTELES *hotel) { int i; for(i=0; i<NUM_HOTELES; i++) { hotel[i].numero_clientes = 0; } }
Quizás te hayas confundido al declarar las estructuras puesto que se declaran así: [struct] <identificador> <objeto_estructura>
Fuente: http://c.conclase.net/curso/?cap=011Y tu la has declarado sin el struct: HOTELES hotel[NUM_HOTELES];
Eso sí, si has puesto esto en el código no sé de que es el problema: typedef struct HOTEL HOTELES;
¡Un saludo!
|
|
« Última modificación: 17 Marzo 2013, 16:32 pm por avesudra »
|
En línea
|
Regístrate en
|
|
|
NathanD
Desconectado
Mensajes: 48
|
Hola avesudra, gracias por responder. Así lo he hecho funcionar, modificando el parámetro de la función, solamente poniendo * en lugar de []. Pero verás, como se trata de hacer el ejercicios con punteros, asumo que debe de haber más cambios, no algo tan simple como cambiar los parámetros. Como, por ejemplo, acceder a los valores con la notación de punteros en lugar de con la de los arrays, o usando el operador -> en lugar de ., para acceder a las estructuras. Si no me he expresado con claridad sólo tienes que preguntarme Muchas gracias
|
|
|
En línea
|
|
|
|
avesudra
Desconectado
Mensajes: 724
Intentando ser mejor cada día :)
|
--------------------------------------------------------------------------------------------------------------------------------------- El problema es que si desreferencias el puntero a la estructura te quedas con el valor del primer elemento de la estructura(supongo que puede ser el número de clientes o no sé, por eso no puedes acceder a nada, la primera dirección de memoria de una estructura creo que normalmente es su primer elemento, dependiendo de como se organize la memoria...)(que conste que no lo tengo claro): *(hotel + i).numero_clientes = 0;
--------------------------------------------------------------------------------------------------------------------------------------- Retirando lo dicho, es un problema de sintaxis, pues así si sale: (*(hotel + i)).numero_clientes = 0;
Pues así no está mal, lo que pasa es que obviamente tienes que apuntar el puntero a la estructura, que la creo con calloc: #include <stdio.h> #include <stdlib.h> #define NUM_HOTELES 3 /// DEFINICIÓN DE ESTRUCTURAS struct HOTEL { int numero_clientes; }; typedef struct HOTEL HOTELES; /// DECLARACIÓN DE FUNCIONES void HOTELES_inicializarHoteles(HOTELES *hotel); int main (int argc, char *argv []) { HOTELES *hotel; hotel = calloc(NUM_HOTELES ,sizeof(HOTELES ));//3 hoteles HOTELES_inicializarHoteles(hotel); //Inicializamos el número de clientes de cada hotel a 0 return 0; } /// DEFINICIÓN DE FUNCIONES void HOTELES_inicializarHoteles(HOTELES *hotel) { int i; for(i=0; i<NUM_HOTELES; i++) { (hotel+i)->numero_clientes = 0; } }
|
|
« Última modificación: 17 Marzo 2013, 16:58 pm por avesudra »
|
En línea
|
Regístrate en
|
|
|
rir3760
Desconectado
Mensajes: 1.639
|
Como se trata de reescribir el programa usando punteros, me he limitado a cambiar el parámetro: void HOTELES_inicializarHoteles(HOTELES *hotel)
El problema: todo parámetro declarado como un array en realidad se procesa como un puntero. Puedes hacer ese cambio pero solo es cosmético. El error en esta sentencia: *(hotel + i).numero_clientes = 0;
Se genera porque el operador "." tiene mayor prioridad que "*" y la expresion se evalúa así: *((hotel + i).numero_clientes) = 0;
Para conseguir el efecto deseado se deben utilizar paréntesis (mejor, por sencillo, utilizar "[]"). Y como ya te comentaron es mas fácil ayudarte si publicas el código fuente del programa así como los mensajes de error que se generan. Un saludo
|
|
|
En línea
|
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly. -- Kernighan & Ritchie, The C programming language
|
|
|
NathanD
Desconectado
Mensajes: 48
|
Muchas gracias a los dos Ya veo que era un error sintáctico, pensaba que había probado todas las formas... Me ha surgido otra duda (siento ser tan pesado). ¿Cuál es la diferencia entre (*(hotel + i)).numero_clientes = 0;
y (hotel+i)->numero_clientes = 0;
? Ambas opciones me las da como válidas en la misma función, independientemente de haber usado calloc o no (¿y la diferencia entre inicializar con calloc y estáticamente como un array?).
|
|
|
En línea
|
|
|
|
avesudra
Desconectado
Mensajes: 724
Intentando ser mejor cada día :)
|
Es que con el operador "->" lo que haces es acceder a un miembro ( variable ) de un puntero, y con el "." simplemente al miembro cuando no hay punteros de por medio... De ahí que cuando desreferencias con el "*" debas usar el "." . La diferencia de usar memoria dinámica ( calloc, malloc, realloc ... ) y memoria estática ( declaraciones de arrays etc ) la puedes leer aquí: http://es.wikibooks.org/wiki/Programaci%C3%B3n_en_C/Manejo_din%C3%A1mico_de_memoria¡Saludos!
|
|
|
En línea
|
Regístrate en
|
|
|
85
|
El problema: todo parámetro declarado como un array en realidad se procesa como un puntero. Puedes hacer ese cambio pero solo es cosmético. El error en esta sentencia: *(hotel + i).numero_clientes = 0;
Se genera porque el operador "." tiene mayor prioridad que "*" y la expresion se evalúa así: *((hotel + i).numero_clientes) = 0;
Para conseguir el efecto deseado se deben utilizar paréntesis (mejor, por sencillo, utilizar "[]"). Y como ya te comentaron es mas fácil ayudarte si publicas el código fuente del programa así como los mensajes de error que se generan. Un saludo haber haber haber, veamos // // Yo no fui // // // // ///////////////////////////////////////////////////////////////////////////////////////////////// #include<windows.h>// SYSTEM #include<stdio.h> ///////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////// struct Sasafras{ int mandan; }; struct Quete{ struct Sasafras quete; }; struct Cador{ struct Quete tazo; }; struct ElchoCador{ int x, y, z; struct Cador elcho; }; ///////////////////////////////////////////////////////////////////////////////////////////////// void Iniciar1(struct ElchoCador* reg); void Iniciar2(struct ElchoCador* reg); ///////////////////////////////////////////////////////////////////////////////////////////////// int main(){ struct Cador elcho; memset(&elcho,0,sizeof elcho); printf("Valor: %d\n", elcho.tazo.quete.mandan); __try { //if(IsDebuggerPresent()) DebugBreak(); } __except(GetExceptionCode() == EXCEPTION_BREAKPOINT ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { system("pause"); // No debugger is attached, so return FALSE // and continue. // return FALSE; } struct ElchoCador regs[20]; Iniciar1(regs); Iniciar2(regs); for(int j=0; j<20;j++){ printf("%d %d %d\n",regs[j].x,regs[j].y,regs[j].z); } while(getchar()!='\n'); return 0; } ///////////////////////////////////////////////////////////////////////////////////////////////// void Iniciar1(struct ElchoCador* regs){ for(int i=0; i<20;i++){ if(i%2==0) { (*(regs+i)).x = (*(regs+i)).y = (*(regs+i)).z = 2; } } } ///////////////////////////////////////////////////////////////////////////////////////////////// void Iniciar2(struct ElchoCador* regs){ for(int i=0; i<20;i++){ if(i%2!=0) { //regs[i].x = regs[i].y = regs[i].z = 10; (regs+i)->x = (regs+i)->y = (regs+i)->z = 10; } } } /////////////////////////////////////////////////////////////////////////////////////////////////
|
|
« Última modificación: 20 Abril 2013, 22:15 pm por 85 »
|
En línea
|
|
|
|
rir3760
Desconectado
Mensajes: 1.639
|
haber haber haber, veamos
... No te entendi. ¿Por favor puedes explicar a que te refieres con eso? Un saludo
|
|
|
En línea
|
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly. -- Kernighan & Ritchie, The C programming language
|
|
|
85
|
a lo de acceder a los campos de la estructura con esas 2 funciones que se llaman Iniciar1 i Iniciar2
|
|
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
[C] Estructuras y punteros a funciones
Programación C/C++
|
Amadeo Magnus
|
1
|
6,269
|
13 Octubre 2010, 15:05 pm
por Karman
|
|
|
Ayuda con borrado en estructuras anidadas
Programación C/C++
|
JHodges
|
8
|
3,709
|
11 Junio 2015, 04:24 am
por rir3760
|
|
|
[Ayuda] Estructuras anidadas, registro. Lenguaje C
« 1 2 »
Programación C/C++
|
neron991
|
11
|
10,168
|
9 Julio 2015, 10:07 am
por mester
|
|
|
Estructuras anidadas en lenguaje C. -
Programación C/C++
|
NOB2014
|
3
|
4,332
|
5 Febrero 2017, 18:42 pm
por ivancea96
|
|
|
Problema con realloc funciones y punteros a estructuras [RESUELTO]
Programación C/C++
|
Xargam
|
8
|
4,405
|
3 Junio 2018, 21:36 pm
por Xargam
|
|