This is going to sound like a silly question, but I'm still learning C, so please bear with me. :)
I'm working on chapter 6 of K&R (structs), and thus far through the book have seen great success. I decided to work with structs pretty heavily, and therefore did a lot of work early in the chapter with the point and rect examples. One of the things I wanted to try was changing the canonrect
function (2nd Edition, p 131) work via pointers, and hence return void
.
I have this working, but ran into a hiccup I was hoping you guys could help me out with. I wanted canonRect
to create a temporary rectangle object, perform its changes, then reassign the pointer it's passed to the temporary rectangle, thus simplifying the code.
However, if I do that, the rect doesn't change. Instead, I find myself manually repopulating the fields of the rect I'm passed in, which does work.
The code follows:
#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;
}
So here are the questions:
- Why does
r = &temp;
not work? (I think this is because I pass in a reference instead of a pointer; am I correct in thinking that references are not modifiable but pointers are?) - Why might I get an illegal indirection compile-time error if I try to pass in a pointer to
canonRect
? (IE, if I hadcanonRect(*r);
inmain()
.)
I suspect I already know the answer to #1, but #2 perplexes me -- I thought it was legal to pass pointers around.
Anyway ... please forgive the C newb.