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

pasar una estructura por referencia

Estas en el tema de pasar una estructura por referencia en el foro de C/C++ en Foros del Web. El siguiente programa pasa una estructura por referencia; umenta y decrementa el saldo de los clientes y los muestra por pantalla. Al compilarlo funciona, pero ...
  #1 (permalink)  
Antiguo 04/07/2010, 10:37
 
Fecha de Ingreso: febrero-2010
Mensajes: 258
Antigüedad: 14 años, 1 mes
Puntos: 0
pasar una estructura por referencia

El siguiente programa pasa una estructura por referencia; umenta y decrementa el saldo de los clientes y los muestra por pantalla. Al compilarlo funciona, pero me da fallo de segmentación.

Código C:
Ver original
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. struct cuenta{
  5.          char nom[100];
  6.          float saldo;
  7. };
  8.  
  9. int main(){
  10.  
  11. struct cuenta cliente[3];
  12. struct cuenta *punt;
  13.  
  14. int i;
  15. char c;
  16.  
  17. void aumento();
  18. void decremento();
  19.  
  20. for(i=0; i<=2; i++){
  21.         printf("Nombre: ");
  22.         scanf("%99s", cliente[i].nom);
  23.         printf("Saldo: ");
  24.         scanf("%f", &cliente[i].saldo);
  25. }
  26. do{
  27.    printf("A--> Aumentar el saldo.\n");
  28.    printf("D--> Decrementar el saldo.\n");
  29.    printf("S--> Salir.\n");
  30.    scanf("%1s", &c);
  31.    if((c=='A') || (c=='a')){
  32.          printf("Numero del cliente: ");
  33.          scanf("%d", &i);
  34.          punt = &cliente[i];
  35.          aumento(&cliente[i]);
  36.          
  37.    }
  38.    if((c=='D') || (c=='d')){
  39.          printf("Numero del cliente: ");
  40.          scanf("%d", &i);
  41.          punt = &cliente[i];
  42.          decremento(&cliente[i]);
  43.    }
  44. }
  45. while((c != 's') && (c != 'S'));
  46.  
  47. for(i=0; i<=2; i++)
  48.          printf("\nEl saldo del cliente %d: %.2f\n",i, cliente[i].saldo);
  49. }
  50. void aumento(struct cuenta *sal){
  51.          float inc;
  52.  
  53.          printf("Incremento del saldo: ");
  54.          scanf("%f", &inc);
  55.          sal->saldo=sal->saldo+inc;}
  56.  
  57. void decremento(struct cuenta *sal){
  58.          float dec;
  59.  
  60.          printf("Decremento del saldo: ");
  61.          scanf("%f", &dec);
  62.          sal->saldo=sal->saldo+dec;}

En las dos funciones aumento y decremento declaramos struct cuenta *sal. *sal significa que accedemos al valor del salario antes de ser aumentado o decrementado ¿no?. Esta instrucción
Código C:
Ver original
  1. sal->saldo=sal->saldo+inc;
¿qué hace y por qué está el operador flecha dos veces? El operador flecha accede al elemento de la estructura ¿no?.
  #2 (permalink)  
Antiguo 04/07/2010, 13:15
 
Fecha de Ingreso: junio-2010
Mensajes: 22
Antigüedad: 13 años, 10 meses
Puntos: 1
Respuesta: pasar una estructura por referencia

Bueno, el operador flecha se usa cuando se accede a las variables de un apuntador, osea, por referencia; y se usa el operador punto, cuando es por valor.

Código:
sal->saldo = sal->saldo + inc;
Se usa 2 veces para asignar el valor actual, mas el incremento.

Yo compile el programa y lo corri y no me produjo "segmenation fault".

Aqui esta la salida:

Código:
[scumbag@bodysnatcher Temporal]$ ./a.out 
Nombre: e
Saldo: 1
Nombre: r
Saldo: 2
Nombre: t
Saldo: 3

A--> Aumentar el saldo.
D--> Decrementar el saldo.
S--> Salir.
A
Numero del cliente: 1
Incremento del saldo: 23

A--> Aumentar el saldo.
D--> Decrementar el saldo.
S--> Salir.
S

El saldo del cliente 0: 1.00

El saldo del cliente 1: 25.00

El saldo del cliente 2: 3.00
Si pudieras mandar los pasos que sigues para producir el "segmentation fault".

Nota:

La declaración de las funciones protipo van fuera del main y con la misma "firma" que con las que seran usadas posteriormente.

Asi:

Código:
void aumento(struct cuenta *sal);
void decremento(struct cuenta *sal);
Justo despues de que declaras la estructura.
  #3 (permalink)  
Antiguo 05/07/2010, 06:19
 
Fecha de Ingreso: febrero-2010
Mensajes: 258
Antigüedad: 14 años, 1 mes
Puntos: 0
Respuesta: pasar una estructura por referencia

Esta es la compilación:

./a.out
Nombre: pepe
Saldo: 45.54
Nombre: ana
Saldo: 32.25
Nombre: lola
Saldo: 15.74
A--> Aumentar el saldo.
D--> Decrementar el saldo.
S--> Salir.
a
Numero del cliente: 0
Incremento del saldo: 8.3
A--> Aumentar el saldo.
D--> Decrementar el saldo.
S--> Salir.
s

El saldo del cliente 0: 53.84

El saldo del cliente 1: 32.25

El saldo del cliente 2: 15.74
Fallo de segmentación
  #4 (permalink)  
Antiguo 05/07/2010, 09:20
 
Fecha de Ingreso: enero-2008
Mensajes: 229
Antigüedad: 16 años, 2 meses
Puntos: 1
Respuesta: pasar una estructura por referencia

en primera tu no estas pasando las estructuras por referencia lo estas haciendo es pasar un valor por punteros. para pasar estructura por referencia la declaracion de tu funcion debe ser:

void aumento(cuenta &sal)
{

}
dentro de la funcion debes utilizar el "operador ." en lugar del "operador ->".

cuando mandes a llamar a la funcion debes ser asi:

aumento(cliente[i]);

las definicion de tus funciones deben estar fuera de la funcion main, ademas de que debe ser igual a donde se declaran

void aumento(cuenta &sal);
void decremento(cuenta &sal);

si lo estas copilando en linux, debes de cuidar que tu archivo fuente debe tener extencion cpp, por que si no es posible que te marque error

esta

scanf("%1s", &c);

puede ser reeplazada por:

scanf("%c", &c);
  #5 (permalink)  
Antiguo 06/07/2010, 10:31
 
Fecha de Ingreso: febrero-2010
Mensajes: 258
Antigüedad: 14 años, 1 mes
Puntos: 0
Respuesta: pasar una estructura por referencia

Código C:
Ver original
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. struct cuenta{
  5.          char nom[100];
  6.          float saldo;
  7. };
  8.  
  9. int main(){
  10.  
  11. void aumento();
  12. void decremento();
  13.  
  14. struct cuenta cliente[3];
  15. struct cuenta *punt;
  16.  
  17. int i;
  18. char c;
  19.  
  20.  
  21. for(i=0; i<=2; i++){
  22.         printf("Nombre: ");
  23.         scanf("%99s", cliente[i].nom);
  24.         printf("Saldo: ");
  25.         scanf("%f", &cliente[i].saldo);
  26. }
  27. do{
  28.    printf("A--> Aumentar el saldo.\n");
  29.    printf("D--> Decrementar el saldo.\n");
  30.    printf("S--> Salir.\n");
  31.    scanf("%c", &c);
  32.    if((c=='A') || (c=='a')){
  33.          printf("Numero del cliente: ");
  34.          scanf("%d", &i);
  35.          punt = &cliente[i];
  36.          aumento(cliente[i]);
  37.          
  38.    }
  39.    if((c=='D') || (c=='d')){
  40.          printf("Numero del cliente: ");
  41.          scanf("%d", &i);
  42.          punt = &cliente[i];
  43.          decremento(cliente[i]);
  44.    }
  45. }
  46. while((c != 's') && (c != 'S'));
  47.  
  48. for(i=0; i<=2; i++)
  49.          printf("\nEl saldo del cliente %d: %.2f\n", i, cliente[i].saldo);
  50. }
  51. void aumento(cuenta &sal){
  52.          float inc;
  53.  
  54.          printf("Incremento del saldo: ");
  55.          scanf("%f", &inc);
  56.          sal.saldo=sal.saldo+inc;}
  57.  
  58. void decremento(cuenta &sal){
  59.          float dec;
  60.  
  61.          printf("Decremento del saldo: ");
  62.          scanf("%f", &dec);
  63.          sal.saldo=sal.saldo+dec;}

Error al compilar. pasar_estructura_por_referencia.c:51: error: expected ‘)’ before ‘&’ token
pasar_estructura_por_referencia.c:58: error: expected ‘)’ before ‘&’ token

Si se trata de pasar una estructura por referencia no hay que usar el operador "->" en lugar del "."
  #6 (permalink)  
Antiguo 06/07/2010, 11:23
 
Fecha de Ingreso: enero-2008
Mensajes: 229
Antigüedad: 16 años, 2 meses
Puntos: 1
Respuesta: pasar una estructura por referencia

tal vez no me supe explicar en mi comentario anterior. Aquí voy de nuevo.

   if((c=='A') || (c=='a')){
         printf("Numero del cliente: ");
         scanf("%d", &i);
         punt = &cliente[i];
         aumento(cliente[i]);
         
   }

esta parte del codigo debe quedar asi
   if((c=='A') || (c=='a')){
         printf("Numero del cliente: ");
         scanf("%d", &i);
         aumento(cliente[i]);
   }

lo mismo aplica para el decremento

Con respecto al "." y al "->". cuando pasas un valor por referencia debes utilizar, ".", ya el "->" es solo usado cuando utilizas punteros.

El error que te marca es posiblemente por dos causas
1. tu archivo no tiene extension cpp, esto es nombre_de_archivo.cpp.
o
2. que tengas q poner void decremento(struct cuenta &sal).

Ademas tus declaraciones deben ser iguales a tus definiciones

int main(){
 
void aumento();//mal
void decremento();//mal
void aumento(struct cuenta &);//bien
void decremento(struct cuenta &);//bien

...
}
  #7 (permalink)  
Antiguo 06/07/2010, 12:18
 
Fecha de Ingreso: febrero-2010
Mensajes: 258
Antigüedad: 14 años, 1 mes
Puntos: 0
Respuesta: pasar una estructura por referencia

Código C:
Ver original
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. struct cuenta{
  5.          char nom[100];
  6.          float saldo;
  7. };
  8.  
  9.  
  10.  
  11. int main(){
  12.  
  13. void aumento(struct cuenta &sal);
  14. void decremento(struct cuenta &sal);
  15.  
  16. struct cuenta cliente[3];
  17. struct cuenta *punt;
  18.  
  19. int i;
  20. char c;
  21.  
  22.  
  23. for(i=0; i<=2; i++){
  24.         printf("Nombre: ");
  25.         scanf("%99s", cliente[i].nom);
  26.         printf("Saldo: ");
  27.         scanf("%f", &cliente[i].saldo);
  28. }
  29. do{
  30.    printf("A--> Aumentar el saldo.\n");
  31.    printf("D--> Decrementar el saldo.\n");
  32.    printf("S--> Salir.\n");
  33.    scanf("%c", &c);
  34.    if((c=='A') || (c=='a')){
  35.          printf("Numero del cliente: ");
  36.          scanf("%d", &i);
  37.          aumento(cliente[i]);
  38.          
  39.    }
  40.    if((c=='D') || (c=='d')){
  41.          printf("Numero del cliente: ");
  42.          scanf("%d", &i);
  43.          decremento(cliente[i]);
  44.    }
  45. }
  46. while((c != 's') && (c != 'S'));
  47.  
  48. for(i=0; i<=2; i++)
  49.          printf("\nEl saldo del cliente %d: %.2f\n", i, cliente[i].saldo);
  50. }
  51. void aumento(struct cuenta &sal){
  52.          float inc;
  53.  
  54.          punt = &cliente;
  55.          printf("Incremento del saldo: ");
  56.          scanf("%f", &inc);
  57.          sal.saldo=sal.saldo+inc;}
  58.  
  59. void decremento(struct cuenta &sal){
  60.          float dec;
  61.  
  62.           punt = &cliente;
  63.          printf("Decremento del saldo: ");
  64.          scanf("%f", &dec);
  65.          sal.saldo=sal.saldo+dec;}

Me da el mismo error que antes. pasar_estructura_por_referencia.c:51: error: expected ‘;’, ‘,’ or ‘)’ before ‘&’ token
pasar_estructura_por_referencia.c:59: error: expected ‘;’, ‘,’ or ‘)’ before ‘&’ token
  #8 (permalink)  
Antiguo 06/07/2010, 13:14
 
Fecha de Ingreso: enero-2008
Mensajes: 229
Antigüedad: 16 años, 2 meses
Puntos: 1
Respuesta: pasar una estructura por referencia

tu archivo tiene extension .c (pasar_estructura_por_referencia.c), cabiambialo por pasar_estructura_por_referencia.cpp, ademas, quita la intruccion que esta en negritas en estas funciones.

void aumento(struct cuenta &sal){
float inc;

punt = &sal;
printf("Incremento del saldo: ");
scanf("%f", &inc);
sal.saldo=sal.saldo+inc;
}

void decremento(struct cuenta &sal){
float dec;
punt = &sal;
printf("Decremento del saldo: ");
scanf("%f", &dec);
sal.saldo=sal.saldo+dec;}

La razon de por es importante cambiar de .c a .cpp es por que, El compilador toma en cuenta la extension del archivo para saber si va a compilar un archivo de c o de c++. Y debes tomar en cuenta que las referencias no son propias de c si no de c++. es el motivo de por te marca el error que te marca.
Si quitas lo que te puse en negritas, quita tambien estas intrucciones
struct cuenta cliente[3];
struct cuenta *punt;


si no las quitas ponlas fuera de la funcion main.

Trata de seguir mas fielmente lo que se te dice, o si no sabes como hacerlo pregunta...
  #9 (permalink)  
Antiguo 07/07/2010, 10:35
 
Fecha de Ingreso: febrero-2010
Mensajes: 258
Antigüedad: 14 años, 1 mes
Puntos: 0
Mensaje Respuesta: pasar una estructura por referencia

Código C:
Ver original
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. struct cuenta{
  5.          char nom[100];
  6.          float saldo;
  7. };
  8.  
  9. struct cuenta cliente[3];
  10. struct cuenta *punt;
  11.  
  12. int main(){
  13.  
  14. void aumento(struct cuenta &sal);
  15. void decremento(struct cuenta &sal);
  16.  
  17.  
  18.  
  19. int i;
  20. char c;
  21.  
  22.  
  23. for(i=0; i<=2; i++){
  24.         printf("Nombre: ");
  25.         scanf("%99s", cliente[i].nom);
  26.         printf("Saldo: ");
  27.         scanf("%f", &cliente[i].saldo);
  28. }
  29. do{
  30.    printf("A--> Aumentar el saldo.\n");
  31.    printf("D--> Decrementar el saldo.\n");
  32.    printf("S--> Salir.\n");
  33.    scanf("%c", &c);
  34.    if((c=='A') || (c=='a')){
  35.          printf("Numero del cliente: ");
  36.          scanf("%d", &i);
  37.          aumento(cliente[i]);
  38.          
  39.    }
  40.    if((c=='D') || (c=='d')){
  41.          printf("Numero del cliente: ");
  42.          scanf("%d", &i);
  43.          decremento(cliente[i]);
  44.    }
  45. }
  46. while((c != 's') && (c != 'S'));
  47.  
  48. for(i=0; i<=2; i++)
  49.          printf("\nEl saldo del cliente %d: %.2f\n", i, cliente[i].saldo);
  50. }
  51. void aumento(struct cuenta &sal){
  52.          float inc;
  53.  
  54.          
  55.          printf("Incremento del saldo: ");
  56.          scanf("%f", &inc);
  57.          sal.saldo=sal.saldo+inc;}
  58.  
  59. void decremento(struct cuenta &sal){
  60.          float dec;
  61.  
  62.          
  63.          printf("Decremento del saldo: ");
  64.          scanf("%f", &dec);
  65.          sal.saldo=sal.saldo+dec;}

gcc pasar_estructura_por_referencia.cpp
gcc: error trying to exec 'cc1plus': execvp: No existe el fichero ó directorio
  #10 (permalink)  
Antiguo 09/07/2010, 17:19
 
Fecha de Ingreso: julio-2010
Mensajes: 153
Antigüedad: 13 años, 9 meses
Puntos: 1
Respuesta: pasar una estructura por referencia

en c no existe "&" para pasar por referencia, para eso estan los punteros, en c++ si, si esta progarmando en c ¿por que le das una forma de hacerlo en c++?, para pasar por referencia simplemente usa los punteros
  #11 (permalink)  
Antiguo 09/07/2010, 17:26
 
Fecha de Ingreso: julio-2010
Mensajes: 153
Antigüedad: 13 años, 9 meses
Puntos: 1
Respuesta: pasar una estructura por referencia

un ejemplo echo a lo rapido para pasar por referencia una estructura
Código C:
Ver original
  1. #include <stdio.h>
  2.  #include <string.h>
  3.  struct Estructura
  4.  {
  5.      char nombre[10];
  6.      char tel[10];
  7.  };
  8.  
  9.  void funcion(struct Estructura *estructura);
  10.  
  11.  int main(int argc, char **argv)
  12.  {
  13.      struct Estructura estructura;
  14.      strcpy(estructura.nombre, "nombre");
  15.      strcpy(estructura.tel, "tel");
  16.      
  17.      funcion(&estructura);
  18.  }
  19.  
  20.  void funcion(struct Estructura *estructura)
  21.  {
  22.      printf("nombre:%s - tel: %s\n", estructura->nombre, estructura->tel);
  23.      
  24.  }
  #12 (permalink)  
Antiguo 30/07/2010, 06:12
 
Fecha de Ingreso: febrero-2010
Mensajes: 258
Antigüedad: 14 años, 1 mes
Puntos: 0
Respuesta: pasar una estructura por referencia

Hola,este ejercicio que publiqué al tratarse de aumentar y decrementar el salario de los clientes mediante el paso de una estructura entre funciones, los cambios que se hacen tanto en la función aumentar como decrementar se verán reflejados en el programa principal. Así pues, se trataría del paso de una estructura entera por referencia. Quisiera asegurarme si el razonamiento es correcto.

Un ejemplo de enunciado donde pidiera pasar una estructura entera por valor usando funciones (se trataría de hacer una copia de la estructura original ¿no?), ¿cuál podría ser?. Gracias.
  #13 (permalink)  
Antiguo 30/07/2010, 09:19
 
Fecha de Ingreso: junio-2008
Ubicación: Seattle, USA
Mensajes: 733
Antigüedad: 15 años, 10 meses
Puntos: 61
Respuesta: pasar una estructura por referencia

Espero que perdones la pedanteria: No existe pasar "una estructura entera" por referencia. La gracia del paso por referencia es que no pasas estructuras "enteras".

El "paso por referencia", o el truco de usar punteros y direcciones de memoria es similar a tener anotado en un papel la direccion de una casa y tener como mision pintar la puerta principal de esa casa.

No obtienes nada pintando el papel, o haciendole modificaciones a ese papel (osea al puntero). Solo lograras cambios si te diriges a la casa ( usando el operador * o el operador -> ).

Pero es muy facil transportar papeles en los bolsillos. Las funciones reciben papeles (las direcciones de memoria, anotadas en los punteros), y su mision es llegar a esas direcciones y lograr cambios ahi.

Es dificil transportar casas de verdad en los bolsillos. Cuando pasas estructuras por valor, eso es lo que intentas hacer, pero las funciones en vez de recibir una casa completa, hacen una copia personal para modificar. Si pintas la puerta de la casa copiada, no le haras nada a la casa original.
  #14 (permalink)  
Antiguo 30/07/2010, 11:33
 
Fecha de Ingreso: febrero-2010
Mensajes: 258
Antigüedad: 14 años, 1 mes
Puntos: 0
Respuesta: pasar una estructura por referencia

En este ejercicio, cuando declaramos un puntero a la estructura struct cuenta *punt, lo que hacemos es acceder al contenido de la estructura,es decir, a su conjunto ¿no?. ¿Cada campo de la estructura está almacenado en una dirección de memoria diferente?. Gracias.
  #15 (permalink)  
Antiguo 30/07/2010, 11:41
 
Fecha de Ingreso: abril-2010
Ubicación: Rosario
Mensajes: 1.850
Antigüedad: 14 años
Puntos: 228
Respuesta: pasar una estructura por referencia

Cuando haces esto: struct cuenta *punt y le asignas una direccion, se guarda la direccion de inicio de la estructura. Despues el compilador hace de la suyas para buscar donde esta almacenado cada valor. por ejemplo.

struct entero {
int a,b;
}

Esa estructura tiene dos enteros, por lo general va uno seguido del otro en memoria.
Entonces si tenemos un puntero a la direccion de esa estructura, llamemolas X.

SI leemos la direccion X tenemos el valor a. Pero como los enteros ocuoan 4 bytes si a X le sumamos 4 vamos a obtener la variable b. Estas cosas depende del compilador y como maneje este mismo la memoria.

Pero eso es una idea. Las estructura son simplemente metodos para agrupar y manejar rapidamente la memoria.

La verdad si estas cosas no te interesan demasiado, vos abstraete a usar solo los punteros y al paso por referencia. Pero nunca esta de mas saber estas cosas.
  #16 (permalink)  
Antiguo 30/07/2010, 12:31
 
Fecha de Ingreso: febrero-2010
Mensajes: 258
Antigüedad: 14 años, 1 mes
Puntos: 0
Respuesta: pasar una estructura por referencia

Entonces esta instrucción struct cuenta *punt ¿cómo se representaría gráficamente?, para entenderlo mejor. Gracias.
  #17 (permalink)  
Antiguo 30/07/2010, 12:48
 
Fecha de Ingreso: abril-2010
Ubicación: Rosario
Mensajes: 1.850
Antigüedad: 14 años
Puntos: 228
Respuesta: pasar una estructura por referencia

No estoy como para hacer un dibujo de esto... peor te recomiendo el libro:
Lenguaje de programación C. Kernighan & Ritc

Leete el capitulo de punteros que tiene graficos muy interesante.

Etiquetas: estructura, pasar, referencia
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 09:35.