2013-01-05 34 views
5

Trong rất nhiều ví dụ tôi đã đọc một getListLength đơn giản() chức năng sẽ giống như thế này:Pointers như các đối số trong hàm C

int getListLength(struct node *head) 
{ 
    struct node *temp = head; 
    int iCount = 0; 

    while (temp) 
    { 
     ++iCount; 
     temp = temp->next; 
    } 

    return iCount; 
} 

gì đập vào mắt tôi như không cần thiết là việc kê khai của một con trỏ địa phương (trong trường hợp này * temp) sao chép tham số đã truyền. Nếu tôi nhớ lại chính xác, các tham số đã truyền có được các bản sao của riêng chúng. Do đó, sẽ không cần một con trỏ cục bộ sao chép đầu * chỉ vì đầu * là bản sao, đúng không? Nói cách khác, nó sẽ là chính xác để loại bỏ các con trỏ temp * và sử dụng đầu ở khắp mọi nơi thay thế?

Trả lời

4

Vâng, đó là một bản sao, do đó, có, nó sẽ là chính xác.

int getListLength(struct node* head) 
{ 
    int iCount = 0; 

    while (head) 
    { 
     ++iCount; 
     head = head->next; 
    } 
    return iCount; 
} 

Tại sao bạn không thực hiện và tự mình xem?

4

Mặc dù sự thật là bạn không cần bản sao cục bộ vì con trỏ được truyền theo giá trị, nhưng có thể vì lý do phong cách. Một số xem xét nó là hình thức xấu để sửa đổi các đối số được thông qua (mặc dù tôi thấy nó hữu ích trong một số kịch bản), nhưng có lẽ quan trọng hơn, bạn mất một số tài liệu tự trong mã; cụ thể, head không còn luôn trỏ đến người đứng đầu thực sự của danh sách được liên kết. Điều này không gây nhầm lẫn trong đoạn mã ngắn của bạn, nhưng có các biến được đặt tên không chính xác có thể gây nhầm lẫn hơn nhiều khi mã dài hơn và phức tạp hơn.

+0

"khi mã dài hơn và phức tạp hơn". - Tôi có thể tranh luận với điều đó. Nếu một hàm dài hơn OP được đăng, và nếu nó phức tạp đến nỗi nó thực hiện nhiều hơn một nhiệm vụ và cần phải nhớ các tên biến, thì hàm đó có thể được tái cấu trúc. –

+0

Điều đó có lẽ đúng, nhưng thế giới thực hiếm khi hoàn hảo như người ta thích. – jjlin

2

Thông thường, lý do tạo bản sao cục bộ của con trỏ được chuyển vào là giảm side-effects của một hàm (bằng cách không sửa đổi tham số hàm).

Nếu một hàm là chỉ sử dụng con trỏ để đọc (không viết), và có không có tương tác khác với thế giới bên ngoài, chức năng có thể được chú thích như 'tinh khiết' trong GCC và sẽ được mở cho một số tối ưu hóa tốt đẹp.

Ví dụ:

__attribute__((pure)) int getListLength(struct node *head) 
{ 
    struct node *temp = head; 
    int iCount = 0; 

    while (temp) 
    { 
     ++iCount; 
     temp = temp->next; 
    } 

    return iCount; 
} 

Nếu bạn không quen thuộc với những gì tác dụng phụ, hãy thử đọc Side EffectsFunctional Programming bài viết Wikipedia để có thêm thông tin về đề tài này.

Các vấn đề liên quan