Lập trình

Lập trình

Thứ Ba, 17 tháng 11, 2015

Hàm và sự thay đổi của con trỏ

Chào các bạn, như đã biết để thay đổi giá trị của một biến qua hàm thì ta có cách truyền vào địa chỉ của nó , nhưng bên cạnh đó có thể có một số hiểu nhầm .Hôm nay mình trình bày sự kết hợp giữa hàm và con trỏ :

ví dụ ta có code :

void test(int *p){
int a = 9;
p = &a;
}

int main(){
int a = 5;
int *p = &a;

cout << p << " " << *p << endl; // 0x0002 5
test(p);
cout << p << " " << *p << endl;// 0x0002 5

       // dễ thấy giá trị của biến p không bị thay đổi

return 0;
}

Ta thấy khi gọi hàm test(int *p) chương trình tạo ra một biến kiểu int* copy nông (shadow copy) giá trị của biến p. Trong thân hàm test các thao tác được thực hiện trên ban sao của p, nên khi ta gán p cho một địa chỉ khác thực chất là gán bản sao của p, p không thay đổi. Chính vì thế nên giá trị của p không bị thay đổi.

Qua đây ta cũng có thể hiểu kĩ hơn bản chất của việc thay đổi giá trị của một biến bằng cách truyền vào đia chỉ của nó.

Trên đây mình ví dụ một ví dụ cơ bản về việc hiểu nhầm chút ít trong việc kết hợp hàm và con trỏ. Có vài trường hợp khác như sau (trong linked list) :
  1. void WrongPush(struct node* head, int data) {
  2.      struct node* newNode = malloc(sizeof(struct node));
  3.      newNode->data = data;
  4.      newNode->next = head;
  5.      head = newNode;
  6. }
   (Nguồn : congdongcviet.com)
cái này sai ở : head = newNode;
vì giá trị của con trỏ head không bị thay đổi.

Cách khắc phục :
dùng con trỏ đa cấp :)

  1. /*
  2. Takes a list and a data value.
  3. Creates a new link with the given data and pushes
  4. it onto the front of the list.
  5. The list is not passed in by its head pointer.
  6. Instead the list is passed in as a "reference" pointer
  7. to the head pointer -- this allows us
  8. to modify the caller's memory.
  9. */
  10. void Push(struct node** headRef, int data) {
  11.      struct node* newNode = malloc(sizeof(struct node));
  12.      newNode->data = data;
  13.      newNode->next = *headRef; // The '*' to dereferences back to the real head
  14.      *headRef = newNode;          
  15. }

Cảm ơn các bạn đã xem :) . 

Không có nhận xét nào:

Đăng nhận xét