chuyển một cấu trúc đến một hàm không hoạt động [trùng lặp]
Trong đoạn mã dưới đây, tôi đã tạo một hàm ngoài hàm main để chia int bên trong một cấu trúc thành một nửa.
Sau đó, tôi muốn in ra giá trị mới. Tuy nhiên, giá trị in ra vẫn là giá trị cũ.
Tôi tin rằng kiến thức cơ bản của tôi về cấu trúc và con trỏ là không đủ tốt.
Bất cứ ai có thể giúp tôi với điều này? Cảm ơn rất nhiều!!!
typedef struct{
int age;
int wage;
}person;
void divide(person A)
{
person half;
half.age = A.age / 2;
half.wage = A.wage / 2;
A = half;
}
int main(void)
{
person A;
A.age = 30;
A.wage = 35000;
divide(A);
printf("%i\n", A.age);
}
Trả lời
Hàm divide
đang sửa đổi một bản sao của cấu trúc đó vì cấu trúc được chuyển theo giá trị. Bạn sẽ cần phải chuyển con trỏ đến cấu trúc để hàm có thể sửa đổi bản gốc.
void divide(person* A)
{
person half;
half.age = A->age / 2;
half.wage = A->wage / 2;
*A = half;
}
Được gọi divide
với địa chỉ của cấu trúc ban đầu
divide(&A);
Khi bạn chuyển A
đến divide
, một bản sao của A
sẽ được tạo. Việc sửa đổi bản sao bên trong divide
này không ảnh hưởng đến biến cục bộ A
mà bạn đã xác định main
. Để khắc phục điều này, bạn có thể thực divide
hiện một con trỏ tới person
. Một con trỏ thể hiện một cách hiệu quả một địa chỉ trong bộ nhớ để bạn có thể sử dụng nó để truy cập vào các biến cục bộ được xác định trong các hàm khác mà nếu không thì không thể truy cập được (nghiên cứu khung ngăn xếp nếu bạn muốn hiểu tại sao lại như vậy).
Vì vậy, trong thực tế bạn thay đổi divide
chữ ký 's: void divide(person *A)
và ở dòng cuối cùng của chức năng này, bạn assing không A
nhưng để bất cứ điều gì A
được trỏ đến bằng cách sử dụng các toán tử tham chiếu: *A = half
. Trong bạn main
chức năng bạn sau đó vượt qua địa chỉ của A
thay vì A
bản thân để divide
sử dụng địa chỉ của nhà điều hành: divide(&A)
.
EDIT: thậm chí tốt hơn, bạn có thể tránh tạo ra tạm thời half
bằng cách trực tiếp thực hiện: A->age /= 2
và A->wage /= 2
nơi A.x
là cú pháp đường cho (*A).x
.