2014-08-29 24 views
6

tôi đã được đưa ra một mã số (C++), nơi các mảng được truyền sử dụngTại sao truyền mảng dưới dạng "int * & name"?

void fun(int *& name){...} 

nhưng ý tưởng đằng sau đó là gì? Tôi đoán nó có nghĩa là "một mảng tài liệu tham khảo" nhưng khi bạn chỉ cần chuyển một con trỏ đến phần tử đầu tiên sẽ ổn, phải không? Vậy động lực để làm theo cách này là gì?

+3

Nó có nghĩa là tham chiếu về biến con trỏ. Mục đích là thay đổi biến con trỏ được truyền cho nó. –

+3

Mảng? Không thể truyền các đối tượng mảng thực thông qua tham số đó. Những gì bạn có thể vượt qua là một con trỏ * trỏ đến một phần tử mảng, nhưng không phải là chính mảng đó. Ví dụ, bạn sẽ không thể trực tiếp truyền mảng 'int a [10]' tới hàm này. – AnT

+0

Điều quan trọng là phải biết rằng ** mảng không phải là con trỏ, và con trỏ không phải là mảng **. Xem [** bài đăng này **] (http://stackoverflow.com/questions/1641957/is-array-name-a-pointer-in-c) để biết thêm về điều đó. – juanchopanza

Trả lời

5

Hàm nhận được tham chiếu đến con trỏ. Điều này có nghĩa rằng chức năng không chỉ có thể sửa đổi int được trỏ đến bởi name, mà còn thay đổi đối với con trỏ chính nó được thực hiện trong cuộc gọi chức năng cũng sẽ hiển thị bên ngoài.

Ví dụ:

#include <iostream> 

int* allocate() 
{ 
    return new int(); 
} 

void destroy(int*& ptr) 
{ 
    delete ptr; 
    ptr = NULL; 
} 

int 
main(int argc, char *argv[]) 
{ 
    int* foo = allocate(); 

    std::cout << foo << std::endl; 

    destroy(foo); 

    std::cout << foo << std::endl; 

    return 0; 
} 

Output là:

0x82dc008 
0 
1

Nó có nghĩa là chức năng có thể thay đổi giá trị của con trỏ trong người gọi.

ví dụ:

myName* foo; /* ToDo - initialise foo in some way*/ 
fun(foo); 
/* foo might now point to something else*/ 

Tôi coi đây là một mô hình chống. Lý do khiến mọi người đọc mã của bạn sẽ không được mong đợifoo được sửa đổi theo cách như vậy vì cú pháp gọi là không thể phân biệt được với chức năng bình thường hơn void anotherFun(int * name){...}.

Tính ổn định của mã như vậy có thể bị ảnh hưởng. Vì vậy, tôi khuyên bạn nên sử dụng void fun(int ** name){...}. Cú pháp gọi sau đó trở thành fun(&foo) cho biết người dùng chức năng foo có thể được sửa đổi.

+1

Tôi sẽ nói đó là một mô hình chống sử dụng một con trỏ khi bạn có thể sử dụng một tham chiếu. Nhưng tôi cũng sẽ làm một cái gì đó khác: 'int * fun (int * name);', và trả về giá trị mới. – juanchopanza

+0

Vâng, cá nhân tôi không thích cú pháp con trỏ đến con trỏ mà nó không thực sự cần thiết. Vì vậy, nó phụ thuộc vào sở thích cá nhân. Tuy nhiên, tôi đồng ý rằng nói chung nó có thể đến bất ngờ cho người gọi rằng con trỏ có thể được sửa đổi. Cách thay thế cho việc sử dụng 'int **' như bạn đề xuất là có một API rõ ràng và được tài liệu hóa với các tên được lựa chọn tốt cho các hàm, ví dụ: 'deleteAndSetNull (int * & ptr)' cho một hàm xóa con trỏ và đặt nó thành NULL. – oxygene

+0

Thật buồn cười khi chia rẽ điều này là: Tôi rõ ràng tôn trọng ý kiến ​​của bạn và thích đề xuất sử dụng 'int * fun (int * name)'. Tôi không thích các tài liệu tham khảo được sử dụng theo cách mà OP có khi họ làm cho mã khó đọc và lỗi có thể được giới thiệu bởi đàn em làm việc trên các dự án cộng tác. Ít nhất hãy sử dụng 'const &' nếu có thể. – Bathsheba

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