Esto va a sonar como una pregunta tonta, pero todavía estoy aprendiendo C, así que por favor tengan paciencia conmigo. :)Pasar punteros/referencias a estructuras en funciones
Estoy trabajando en el capítulo 6 de K & R (structs), y hasta ahora a través del libro han tenido un gran éxito. Decidí trabajar con estructuras bastante pesadas, y por lo tanto trabajé mucho al comienzo del capítulo con los ejemplos de punto y rect. Una de las cosas que quería probar era cambiar la función canonrect
(2da Edición, p 131) a través de punteros, y por lo tanto devolver void
.
Tengo esto funcionando, pero tuve un problema con el que esperaba que ustedes pudieran ayudarme. Quería canonRect
crear un objeto rectángulo temporal, realizar sus cambios, luego reasignar el puntero al rectángulo temporal, simplificando así el código.
Sin embargo, si hago eso, el rect no cambia. En cambio, me encuentro repoblando manualmente los campos de rect que me dieron, lo cual funciona.
El código sigue:
#include <stdio.h>
#define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) > (b) ? (a) : (b))
struct point {
int x;
int y;
};
struct rect {
struct point lowerLeft;
struct point upperRight;
};
// canonicalize coordinates of rectangle
void canonRect(struct rect *r);
int main(void) {
struct point p1, p2;
struct rect r;
p1.x = 10;
p1.y = 10;
p2.x = 20;
p2.y = 40;
r.lowerLeft = p2; // note that I'm inverting my points intentionally
r.upperRight = p1;
printf("Rectangle, lower left: %d, %d; upper right: %d %d\n\n",
r.lowerLeft.x, r.lowerLeft.y, r.upperRight.x, r.upperRight.y);
// can't pass a pointer, only a reference.
// (Passing pointers results in illegal indirection compile time errors)
canonRect(&r);
printf("Rectangle, lower left: %d, %d; upper right: %d %d\n\n",
r.lowerLeft.x, r.lowerLeft.y, r.upperRight.x, r.upperRight.y);
}
void canonRect(struct rect *r) {
struct rect temp;
temp.lowerLeft.x = min(r->lowerLeft.x, r->upperRight.x);
temp.lowerLeft.y = min(r->lowerLeft.y, r->upperRight.y);
temp.upperRight.x = max(r->lowerLeft.x, r->upperRight.x);
temp.upperRight.y = max(r->lowerLeft.y, r->upperRight.y);
r = &temp; // doesn't work; my passed-in rect remains the same
// I wind up doing the following instead, to reassign all
// the members of my passed-in rect
//r->lowerLeft = temp.lowerLeft;
//r->upperRight = temp.upperRight;
}
Así que aquí están las preguntas:
- ¿Por qué
r = &temp;
no funciona? (I piensa esto es porque paso en una referencia en lugar de un puntero; ¿estoy en lo cierto al pensar que las referencias no son modificables pero los punteros son?) - ¿Por qué podría obtener un error de tiempo de compilación indirecto ilegal si lo intento pasar en un puntero al
canonRect
? (. IE, si tuvieracanonRect(*r);
enmain()
)
Sospecho que ya sé la respuesta a # 1, # 2, pero me deja perplejo - pensé que era legal para pasar punteros alrededor.
De todos modos ... por favor perdone el C newb.
Ehhh ... Debo tener problemas cerebrales hoy. Pasar un puntero a un puntero sería canonRect (** r) ;, no? Los mismos errores indirectos ilegales. –
Wow; gran edición! ¡Gracias! –
Acabo de probarlo; Éste es el indicado. Gracias por la minuciosa explicación. –