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

Pasar estructuras por referencia

Estas en el tema de Pasar estructuras por referencia en el foro de C/C++ en Foros del Web. Hola :) En mi instituto estamos estudiando las estructuras, y aunque entiendo mas o menos todo, hay algo que se me escapa! ¿¡Como se pasan ...
  #1 (permalink)  
Antiguo 14/02/2008, 15:29
 
Fecha de Ingreso: enero-2008
Mensajes: 22
Antigüedad: 16 años, 3 meses
Puntos: 0
Pasar estructuras por referencia

Hola :)

En mi instituto estamos estudiando las estructuras, y aunque entiendo mas o menos todo, hay algo que se me escapa! ¿¡Como se pasan estructuras a una funcion por referencia!?

He buscado por internet, con deleznables resultados, por lo cual acudo a pedir la ayuda de los veteranos foreros (lease: Lucifer sobre todo :P).

Esto es lo que he probado yo :S

Código:
#include <stdio.h>

void LeerFecha(struct fecha *Date);

int main()
{
	struct fecha
	{
		int day;
		int month;
		int year;
	};
	struct fecha Date;
	
	LeerFecha(Date);
	
	printf("%d",day);
	printf("%d\n",month);
	printf("%d\n",year);
	
	
	return 0;	
}


void LeerFecha(struct fecha *Date)
{
	Date.day=1;
	Date.month=2;
	Date.year=3;
}
Me da tantos errores que me duelen los ojos :P
  #2 (permalink)  
Antiguo 14/02/2008, 16:37
Avatar de aloqui  
Fecha de Ingreso: diciembre-2007
Mensajes: 973
Antigüedad: 16 años, 4 meses
Puntos: 24
Re: Pasar estructuras por referencia

Para C, el prototipo lo tienes bien, es decir el parámetro es la direccion de la estructura (o lo que es lo mismo un puntero a estructura).
Lo que tienes mal es la llamada, que no se ajusta al prototipo.
En lugar de: LeerFecha(Date); /* Aqui pasas la estructura por valor copiandola entera en la pila */
Debes usar: LeerFecha(&Date); /* Aqui en la pila solo se copia la direccion de memoria en que está ubicada la esctructura */

Luego en la propia funcion, cuando quieres acceder a los datos de la estructura, debes tener en cuenta que lo que tienes es un puntero a estructura, por lo que no debes utilizar el operador punto sino el operador flecha.

----

Luego en C++ hay otra forma de pasar referencias, pero mejor no comentarlo ahora para no acabar de liar el asunto.
__________________
Grupos de Música
Pop Music Stars
  #3 (permalink)  
Antiguo 14/02/2008, 17:24
 
Fecha de Ingreso: enero-2008
Mensajes: 22
Antigüedad: 16 años, 3 meses
Puntos: 0
Re: Pasar estructuras por referencia

Gracias por la respuesta!

Lamentablemente son las 00:23 de la noche y necesito ir a dormir!

Pero mañana vere como solucionarlo y ya comento ^^

Gracias de todas formas ;)
  #4 (permalink)  
Antiguo 15/02/2008, 07:45
 
Fecha de Ingreso: febrero-2008
Mensajes: 5
Antigüedad: 16 años, 2 meses
Puntos: 0
Re: Pasar estructuras por referencia

Mas que aclarar o responder a tu pregunta yo vengo a complicarla, me he perdido un poco, si los arreglos se pasan a funciones solo por referencia, los arreglos de estructuras, estimo tambien lo hacen, sin embargo en el codigo que inserto a continuacion en la funcion debo trabajar con (.) en lugar de (->) a que se debe??
otro punto que me confunde es que si no uso fflush(stdin); no me permite ingresar los datos... que estoy haciendo mal?

Código:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define CANT_ALUM 5

struct alum {
            char nombre[15], titulo[15];
            int comision,legajo;};
void busca_alumno(int, struct alum[]);
void carga_datos(alum[CANT_ALUM]);
void listado(int, struct alum[]);

main()
{
int flag,comision,nro;
alum alumnos[CANT_ALUM];
     system("cls");
     printf("1- Carga de datos\n2- Listado de los alumnos de una comision\n3- Busca alumno\n4- Fin\n\n");
while((flag=getchar())!='4')
     {
     system("cls");
     printf("1- Carga de datos\n2- Listado de los alumnos de una comision\n3- Busca alumno\n4- Fin\n\n");
     switch(flag)
          {
          case '1':carga_datos(alumnos); 
                 break;
          case '2':
                 printf("\n\nIngrese el nro de comision que desea listar: ");
                 scanf(" %d",&comision);
                 listado(comision,alumnos);
                 break;
          case '3':printf("\n\nIngrese el nro de legajo del alumno a consultar: ");
                 scanf(" %d",&nro);
                 busca_alumno(nro,alumnos);
                 break;
          default: break; 
          }
     
     };

return 0;       
}

void carga_datos(alum estudiantes[CANT_ALUM])
{
int i;
for(i=0;i<CANT_ALUM;i++)
     {printf("\nIngrese el nro de legajo: ");
     scanf(" %d",&estudiantes[i].legajo);
     printf("Apellido y Nombre del alumno: ");
     fflush(stdin);
     gets(estudiantes[i].nombre);
     printf("Titulo Nivel Medio: ");
     fflush(stdin);
     gets(estudiantes[i].titulo);
     printf("Comision asignada: ");
     scanf(" %d",&estudiantes[i].comision); };
}
void listado(int com, alum est[CANT_ALUM])
{
int i;
system("cls");
printf("\t\t\tCOMISION %d\nLEGAJO\tNOMBRE Y APELLIDO\tTITULO NIVEL MEDIO",com);
for(i=0;i<CANT_ALUM;i++)
     {
     if(est[i].comision==com)
          {
          printf("\n%4d\t%15s\t%15s",est[i].legajo,est[i].nombre,est[i].titulo);
          };
     }
printf("\n");
system("pause");     
}
void busca_alumno(int nro, alum est[CANT_ALUM])
{
int i,aux=0;
for(i=0;i<CANT_ALUM;++i)
     if(nro==est[i].legajo)
          break;
printf("\nNro de Legajo: %d",est[i].legajo);
printf("\nApellido y Nombre: %s\nTitulo Nivel Medio: %s\nComision asignada: %d\n",est[i].nombre,est[i].titulo,est[i].comision);
system("pause");
}
  #5 (permalink)  
Antiguo 15/02/2008, 09:16
Avatar de _Lucifer_  
Fecha de Ingreso: junio-2006
Mensajes: 1.662
Antigüedad: 17 años, 10 meses
Puntos: 28
Re: Pasar estructuras por referencia

En primer lugar tienes el error que menciona aloqui, te falta el & en el llamado de la función para obtener la dirección de la estructura y poder pasarla por dirección, no por referencia...el paso por referencia se hace usando referenciadores y es algo que pertecena a C++.

Otro error que tienes es el siguiente:
Código:
void LeerFecha(struct fecha *Date)
{
	Date.day=1;
	Date.month=2;
	Date.year=3;
}
Debería ser algo así:
Código:
void LeerFecha(struct fecha *Date)
{
	Date->day=1;
	Date->month=2;
	Date->year=3;
}
O algo así:
Código:
void LeerFecha(struct fecha *Date)
{
	(*Date).day=1;
	(*Date).month=2;
	(*Date).year=3;
}
Recuerda que estás pasando un puntero y debes desreferenciarlo para poder acceder a su contenido. Las dos formas que te coloqué son equivalentes, aunque yo prefiero la primera, es más limpia y fácil de leer.

@TemplarK :
Cita:
Mas que aclarar o responder a tu pregunta yo vengo a complicarla, me he perdido un poco, si los arreglos se pasan a funciones solo por referencia, los arreglos de estructuras, estimo tambien lo hacen, sin embargo en el codigo que inserto a continuacion en la funcion debo trabajar con (.) en lugar de (->) a que se debe??
...
Los arreglos se pasan por dirección, los arreglos de estructuras o de lo que sea también. Debes trabajar con el "." porque al acceder al arreglo usando el operador "[]" estás dereferenciando el puntero (la segunda forma que coloqué antes), si quisieras acceder a la pos 2 del arreglo lo harías así:
Código:
...
arreglo[2].edad = 20;
...
pero también podrías acceder así:
Código:
...
(arreglo +2)->edad = 20;
...
Tomen en cuenta que lo que se coloca entre corchetes ("[]") es el desplazamiento con respecto a la primera posición de memoria del arreglo.

Cita:
...
otro punto que me confunde es que si no uso fflush(stdin); no me permite ingresar los datos... que estoy haciendo mal?
...
Debes usarlo porque la función gets te obliga a ello.

Saludos
__________________
Si crees que no tiene sentido, etonces probablemente lo tenga... :arriba:
  #6 (permalink)  
Antiguo 15/02/2008, 10:46
 
Fecha de Ingreso: enero-2008
Mensajes: 22
Antigüedad: 16 años, 3 meses
Puntos: 0
Re: Pasar estructuras por referencia

Gracias Lucifer y Aloqui, al final he conseguido hacer el ejercicio y entender como funciona!

Saludos :D

Código:
#include <stdio.h>

	struct fecha
	{
		int day;
		int month;
		int year;
	};
	
void LeerFecha(struct fecha *Date)
{
	(*Date).day=1;
	(*Date).month=2;
	(*Date).year=3;
}

int main()
{
	
	struct fecha Date;
	
	LeerFecha(&Date);
	
	printf("%d\n",Date.day);
	printf("%d\n",Date.month);
	printf("%d\n",Date.year);
	
	
	return 0;	
}
  #7 (permalink)  
Antiguo 16/02/2008, 08:36
 
Fecha de Ingreso: febrero-2008
Mensajes: 11
Antigüedad: 16 años, 2 meses
Puntos: 0
Re: Pasar estructuras por referencia

Estoy de acuerdo con Lucifer menos en el párrafo:

"En primer lugar tienes el error que menciona aloqui, te falta el & en el llamado de la función para obtener la dirección de la estructura y poder pasarla por dirección, no por referencia...el paso por referencia se hace usando referenciadores y es algo que pertecena a C++."

¿A qué te refieres con paso por dirección? ¿Y a paso por referencia?
En el ejemplo hacemos que los parámetros formales, que deben ser de tipo puntero, reciban la dirección de los parámetros reales (mediante el operador &) y por tanto se puede acceder y modificar el valor de los parámetros reales desde dentro de la función (ya que se conoce su dirección) como muy bien ha detallado Lucifer, bien con el operador -> o bien usando el operador . y el de dirección (*).
Yo a eso le llamo paso por referencia.
  #8 (permalink)  
Antiguo 17/02/2008, 13:58
 
Fecha de Ingreso: enero-2008
Mensajes: 22
Antigüedad: 16 años, 3 meses
Puntos: 0
Re: Pasar estructuras por referencia

Dejo aquí un programa que hice, por si a alguien le sirve ^^

Espero que ayude a comprender el paso de estructuras a referencias. He hecho una estructura anidada, y lo he pasado de todos los modos posibles creo :P

Código:
#include <stdio.h>
#define MIEMBROS 5

struct fecha 
{	
	int year;
	int month;
	int day;
};

struct persona
{
	char nombre[20];
	int edad;
	struct fecha birthday;
};	

void LeerDatos(struct persona *yo)
{	
	puts("Nombre");
	scanf("%s",yo->nombre);
	puts("Edad");
	scanf("%d",&yo->edad);
	printf("Año de nacimiento");
	scanf("%d",&yo->birthday.year);
	printf("Mes de nacimiento");
	scanf("%d",&yo->birthday.month);
	printf("Día de nacimiento");
	scanf("%d",&yo->birthday.day);
}

void VerDatos(struct persona yo)
{
	printf("\n%s",yo.nombre);
	printf("\n%d\n",yo.edad);
	printf("%d/%d/%d\n",yo.birthday.day,yo.birthday.month,yo.birthday.year);
	
}

void LeerFamilia (struct persona * familia)
{
	int x;
	for (x=0;x<MIEMBROS;x++)
	{
		puts("Nombre");
		scanf("%s",familia[x].nombre);
		puts("Edad");
		scanf("%d",&familia[x].edad);
		puts("Año de nacimiento");
		scanf("%d",&familia[x].birthday.year);
		puts("Mes de nacimiento");
		scanf("%d",&familia[x].birthday.month);
		puts("Día de nacimiento");
		scanf("%d",&familia[x].birthday.day);						
	}
}

void VerFamilia(struct persona * familia)
{	
	int x;
	for (x=0;x<MIEMBROS;x++)
	{
		puts("Nombre");
		printf("%s\n",familia[x].nombre);
		puts("Edad");
		printf("%d\n",familia[x].edad);
		puts("Año de nacimiento");
		printf("%d\n",familia[x].birthday.year);
		puts("Mes de nacimiento");
		printf("%d\n",familia[x].birthday.month);
		puts("Día de nacimiento");
		printf("%d\n",familia[x].birthday.day);	
	}
}
int main()
{
	struct persona yo;
	
	LeerDatos(&yo);
	VerDatos(yo);
	
	struct persona familia[MIEMBROS];
	
	LeerFamilia(familia);
	VerFamilia(familia);
	
	
	
	return 0;
}
  #9 (permalink)  
Antiguo 19/02/2008, 07:30
Avatar de _Lucifer_  
Fecha de Ingreso: junio-2006
Mensajes: 1.662
Antigüedad: 17 años, 10 meses
Puntos: 28
Re: Pasar estructuras por referencia

Cita:
Iniciado por mArss Ver Mensaje
...
¿A qué te refieres con paso por dirección? ¿Y a paso por referencia?
...
Paso por dirección en C/C++ es cuando pasas la dirección de la variable u objeto usando un puntero:
Código:
void funcion(int *a); // prototipo de la función

int main(int nargs, char **args)
{
int a;
funcion(&a);
}

void funcion(int *a) // definición de la función
{
 // Código de la función
 *a = 12; // Hay que desreferenciar el puntero

}
Y paso por referencia es algo exclusivo de C++ y se hace usando referenciadores:
Código:
void funcion(int &a); // prototipo de la función

int main(int nargs, char **args)
{
int a;
funcion(a);
}

void funcion(int &a) // definición de la función
{
 // Código de la función
 a = 12; // Un referenciador es un puntero desreferenciado

}
Espero que esto sirva para aclarar las dudas y entender la diferencia entre paso por dirección y paso por referencia en C y C++. En caso de cualquier duda aquí te explican que es paso por referencia en el punto 12 y adicionalmente te explican qué es un referenciador y la diferencia que hay con un puntero.

Saludos
__________________
Si crees que no tiene sentido, etonces probablemente lo tenga... :arriba:
  #10 (permalink)  
Antiguo 19/02/2008, 08:40
 
Fecha de Ingreso: febrero-2008
Mensajes: 11
Antigüedad: 16 años, 2 meses
Puntos: 0
Re: Pasar estructuras por referencia

Lucifer, a lo que tu llamas paso por dirección yo le llamo paso por referencia. Y te aseguuuro que mi forma es correcta. Quizá es que donde tu vives lo llamáis de esa forma... pero no se, yo nunca había odio lo de paso por dirección, sino por referencia y por valor. Un saludo.
  #11 (permalink)  
Antiguo 19/02/2008, 10:08
Avatar de _Lucifer_  
Fecha de Ingreso: junio-2006
Mensajes: 1.662
Antigüedad: 17 años, 10 meses
Puntos: 28
Re: Pasar estructuras por referencia

¿Entonces me estás diciendo que lo los dos ejemplos que puse son exactamente iguales?

¿Es lo mismo un puntero que un referenciador?

No es que quiera cuestionar tus conocimientos en la materia, pero bajo ningún concepto me puedes decir que son iguales. Tal vez en otros lenguajes no exista el paso por dirección y solo el paso por referencia, pero en C++ son dos cosas diferentes y existen.

Saludos
__________________
Si crees que no tiene sentido, etonces probablemente lo tenga... :arriba:
  #12 (permalink)  
Antiguo 19/02/2008, 11:01
Avatar de aloqui  
Fecha de Ingreso: diciembre-2007
Mensajes: 973
Antigüedad: 16 años, 4 meses
Puntos: 24
Re: Pasar estructuras por referencia

Cita:
Iniciado por mArss Ver Mensaje
Lucifer, a lo que tu llamas paso por dirección yo le llamo paso por referencia. Y te aseguuuro que mi forma es correcta. Quizá es que donde tu vives lo llamáis de esa forma... pero no se, yo nunca había odio lo de paso por dirección, sino por referencia y por valor. Un saludo.
Repasa el post #9 de Lucifer y verás que son dos cosas parecidas pero diferentes.
Me parece que no conoces el paso "por referencia" de C++ que no existe en C.
__________________
Grupos de Música
Pop Music Stars
  #13 (permalink)  
Antiguo 20/02/2008, 16:39
 
Fecha de Ingreso: febrero-2008
Mensajes: 11
Antigüedad: 16 años, 2 meses
Puntos: 0
Re: Pasar estructuras por referencia

Vamos a ver, no os estoy contradiciendo. Simplemente dije que nunca había oído paso por dirección como hace Lucifer, yo le llamo paso por referencia y que ésta forma es correcta, que de algo sirve estudiar estudiar ingeniería técnica en informática. Aquí nadie ha dicho que sean la misma cosa, eso no se de donde os lo habéis sacado.
He dicho.
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

SíEste tema le ha gustado a 2 personas (incluyéndote)




La zona horaria es GMT -6. Ahora son las 15:41.