Discussion:
Punteros C / Paso de Parametros
(demasiado antiguo para responder)
Olaf "El Blanco"
2006-03-07 13:18:58 UTC
Permalink
No soy de esos comodos, que no quieren investigar por su propia cuenta...
Pero es que de verdad, ya no se que mas ver.
Pensaba que entendia mas o menos bien el tema de punteros, he encontrado
este ejercicio y me lo he puesto a hacer usando memoria dinámica...

*****************************************************************************************/
#include <stdio.h>
#include <stdlib.h>

/* Problema 4(a entregar). Partiendo de la siguiente declaración de
plantilla de estructura:

Struct empresa{
int id_emp;
char nombre[15];
char direc_emp[30];
long telefono;
};

Escribir un programa modular (con funciones) que defina una tabla de 10
empresas y establezca
un menú que llame a una serie de funciones. Se usará la llamada a función
típica de vectores
p.e. void rellenar (struct empresa Emp[]) que deberán realizar las tareas
siguientes:
a) Introducir todos los datos de las empresas.
b) Visualizar todos los datos d las empresas
c) Visualizar datos de una determinada empresa seleccionada al introducir
por teclado un
identificador de empresa.
d) Borrar datos de una determinada empresa seleccionada al introducir por
teclado un
identificador de empresa.This file will not be overwritten */


struct empresa {
int id_emp;
char nombre[15];
char direc_emp[30];
long telefono;
};

typedef struct empresa Empresa;

/* Devuelve una empresa, ya creada. */
Empresa agregar();

/* Muestra la empresa x */
void mostrar(Empresa x);

/* Agrega algunas empresas para no teclear en cada prueba */
void agregando(Empresa *listado, int *cantidad);

/* Muestra el listado de Empresas */
void ver_listado(Empresa *listado, int cantidad);

/* Menu y desarrollo del programa */
int menu(Empresa *listado, int *cantidad);

/* Imprimie un menu */
void imprime_menu(void);

/* Funciones que uso dentro del menu, por orgranización(?) */
void MENU_agregar(Empresa *listado, int *cantidad);

/*Las siguientes y las que se necesitan para las siguientes, aun no estan
codificadas */
void MENU_eliminar(Empresa *listado, char *nombre);
void MENU_ver(Empresa *listado, char *nombre);


int main()
{
/* Vector de Empresas */
Empresa *listado;
/* Cantidad de Empresas. al inicio del programa, tenemos solo una
(vacia) */
/* Me gustaria poder hacer que en caso de no crear ninguna empresa, no
se gaste ni un KB en un registro */
int cant = 1;
/* Reservo espacio minimo para una empresa */
listado=(Empresa*)malloc(sizeof(Empresa)*cant);
/* Agrego algunas empresas de prueba */
agregando(listado, &cant);
/* Empieza el menu y el desarrollo */
menu(listado, &cant);

getch();
return 0;
}


/*****************************************************************************************/
void ver_listado(Empresa *listado, int cantidad)
{
/* Porque no funciona el while (listado != NULL) ; listado++
???? */
int n;
for (n=0; n<cantidad; n++)
mostrar(*(listado+n));
getch();
}
/*****************************************************************************************/
void agregando(Empresa *listado, int *nueva_cantidad)
{
/* Los parrafos de este procedimiento son cargas automaticas,
en caso de querer modificar la cantidad de cargas automaticas,
modificar tambien la siguiente variable */
int parrafos = 4;
listado = (Empresa *)realloc(listado, (sizeof(Empresa) * parrafos));

(*(listado+0)).id_emp = 0001;
strcpy ( (*(listado+0)).nombre, "WotansFOLK SRL");
strcpy ( (*(listado+0)).direc_emp, "Bennisa 11 PB \"E\"");
(*(listado+0)).telefono = 335256981;

(*(listado+1)).id_emp = 0002;
strcpy ( (*(listado+1)).nombre, "Audery gayo y CIA");
strcpy ( (*(listado+1)).direc_emp, "Salto de la Madri");
(*(listado+1)).telefono = 687267122;

(*(listado+2)).id_emp = 0044;
strcpy ( (*(listado+2)).nombre, "Skywalker");
strcpy ( (*(listado+2)).direc_emp, "Death STAR");
(*(listado+2)).telefono = 335256981;

(*(listado+3)).id_emp = 0022;
strcpy ( (*(listado+3)).nombre, "Zorra golfa");
strcpy ( (*(listado+3)).direc_emp, "San Joan d Alacant");
(*(listado+3)).telefono = 6668122;

*nueva_cantidad = parrafos;
}
/*****************************************************************************************/
Empresa agregar(void)
{
Empresa aux; /* Uso un registro auxiliar, el que voy a devolver */
printf ("ID : "); scanf ("%d", &aux.id_emp);
printf ("Nombre : "); scanf ("%s", aux.nombre);
printf ("Direccion : "); scanf ("%s", aux.direc_emp);
printf ("Tel : "); scanf ("%l", &aux.telefono);
return aux;
}
/*****************************************************************************************/
void mostrar(Empresa x)
{
printf ("%s\n", x.nombre);
printf ("\t%s\n\t%d(ID)\n\tTel:%d\n", x.direc_emp, x.id_emp, x.telefono);
}
/*****************************************************************************************/
void imprime_menu(void)
{
system ("cls");
printf ("\t1. Agregar Empresa\n");
printf ("\t2. Eliminar Empresa\n");
printf ("\t3. Ver Empresa\n");
printf ("\t4. Ver listado Completo\n");
printf ("\t5. Salir\n");
}
/*****************************************************************************************/
/* La variable cantidad pasadoa como parametro se utiliza en caso de
usar (lo hago) un procedimiento que cargue varios registros al mismo
tiempo */
int menu(Empresa *listado, int *cantidad)
{
char eleccion;
int cant = *cantidad;
imprime_menu();
while (eleccion != '5') {
imprime_menu();
eleccion=getch();
switch (eleccion) {
case '1' : MENU_agregar(listado, &cant);
break;
/* case '2' : break;
case '3' : break; */
case '4' : ver_listado(listado, cant);
break;
case '5' : return 0;

}
}
}
/*****************************************************************************************/
void MENU_agregar(Empresa *listado, int *cantidad)
{
++*cantidad;
listado = (Empresa *)realloc(listado, (sizeof(Empresa) * (*cantidad)));
*(listado+(*cantidad)) = agregar();
printf ("Cantidad actual de Empresas en listado: %d\n", *cantidad);
system ("pause");
}
/*****************************************************************************************/
--
*****************************************************
"...Winds and storms, embrace us now,
Lay waste the light of day.
Open gates to darker lands...
We spread our wings and fly away..."
*****************************************************
Zephryn Xirdal
2006-03-07 14:05:40 UTC
Permalink
Hasta donde he llegado estás reservando memoria para un sólo elemento, con
lo que tarde o temprano te petará.

Este ejemplo es de los clásicos de toda la vida-
Post by Olaf "El Blanco"
No soy de esos comodos, que no quieren investigar por su propia cuenta...
Pero es que de verdad, ya no se que mas ver.
Pensaba que entendia mas o menos bien el tema de punteros, he encontrado
este ejercicio y me lo he puesto a hacer usando memoria dinámica...
*****************************************************************************************/
#include <stdio.h>
#include <stdlib.h>
/* Problema 4(a entregar). Partiendo de la siguiente declaración de
Struct empresa{
int id_emp;
char nombre[15];
char direc_emp[30];
long telefono;
};
Escribir un programa modular (con funciones) que defina una tabla de 10
empresas y establezca
un menú que llame a una serie de funciones. Se usará la llamada a función
típica de vectores
p.e. void rellenar (struct empresa Emp[]) que deberán realizar las tareas
a) Introducir todos los datos de las empresas.
b) Visualizar todos los datos d las empresas
c) Visualizar datos de una determinada empresa seleccionada al introducir
por teclado un
identificador de empresa.
d) Borrar datos de una determinada empresa seleccionada al introducir por
teclado un
identificador de empresa.This file will not be overwritten */
struct empresa {
int id_emp;
char nombre[15];
char direc_emp[30];
long telefono;
};
typedef struct empresa Empresa;
/* Devuelve una empresa, ya creada. */
Empresa agregar();
/* Muestra la empresa x */
void mostrar(Empresa x);
/* Agrega algunas empresas para no teclear en cada prueba */
void agregando(Empresa *listado, int *cantidad);
/* Muestra el listado de Empresas */
void ver_listado(Empresa *listado, int cantidad);
/* Menu y desarrollo del programa */
int menu(Empresa *listado, int *cantidad);
/* Imprimie un menu */
void imprime_menu(void);
/* Funciones que uso dentro del menu, por orgranización(?) */
void MENU_agregar(Empresa *listado, int *cantidad);
/*Las siguientes y las que se necesitan para las siguientes, aun no estan
codificadas */
void MENU_eliminar(Empresa *listado, char *nombre);
void MENU_ver(Empresa *listado, char *nombre);
int main()
{
/* Vector de Empresas */
Empresa *listado;
/* Cantidad de Empresas. al inicio del programa, tenemos solo una
(vacia) */
/* Me gustaria poder hacer que en caso de no crear ninguna empresa, no
se gaste ni un KB en un registro */
int cant = 1;
/* Reservo espacio minimo para una empresa */
listado=(Empresa*)malloc(sizeof(Empresa)*cant);
/* Agrego algunas empresas de prueba */
agregando(listado, &cant);
/* Empieza el menu y el desarrollo */
menu(listado, &cant);
getch();
return 0;
}
/*****************************************************************************************/
void ver_listado(Empresa *listado, int cantidad)
{
/* Porque no funciona el while (listado != NULL) ; listado++
???? */
int n;
for (n=0; n<cantidad; n++)
mostrar(*(listado+n));
getch();
}
/*****************************************************************************************/
void agregando(Empresa *listado, int *nueva_cantidad)
{
/* Los parrafos de este procedimiento son cargas automaticas,
en caso de querer modificar la cantidad de cargas automaticas,
modificar tambien la siguiente variable */
int parrafos = 4;
listado = (Empresa *)realloc(listado, (sizeof(Empresa) * parrafos));
(*(listado+0)).id_emp = 0001;
strcpy ( (*(listado+0)).nombre, "WotansFOLK SRL");
strcpy ( (*(listado+0)).direc_emp, "Bennisa 11 PB \"E\"");
(*(listado+0)).telefono = 335256981;
(*(listado+1)).id_emp = 0002;
strcpy ( (*(listado+1)).nombre, "Audery gayo y CIA");
strcpy ( (*(listado+1)).direc_emp, "Salto de la Madri");
(*(listado+1)).telefono = 687267122;
(*(listado+2)).id_emp = 0044;
strcpy ( (*(listado+2)).nombre, "Skywalker");
strcpy ( (*(listado+2)).direc_emp, "Death STAR");
(*(listado+2)).telefono = 335256981;
(*(listado+3)).id_emp = 0022;
strcpy ( (*(listado+3)).nombre, "Zorra golfa");
strcpy ( (*(listado+3)).direc_emp, "San Joan d Alacant");
(*(listado+3)).telefono = 6668122;
*nueva_cantidad = parrafos;
}
/*****************************************************************************************/
Empresa agregar(void)
{
Empresa aux; /* Uso un registro auxiliar, el que voy a devolver */
printf ("ID : "); scanf ("%d", &aux.id_emp);
printf ("Nombre : "); scanf ("%s", aux.nombre);
printf ("Direccion : "); scanf ("%s", aux.direc_emp);
printf ("Tel : "); scanf ("%l", &aux.telefono);
return aux;
}
/*****************************************************************************************/
void mostrar(Empresa x)
{
printf ("%s\n", x.nombre);
printf ("\t%s\n\t%d(ID)\n\tTel:%d\n", x.direc_emp, x.id_emp,
x.telefono);
}
/*****************************************************************************************/
void imprime_menu(void)
{
system ("cls");
printf ("\t1. Agregar Empresa\n");
printf ("\t2. Eliminar Empresa\n");
printf ("\t3. Ver Empresa\n");
printf ("\t4. Ver listado Completo\n");
printf ("\t5. Salir\n");
}
/*****************************************************************************************/
/* La variable cantidad pasadoa como parametro se utiliza en caso de
usar (lo hago) un procedimiento que cargue varios registros al mismo
tiempo */
int menu(Empresa *listado, int *cantidad)
{
char eleccion;
int cant = *cantidad;
imprime_menu();
while (eleccion != '5') {
imprime_menu();
eleccion=getch();
switch (eleccion) {
case '1' : MENU_agregar(listado, &cant);
break;
/* case '2' : break;
case '3' : break; */
case '4' : ver_listado(listado, cant);
break;
case '5' : return 0;
}
}
}
/*****************************************************************************************/
void MENU_agregar(Empresa *listado, int *cantidad)
{
++*cantidad;
listado = (Empresa *)realloc(listado, (sizeof(Empresa) *
(*cantidad)));
*(listado+(*cantidad)) = agregar();
printf ("Cantidad actual de Empresas en listado: %d\n", *cantidad);
system ("pause");
}
/*****************************************************************************************/
--
Por lo general, los hombres creen fácilmente lo que desean.
-- Julio César. Emperador romano.
Olaf "El Blanco"
2006-03-07 14:32:32 UTC
Permalink
Pero en: 'void MENU_agregar(Empresa *listado, int *cantidad);'
a medida que quiero crear empresas hago un realloc.
Mi idea es reservar lo justo y necesario.
Post by Zephryn Xirdal
Hasta donde he llegado estás reservando memoria para un sólo elemento, con
lo que tarde o temprano te petará.
Este ejemplo es de los clásicos de toda la vida-
Post by Olaf "El Blanco"
No soy de esos comodos, que no quieren investigar por su propia cuenta...
Pero es que de verdad, ya no se que mas ver.
Pensaba que entendia mas o menos bien el tema de punteros, he encontrado
este ejercicio y me lo he puesto a hacer usando memoria dinámica...
*****************************************************************************************/
#include <stdio.h>
#include <stdlib.h>
/* Problema 4(a entregar). Partiendo de la siguiente declaración de
Struct empresa{
int id_emp;
char nombre[15];
char direc_emp[30];
long telefono;
};
Escribir un programa modular (con funciones) que defina una tabla de 10
empresas y establezca
un menú que llame a una serie de funciones. Se usará la llamada a función
típica de vectores
p.e. void rellenar (struct empresa Emp[]) que deberán realizar las tareas
a) Introducir todos los datos de las empresas.
b) Visualizar todos los datos d las empresas
c) Visualizar datos de una determinada empresa seleccionada al introducir
por teclado un
identificador de empresa.
d) Borrar datos de una determinada empresa seleccionada al introducir por
teclado un
identificador de empresa.This file will not be overwritten */
struct empresa {
int id_emp;
char nombre[15];
char direc_emp[30];
long telefono;
};
typedef struct empresa Empresa;
/* Devuelve una empresa, ya creada. */
Empresa agregar();
/* Muestra la empresa x */
void mostrar(Empresa x);
/* Agrega algunas empresas para no teclear en cada prueba */
void agregando(Empresa *listado, int *cantidad);
/* Muestra el listado de Empresas */
void ver_listado(Empresa *listado, int cantidad);
/* Menu y desarrollo del programa */
int menu(Empresa *listado, int *cantidad);
/* Imprimie un menu */
void imprime_menu(void);
/* Funciones que uso dentro del menu, por orgranización(?) */
void MENU_agregar(Empresa *listado, int *cantidad);
/*Las siguientes y las que se necesitan para las siguientes, aun no estan
codificadas */
void MENU_eliminar(Empresa *listado, char *nombre);
void MENU_ver(Empresa *listado, char *nombre);
int main()
{
/* Vector de Empresas */
Empresa *listado;
/* Cantidad de Empresas. al inicio del programa, tenemos solo una
(vacia) */
/* Me gustaria poder hacer que en caso de no crear ninguna empresa, no
se gaste ni un KB en un registro */
int cant = 1;
/* Reservo espacio minimo para una empresa */
listado=(Empresa*)malloc(sizeof(Empresa)*cant);
/* Agrego algunas empresas de prueba */
agregando(listado, &cant);
/* Empieza el menu y el desarrollo */
menu(listado, &cant);
getch();
return 0;
}
/*****************************************************************************************/
void ver_listado(Empresa *listado, int cantidad)
{
/* Porque no funciona el while (listado != NULL) ; listado++
???? */
int n;
for (n=0; n<cantidad; n++)
mostrar(*(listado+n));
getch();
}
/*****************************************************************************************/
void agregando(Empresa *listado, int *nueva_cantidad)
{
/* Los parrafos de este procedimiento son cargas automaticas,
en caso de querer modificar la cantidad de cargas automaticas,
modificar tambien la siguiente variable */
int parrafos = 4;
listado = (Empresa *)realloc(listado, (sizeof(Empresa) * parrafos));
(*(listado+0)).id_emp = 0001;
strcpy ( (*(listado+0)).nombre, "WotansFOLK SRL");
strcpy ( (*(listado+0)).direc_emp, "Bennisa 11 PB \"E\"");
(*(listado+0)).telefono = 335256981;
(*(listado+1)).id_emp = 0002;
strcpy ( (*(listado+1)).nombre, "Audery gayo y CIA");
strcpy ( (*(listado+1)).direc_emp, "Salto de la Madri");
(*(listado+1)).telefono = 687267122;
(*(listado+2)).id_emp = 0044;
strcpy ( (*(listado+2)).nombre, "Skywalker");
strcpy ( (*(listado+2)).direc_emp, "Death STAR");
(*(listado+2)).telefono = 335256981;
(*(listado+3)).id_emp = 0022;
strcpy ( (*(listado+3)).nombre, "Zorra golfa");
strcpy ( (*(listado+3)).direc_emp, "San Joan d Alacant");
(*(listado+3)).telefono = 6668122;
*nueva_cantidad = parrafos;
}
/*****************************************************************************************/
Empresa agregar(void)
{
Empresa aux; /* Uso un registro auxiliar, el que voy a devolver */
printf ("ID : "); scanf ("%d", &aux.id_emp);
printf ("Nombre : "); scanf ("%s", aux.nombre);
printf ("Direccion : "); scanf ("%s", aux.direc_emp);
printf ("Tel : "); scanf ("%l", &aux.telefono);
return aux;
}
/*****************************************************************************************/
void mostrar(Empresa x)
{
printf ("%s\n", x.nombre);
printf ("\t%s\n\t%d(ID)\n\tTel:%d\n", x.direc_emp, x.id_emp,
x.telefono);
}
/*****************************************************************************************/
void imprime_menu(void)
{
system ("cls");
printf ("\t1. Agregar Empresa\n");
printf ("\t2. Eliminar Empresa\n");
printf ("\t3. Ver Empresa\n");
printf ("\t4. Ver listado Completo\n");
printf ("\t5. Salir\n");
}
/*****************************************************************************************/
/* La variable cantidad pasadoa como parametro se utiliza en caso de
usar (lo hago) un procedimiento que cargue varios registros al mismo
tiempo */
int menu(Empresa *listado, int *cantidad)
{
char eleccion;
int cant = *cantidad;
imprime_menu();
while (eleccion != '5') {
imprime_menu();
eleccion=getch();
switch (eleccion) {
case '1' : MENU_agregar(listado, &cant);
break;
/* case '2' : break;
case '3' : break; */
case '4' : ver_listado(listado, cant);
break;
case '5' : return 0;
}
}
}
/*****************************************************************************************/
void MENU_agregar(Empresa *listado, int *cantidad)
{
++*cantidad;
listado = (Empresa *)realloc(listado, (sizeof(Empresa) *
(*cantidad)));
*(listado+(*cantidad)) = agregar();
printf ("Cantidad actual de Empresas en listado: %d\n", *cantidad);
system ("pause");
}
/*****************************************************************************************/
--
Por lo general, los hombres creen fácilmente lo que desean.
-- Julio César. Emperador romano.
Jorge S. de Lis
2006-03-07 17:28:09 UTC
Permalink
Post by Olaf "El Blanco"
*(listado+(*cantidad)) = agregar();
Te estás pasando... si hay 5 reservados, el primero + 5 = 6.
Debería ser

*(listado+(*cantidad)-1) = agregar();

Loading...