2012-12-06 19 views
8

Tôi viết ngày càng nhiều ứng dụng C, và bây giờ tôi tự hỏi điều gì đó về phôi. Trong C++, một diễn viên năng động là một hoạt động rất tốn kém (ví dụ như một diễn viên xuống), nhưng tôi thậm chí không biết cho một diễn viên tĩnh.C dàn diễn viên thực sự làm gì?

Trong C, tôi đã phải viết một cái gì đó như thế:

assert (p); /* p is void* */ 
int v = *(int*)p; 

có phải là một «C dynamic-cast»? Có khá giống với static_cast<int*>(p) của C++ không? Chi phí là bao nhiêu?

Xin cảm ơn trước.

+2

... cho các định nghĩa thích hợp của "rất" ... – DevSolar

+0

Có thể trùng lặp của [Trình biên dịch C/C++ xử lý việc nhập kiểu giữa các loại với các phạm vi giá trị khác nhau như thế nào?] (https://stackoverflow.com/questions/340413/how-do-cc-compilers-handle-type-casting-between-types-with-different-value-ra) – jww

Trả lời

7

Một diễn viên trong C chỉ có ý nghĩa tại thời gian biên dịch bởi vì nó cho trình biên dịch biết cách bạn muốn thao tác một đoạn dữ liệu. Nó không thay đổi giá trị thực tế của dữ liệu. Ví dụ: (int*)p yêu cầu trình biên dịch xử lý p làm địa chỉ bộ nhớ cho một số nguyên. Tuy nhiên chi phí này không có gì trong thời gian chạy, bộ vi xử lý chỉ giao dịch với số liệu thô theo cách chúng được trao cho nó.

+8

Điều này không đúng cho tất cả các phôi. '(float) 0.3' thay đổi giá trị trên các hệ thống IEEE754. Nó không còn bằng '0.3' nữa. –

+0

Điều đó đúng, cảm ơn bạn. – jazzbassrob

8

Chữ C của con trỏ giống C++ reinterpret_cast. Nó chỉ thị cho trình biên dịch xử lý một biến như là một kiểu khác và không tốn chi phí khi chạy.

+1

Đó là khi truyền từ một loại con trỏ đến một trường hợp khác, nhưng trong trường hợp đó, 'reinterpret_cast' thực hiện tương tự như' static_cast'. Đúc, nói, một đôi để một số nguyên không thực sự làm việc và không có gì giống như một 'reinterpret_cast'. Với tôi, sự so sánh với 'static_cast' có vẻ thích hợp hơn' dynamic_cast'. – sepp2k

+0

@ sepp2k Tôi đã cập nhật câu trả lời của tôi để bao gồm các điểm của bạn về phôi của các loại con trỏ. Tôi không chắc chắn tôi đồng ý với bạn về phôi tĩnh và diễn giải lại là giống hệt nhau cho các loại con trỏ - không phải là trình biên dịch kiểm tra xem phôi tĩnh là giữa các loại tương thích? (Điều này có thể xảy ra trên một ốp mặc dù ... Tôi đồng ý và đã chú ý đến điểm chính của bạn) – simonc

+0

Bạn nói đúng, 'static_cast' chỉ giống hệt' reinterpret_cast' ** nếu ** nó biên dịch. – sepp2k

2

Con trỏ là con trỏ - truyền con trỏ là một vòng tròn.

Đó là địa chỉ bộ nhớ trước đó, đây là địa chỉ bộ nhớ sau đó.

Về cơ bản, đó là tuyên bố "hãy giả định rằng đây là con trỏ để nhập x để kiểm tra loại trong tương lai".

Vì vậy, bạn có thể gọi đây là reinterpret_cast về C++, vì nó không thực hiện thêm thời gian biên dịch kiểm tra loại đó, ví dụ: dynamic_cast hoặc static_cast.

Tôi không nghĩ rằng C có tương đương với số dynamic_cast ("chèn loại thời gian chạy ở đây") hoặc static_cast ("thực hiện thêm loại thời gian biên dịch kiểm tra tại đây").

Lưu ý rằng đối với không phải là con trỏ mọi thứ sẽ hoạt động hơi khác.

int b = 1; 
double a = (double) b; 

không phải là quá nhiều diễn viên, nhưng loại rõ ràng chuyển đổi.

+0

Lưu ý rằng tiêu chuẩn này bảo lưu quyền có các con trỏ tới các loại khác nhau có chiều rộng khác nhau ... trong khi đây là một trường hợp kỳ lạ trong thế giới kiến ​​trúc nổi 8 bit 2-bổ sung của IEEE, các luật sư ngôn ngữ có thể theo sau bạn cho nhận xét "noop". ;-) – DevSolar

+0

Ok hiểu rồi. Vì vậy, nó là một gợi ý _compiler_ ** ** hơn bất cứ điều gì khác? – phaazon

+0

Không thực sự là một gợi ý "" cho trình biên dịch: - nó không giúp trình biên dịch để tối ưu hóa bất cứ điều gì. Nhưng nó là một điều * lập trình viên *. Tôi không để cho trình biên dịch * đoán * điều này là chính xác, nhưng tôi * nói rõ * rằng điều này sẽ được đúc, và không phải là lỗi đánh máy; nó chỉ nói với trình biên dịch rằng đây là "không phải là lỗi, nhưng có nghĩa là theo cách này". –

5

Một diễn viên C giống như tất cả các phôi kiểu C++ ngoại trừdynamic_cast kết hợp. Vì vậy, khi bạn nhập một int vào một loại số nguyên khác, nó là static_cast. Khi bạn đưa con trỏ đến các loại con trỏ khác hoặc các loại số nguyên hoặc ngược lại, nó là reinterpret_cast. Nếu bạn bỏ đi một số const, nó là const_cast.

C không có thứ gì đó tương tự như dynamic_cast vì nó có khái niệm về loại đối tượng và sẽ không sử dụng cho chúng như C++ hoặc (không có chức năng ảo ...). Các loại liên quan đến việc giải thích các bit của đối tượng chỉ trở nên quan trọng khi được kết hợp với các biểu thức đề cập đến các đối tượng, trong C. Các đối tượng chúng không có các loại.