2011-02-09 99 views
6

'&' có nghĩa là gì trong C++? như trong hàm'&' có nghĩa là gì trong C++?

void Read_wav::read_wav(const string &filename) 
{ 

} 

Và điều gì tương đương với C?

Cảm ơn


EDIT 1

Nếu tôi muốn chuyển đổi hàm C++ trên vào một hàm C, làm thế nào tôi sẽ làm điều đó?

+1

http://en.wikipedia.org/wiki/Reference_ (C% 2B% 2B) –

+1

như @Tim Medora đã nói http://en.wikipedia.org/wiki/Reference_%28C%2B%2B%29 (nhưng tôi đã sửa liên kết;)) –

+0

@ Hernán Eche - Dán thất bại một phần của tôi ... Cảm ơn! –

Trả lời

12

Trong bối cảnh đó, các & làm cho biến một tài liệu tham khảo.

Thông thường, khi bạn chuyển một biến cho hàm, biến được sao chép và hàm hoạt động trên bản sao. Khi hàm trả về, biến ban đầu của bạn không thay đổi. Khi bạn vượt qua một tham chiếu, không có bản sao nào được thực hiện và các thay đổi được thực hiện bởi hàm sẽ hiển thị ngay cả sau khi hàm trả về.

C không có tài liệu tham khảo, nhưng C++ tham chiếu là chức năng giống như một con trỏ trong C. Thật sự khác biệt duy nhất là con trỏ phải được dereferenced khi bạn sử dụng chúng:

*filename = "file.wav"; 

Nhưng tài liệu tham khảo có thể được sử dụng như thể chúng là các biến ban đầu:

filename = "file.wav"; 

Bề ngoài, tài liệu tham khảo có nghĩa vụ phải bao giờ được null, mặc dù nó không phải là không thể cho điều đó xảy ra.

Chức năng C tương đương sẽ là:

 void read_wav(const char* filename) 
    { 

    } 

Điều này là do C không có string. Thực hành thông thường trong C là gửi một con trỏ tới một mảng các ký tự khi bạn cần một chuỗi ký tự. Giống như trong C++, nếu bạn nhập một hằng số chuỗi

read_wav("file.wav"); 

Loại là const char*.

11

Điều đó có nghĩa là biến số là reference. Không có tương đương trực tiếp trong C. Bạn có thể nghĩ về nó như là một con trỏ được tự động dereferenced khi được sử dụng, và không bao giờ có thể được NULL, có thể.

Cách tiêu biểu để đại diện cho một chuỗi trong C là bởi một con trỏ char, vì vậy chức năng có khả năng sẽ giống như thế này:

void read_wav(struct Read_wav* instance, const char *filename) 
{ 
} 

Lưu ý: đối số đầu tiên ở đây mô phỏng các tài liệu tham khảo this đối tượng tiềm ẩn bạn sẽ phải trong C++, vì nó trông giống như một phương thức thành viên.

+0

Bạn có chắc chắn không?!? – karlphillip

+0

Vui lòng xem chỉnh sửa đầu tiên của tôi. Cảm ơn :) –

+1

bạn cần tham chiếu đến cấu trúc gốc - dựa trên việc sử dụng, nội bộ từ lớp Read_wav đang được sử dụng –

-3

& filename có nghĩa đây là một tham chiếu đến tên tập tin

+1

C không có tham chiếu. – unwind

+0

Không có điều gì như vượt qua bằng cách tham chiếu trong C. Mã này không biên dịch trong C. –

0

& có nghĩa là biến đó được chuyển qua tham chiếu. Vì vậy, bên trong hàm của bạn, bạn sẽ không có một bản sao cục bộ của biến, mà là biến gốc. Tất cả các thay đổi đối với biến bên trong hàm sẽ ảnh hưởng đến biến được truyền ban đầu.

+0

cũng đúng, nhưng trong trường hợp của ông là có một const-vòng loại, biến sẽ không được thay đổi – Nikko

0

Bạn có thể muốn xem Binky Pointer fun, đó là video minh họa những gì Con trỏ và Tham chiếu.

1

Trong C, bạn sẽ viết nó theo cách này:

void read_wav(struct Read_wav* , const char * pSzFileName) 
{ 

} 

std :: string là C++ cách đối phó với mảng của char const.

& là tham chiếu C++. Nó hoạt động giống như khi bạn đang xử lý con trỏ phía sau (nó chủ yếu là một đường cú pháp, nghĩ rằng nó sẽ nhắc nhở hợp đồng mà con trỏ phía sau không được rỗng).

+2

Bạn chỉ viết nó theo cách đó nếu nó là 'tĩnh'. Một hàm thành viên không tĩnh sẽ yêu cầu một đối số 'Read_wav *' rõ ràng để thay thế hàm 'this' ẩn từ C++. – dan04

+0

Bạn nói đúng. Tôi chỉnh sửa. –

0

Trong trường hợp này, string &filename có nghĩa là chức năng sẽ nhận được tham chiếu (địa chỉ bộ nhớ) làm tham số thay vì nhận nó dưới dạng bản sao.

Lợi thế của phương pháp này là chức năng của bạn sẽ không phân bổ nhiều không gian hơn trên ngăn xếp để lưu dữ liệu có trong tên tệp.

0

Đó là một tham chiếu, như những người khác đã nói. Trong C, có lẽ bạn muốn viết các chức năng như một cái gì đó giống như

void read_wav(struct Read_wav* rw, const char* filename) 
{ 

} 
+0

'const char * filename' –

+1

@Foo Bah: Hoặc thậm chí' const char * const filename' :) – GrahamS

1

dấu và được sử dụng trong hai ý nghĩa khác nhau trong C++: gán địa chỉ của một cái gì đó (ví dụ của một biến hoặc một hàm) và cách xác định một biến hoặc tham số hàm là tham chiếu đến một thực thể được định nghĩa ở một nơi khác. Trong ví dụ của bạn, ý nghĩa thứ hai được sử dụng.

C không hoàn toàn nói bất cứ điều gì giống như tham chiếu nhưng con trỏ (hoặc con trỏ đến con trỏ) đã được người dùng cho độ tuổi cho những thứ tương tự.

Xem ví dụ: http://www.cprogramming.com/tutorial/references.html, What are the differences between a pointer variable and a reference variable in C++? hoặc http://en.wikipedia.org/wiki/Reference_%28C%2B%2B%29 để biết thêm thông tin về tài liệu tham khảo trong C++.

1

Trong trường hợp cụ thể này, std :: string có phương thức c_str trả về const char *. Bạn có thể tạo ra một phiên bản C song song và sau đó có C++ làm điều gì đó như:

void Read_wav::read_wav(const string &filename) 
{ 
    do_read_wav(internal_read_wav, filename.c_str()); 
} 

nơi do_read_wav là thói quen C và internal_read_wav là một con trỏ đến một cấu trúc C-phong cách.

void do_read_wav(struct Read_wav rw, const char * filename) 

Bây giờ, nếu bạn đang lưu trữ thông tin trong lớp, bạn cần phải thực hiện một struct C [tất cả các trường phải POD, vv]

1

Tài liệu tham khảo là bí danh, họ rất giống với con trỏ .

std::string là một mảng char với rõ ràng length (nghĩa là, có thể có các ký tự null được nhúng bên trong).

Có thư viện C để mô phỏng std::string (nghĩa là, cung cấp giao diện được đóng gói) được gọi là bstring cho Better String Library. Nó giúp bạn tránh khỏi tedium phải đối phó với hai biến riêng biệt (mảng và chiều dài).Bạn không thể sử dụng các lớp trong C, nhưng bạn có thể mô phỏng chúng với cấu trúc được chuyển tiếp (để áp đặt đóng gói) và các phương thức lớp đơn giản trở thành các hàm thông thường với một tham số rõ ràng.

Nhìn chung, điều này dẫn đến sự biến đổi sau:

void Read_wav::read_wav(const string &filename); 

void read_wav(struct Read_wav* this, struct bstring const* filename); 

nào (ngoài những struct tiếng ồn) rất giống với những gì bạn có trước :)