Điều này nghe có vẻ giống như một câu hỏi ngớ ngẩn, nhưng tôi vẫn đang học C, vì vậy hãy chịu với tôi. :)Chuyển con trỏ/tham chiếu đến cấu trúc thành các hàm
Tôi đang làm việc trên chương 6 của K & R (cấu trúc), và do đó đến nay qua cuốn sách đã đạt được thành công lớn. Tôi quyết định làm việc với cấu trúc khá nhiều, và do đó đã làm rất nhiều công việc sớm trong chương với các ví dụ điểm và rect. Một trong những điều tôi muốn thử đã thay đổi chức năng canonrect
(2nd Edition, p 131) hoạt động qua con trỏ, và do đó trả về void
.
Tôi đã làm việc này, nhưng gặp phải một trục trặc, tôi hy vọng các bạn có thể giúp tôi. Tôi muốn canonRect
để tạo một đối tượng hình chữ nhật tạm thời, thực hiện các thay đổi của nó, sau đó gán lại con trỏ nó được chuyển tới hình chữ nhật tạm thời, do đó đơn giản hóa mã.
Tuy nhiên, nếu tôi thực hiện điều đó, chế độ chỉnh sửa sẽ không thay đổi. Thay vào đó, tôi thấy mình tự tái tạo lại các trường của rect mà tôi chuyển vào, nó hoạt động.
mã sau:
#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;
}
Vì vậy, đây là những câu hỏi sau:
- Tại sao
r = &temp;
không hoạt động? (Tôi nghĩ rằng điều này là do tôi chuyển qua tham chiếu thay vì một con trỏ; tôi có đúng là không thể sửa đổi được nhưng con trỏ là?) - Tại sao tôi có thể gặp lỗi biên dịch gián tiếp bất hợp pháp nếu tôi thử để chuyển một con trỏ đến
canonRect
? (. IE, nếu tôi cócanonRect(*r);
trongmain()
)
tôi nghi ngờ tôi đã biết câu trả lời cho # 1, nhưng # 2 giới làm bối rối cho tôi - Tôi nghĩ đó là pháp lý để vượt qua con trỏ xung quanh.
Dù sao ... xin vui lòng tha thứ cho C newb.
Ehhh ... Tôi phải có vấn đề về não hiện nay. Việc chuyển một con trỏ tới một con trỏ sẽ là canonRect (** r) ;, không? Cùng một lỗi gián tiếp bất hợp pháp. –
Wow; chỉnh sửa tuyệt vời! Cảm ơn! –
Chỉ cần thử nghiệm nó; đây là một. Cảm ơn bạn đã giải thích rất kỹ lưỡng. –